Index: kcore/boot.rt.c ================================================================== --- kcore/boot.rt.c +++ kcore/boot.rt.c @@ -1,14 +1,17 @@ #include extern stat entry(kenv); -stat _boot(unsigned int argc, char** argv) { +unsigned long long +_boot(unsigned int argc, /* argument count */ + char** argv, /* arguments */ + char** envp /* environment */ ) { kenv e = { - // todo: determine terminal class and set term vs ansi correctly! + /* TODO: determine terminal class and set term vs ansi correctly! */ { {kiostream_term, 0}, {kiostream_term, 1} }, // chan std { {kiostream_closed}, {kiostream_term, 2} }, // chan err - argc, argv, - null // no environment yet + argc, argv, + null // needs parsing }; return entry(e); } Index: kcore/boot.rt.x86.lin.64.s ================================================================== --- kcore/boot.rt.x86.lin.64.s +++ kcore/boot.rt.x86.lin.64.s @@ -4,14 +4,64 @@ global _start:function extern _boot extern entry _start: - mov rbp, rsp - mov rdi, [rbp + 0] ; argc - lea rsi, [rbp + 8] ; argv + mov rbp, 0 ; zero the stack base ptr. + ; attempted fix for a difficult-to- + ; reproduce bug + + mov rdi, 0 ; zero rdi - because argc + ; is 32 bits long, we have to store + ; its value in the lower half of rdi. + ; this ensures that the upper half is + ; zeroed as well. + + mov edi, [rsp + 0] ; sizeof arguments + ; first argument to _boot(): argc + ; this is a 32-bit signed(??) integer + ; that is equal to the number of + ; elements in argv (see below). it is + ; not strictly necessary, because argv + ; is per spec always null-terminated, + ; but we pass it just in case. + + lea rsi, [rsp + 8] ; &arguments + ; 2nd argument to _boot(): ptr to argv + ; this points to an array of strings + ; containing the program's command line + ; arguments. _boot() does not need to + ; parse this, but it does need to store + ; it in the structure passed to main() + + lea rdx, [rsp + 16] ; &environment + ; third argument to _boot(): ptr to envp + ; this points to the list of environment + ; variables for the running program. it + ; is the responsibility of _boot to parse + ; this list and arrange it into a set of + ; legible and useful C arrays. + + mov rax, 0 ; zero out %rax + ; this is required by the C ABI, and is + ; reputedly necessary for compatibility + ; with icc, intel's own proprietary C + ; compiler. + + call _boot ; invoke the start function + ; that will set up the runtime and + ; construct the necessary structures + ; that will be bassed to libc. + + ; boot has returned and left its + ; return value in the register %rax. + ; regardless of the size of the + ; return value of main(), _boot always + ; returns the system word length. + + mov sys.reg.1, sys.reg.ret ; fill in + ; the return value as exit's argument - call _boot + mov sys.reg.0, sys.exit ; set %rax to + ; the syscall number of exit - mov sys.reg.1, sys.reg.ret - mov sys.reg.0, sys.exit - sys.call + sys.call ; invoke the kernel