diff --git a/modules.yaml b/modules.yaml index c60391f..74ee97f 100644 --- a/modules.yaml +++ b/modules.yaml @@ -84,7 +84,6 @@ modules: source: - src/drivers/nulldrv/io.cpp - src/drivers/nulldrv/main.cpp - - src/drivers/nulldrv/main.s - src/drivers/nulldrv/serial.cpp fb: @@ -95,7 +94,6 @@ modules: - libc source: - src/drivers/fb/main.cpp - - src/drivers/fb/main.s kutil: kind: lib @@ -132,6 +130,8 @@ modules: #- LACKS_TIME_H source: - src/libraries/libc/arch/x86_64/_Exit.s + - src/libraries/libc/arch/x86_64/crt0.s + - src/libraries/libc/arch/x86_64/init_libc.c - src/libraries/libc/arch/x86_64/syscalls.s - src/libraries/libc/ctype/isalnum.c - src/libraries/libc/ctype/isalpha.c diff --git a/src/drivers/fb/main.cpp b/src/drivers/fb/main.cpp index d14b319..b8aa69c 100644 --- a/src/drivers/fb/main.cpp +++ b/src/drivers/fb/main.cpp @@ -1,25 +1,16 @@ #include #include -#include "j6/types.h" +#include "j6/init.h" #include "j6/errors.h" #include "j6/signals.h" +#include "j6/types.h" #include extern "C" { - void _init_libc(j6_process_init *); int main(int, const char **); -} - -j6_handle_t sys = j6_handle_invalid; -size_t size = 0; - -void -_init_libc(j6_process_init *init) -{ - sys = init->handles[0]; - size = reinterpret_cast(init->handles[1]); + void _get_init(size_t *initc, struct j6_init_value **initv); } int @@ -27,12 +18,25 @@ main(int argc, const char **argv) { _syscall_system_log("fb driver starting"); - if (size == 0) + size_t initc = 0; + j6_init_value *initv = nullptr; + _get_init(&initc, &initv); + + j6_init_framebuffer *fb = nullptr; + for (unsigned i = 0; i < initc; ++i) { + if (initv[i].type == j6_init_desc_framebuffer) { + fb = reinterpret_cast(initv[i].value); + break; + } + } + + if (!fb) return 1; - uint32_t *fb = reinterpret_cast(0x100000000); + uint32_t *fbp = reinterpret_cast(fb->addr); + size_t size = fb->size; for (size_t i=0; i < size/4; ++i) { - fb[i] = 0xff; + fbp[i] = 0xff; } _syscall_system_log("fb driver done, exiting"); diff --git a/src/drivers/nulldrv/main.cpp b/src/drivers/nulldrv/main.cpp index a239eb4..b46ccb0 100644 --- a/src/drivers/nulldrv/main.cpp +++ b/src/drivers/nulldrv/main.cpp @@ -11,7 +11,7 @@ #include "serial.h" char inbuf[1024]; -j6_handle_t sys = j6_handle_invalid; +extern j6_handle_t __handle_sys; j6_handle_t endp = j6_handle_invalid; extern "C" { @@ -51,12 +51,6 @@ thread_proc() _syscall_thread_exit(0); } -void -_init_libc(j6_process_init *init) -{ - sys = init->handles[0]; -} - int main(int argc, const char **argv) { @@ -65,6 +59,9 @@ main(int argc, const char **argv) _syscall_system_log("main thread starting"); + for (int i = 0; i < argc; ++i) + _syscall_system_log(argv[i]); + void *base = malloc(0x1000); if (!base) return 1; @@ -97,7 +94,7 @@ main(int argc, const char **argv) if (tag != 17) _syscall_system_log("GOT WRONG TAG FROM SENDRECV"); - result = _syscall_system_bind_irq(sys, endp, 3); + result = _syscall_system_bind_irq(__handle_sys, endp, 3); if (result != j6_status_ok) return result; diff --git a/src/drivers/nulldrv/main.s b/src/drivers/nulldrv/main.s deleted file mode 100644 index e79154b..0000000 --- a/src/drivers/nulldrv/main.s +++ /dev/null @@ -1,24 +0,0 @@ -section .bss -mymessage: - resq 1024 - -extern main -extern _init_libc -extern exit - -section .text - -global _start -_start: - mov rbp, rsp - - mov rdi, rsp - call _init_libc - - mov rdi, 0 - mov rsi, 0 - - call main - - mov rdi, rax - call exit diff --git a/src/include/j6/init.h b/src/include/j6/init.h new file mode 100644 index 0000000..1e9b2cd --- /dev/null +++ b/src/include/j6/init.h @@ -0,0 +1,30 @@ +#pragma once +/// \file init.h +/// Types used in process and thread initialization + +#include + +enum j6_init_type { // `value` is a: + j6_init_handle_system, // Handle to the system + j6_init_handle_process, // Handle to this process + j6_init_handle_thread, // Handle to this thread + j6_init_handle_space, // Handle to this process' address space + j6_init_desc_framebuffer // Pointer to a j6_init_framebuffer descriptor +}; + +struct j6_init_value { + enum j6_init_type type; + uint64_t value; +}; + +/// Structure defining a framebuffer. +/// `flags` has the following bits: +/// 0-3: Pixel layout. 0000: bgr8, 0001: rgb8 +struct j6_init_framebuffer { + void* addr; + size_t size; + uint32_t vertical; + uint32_t horizontal; + uint32_t scanline; + uint32_t flags; +}; diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index c355f5e..e27c9c3 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -1,5 +1,7 @@ #include +#include + #include "apic.h" #include "clock.h" #include "console.h" @@ -63,6 +65,14 @@ scheduler::scheduler(lapic *apic) : bsp_cpu_data.t = idle; } +template +inline T * push(uintptr_t &rsp, size_t size = sizeof(T)) { + rsp -= size; + T *p = reinterpret_cast(rsp); + rsp &= ~(sizeof(uint64_t)-1); // Align the stack + return p; +} + uintptr_t load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb) { @@ -72,31 +82,60 @@ load_process_image(uintptr_t phys, uintptr_t virt, size_t bytes, TCB *tcb) // We're now in the process space for this process, allocate memory for the // process code and load it process &proc = process::current(); + thread &th = thread::current(); vm_space &space = proc.space(); vm_area *vma = new vm_area_open(bytes, space, vm_flags::zero|vm_flags::write); space.add(virt, vma); vma->commit(phys, 0, memory::page_count(bytes)); - tcb->rsp3 -= 2 * sizeof(uint64_t); - uint64_t *sentinel = reinterpret_cast(tcb->rsp3); - sentinel[0] = sentinel[1] = 0; + // double zero stack sentinel + *push(tcb->rsp3) = 0; + *push(tcb->rsp3) = 0; - tcb->rsp3 -= sizeof(j6_process_init); - j6_process_init *init = reinterpret_cast(tcb->rsp3); + const char message[] = "Hello from the kernel!"; + char *message_arg = push(tcb->rsp3, sizeof(message)); + kutil::memcpy(message_arg, message, sizeof(message)); - init->process = proc.add_handle(&proc); - init->handles[0] = proc.add_handle(system::get()); - init->handles[1] = j6_handle_invalid; - init->handles[2] = j6_handle_invalid; + j6_init_framebuffer *fb_desc = push(tcb->rsp3); + fb_desc->addr = reinterpret_cast(0x100000000); + fb_desc->size = fb_size; + + j6_init_value *initv = push(tcb->rsp3); + initv->type = j6_init_handle_system; + initv->value = static_cast(proc.add_handle(system::get())); + + initv = push(tcb->rsp3); + initv->type = j6_init_handle_process; + initv->value = static_cast(proc.add_handle(&proc)); + + initv = push(tcb->rsp3); + initv->type = j6_init_handle_thread; + initv->value = static_cast(proc.add_handle(&th)); + + initv = push(tcb->rsp3); + initv->type = j6_init_handle_space; + //initv->value = static_cast(proc.add_handle(&space)); + + initv = push(tcb->rsp3); + initv->type = j6_init_desc_framebuffer; + initv->value = reinterpret_cast(fb_desc); + + uint64_t *initc = push(tcb->rsp3); + *initc = 5; + + char **argv0 = push(tcb->rsp3); + *argv0 = message_arg; + + uint64_t *argc = push(tcb->rsp3); + *argc = 1; // Crazypants framebuffer part - init->handles[1] = reinterpret_cast(fb_size); vma = new vm_area_open(fb_size, space, vm_flags::write|vm_flags::mmio); space.add(0x100000000, vma); vma->commit(fb_loc, 0, memory::page_count(fb_size)); - thread::current().clear_state(thread::state::loading); + th.clear_state(thread::state::loading); return tcb->rsp3; } diff --git a/src/drivers/fb/main.s b/src/libraries/libc/arch/x86_64/crt0.s similarity index 60% rename from src/drivers/fb/main.s rename to src/libraries/libc/arch/x86_64/crt0.s index e79154b..222f599 100644 --- a/src/drivers/fb/main.s +++ b/src/libraries/libc/arch/x86_64/crt0.s @@ -1,24 +1,19 @@ -section .bss -mymessage: - resq 1024 - extern main -extern _init_libc extern exit +extern _init_libc -section .text - -global _start +global _start:function (_start.end - _start) _start: mov rbp, rsp - mov rdi, rsp + call _init_libc - mov rdi, 0 - mov rsi, 0 + pop rdi + mov rsi, rsp call main mov rdi, rax call exit +.end: diff --git a/src/libraries/libc/arch/x86_64/init_libc.c b/src/libraries/libc/arch/x86_64/init_libc.c new file mode 100644 index 0000000..421e97d --- /dev/null +++ b/src/libraries/libc/arch/x86_64/init_libc.c @@ -0,0 +1,36 @@ +#include +#include +#include + +static size_t __initc = 0; +static struct j6_init_value *__initv = 0; + +j6_handle_t __handle_sys = j6_handle_invalid; + +void +_get_init(size_t *initc, struct j6_init_value **initv) +{ + if (!initc) + return; + + *initc = __initc; + if (initv) + *initv = __initv; +} + +void +_init_libc(uint64_t *rsp) +{ + uint64_t argc = *rsp++; + rsp += argc; + + __initc = *rsp++; + __initv = (struct j6_init_value *)rsp; + + for (unsigned i = 0; i < __initc; ++i) { + if (__initv[i].type == j6_init_handle_system) { + __handle_sys = __initv[i].value; + break; + } + } +}