From 04e765f027b1c1c0a1539a067af1936f48ae8ae2 Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:08:30 -0400 Subject: [PATCH 01/10] Working app entrypoint before main --- src/apps/CMakeLists.txt | 48 ++++++++++++++++++++++++----------- src/apps/bar/src/bar.c | 2 +- src/apps/cinit/CMakeLists.txt | 4 +++ src/apps/cinit/link.ld | 30 ++++++++++++++++++++++ src/apps/cinit/src/cinit.c | 14 ++++++++++ src/apps/cinit/src/entry.asm | 9 +++++++ src/apps/demo/src/demo.c | 2 +- src/apps/foo/src/foo.c | 2 +- src/apps/getpid/src/getpid.c | 2 +- src/apps/ping/src/ping.c | 4 --- src/apps/pong/src/pong.c | 4 --- src/apps/shell/src/shell.c | 2 +- 12 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 src/apps/cinit/CMakeLists.txt create mode 100644 src/apps/cinit/link.ld create mode 100644 src/apps/cinit/src/cinit.c create mode 100644 src/apps/cinit/src/entry.asm diff --git a/src/apps/CMakeLists.txt b/src/apps/CMakeLists.txt index 4cf9f762..68ddbee1 100644 --- a/src/apps/CMakeLists.txt +++ b/src/apps/CMakeLists.txt @@ -1,23 +1,36 @@ -set(APPS_BASE_DIR ${CMAKE_BINARY_DIR}/apps) -execute_process(COMMAND mkdir -p ${APPS_BASE_DIR}) +set(DRIVE_BASE_DIR ${CMAKE_BINARY_DIR}/drive) +execute_process(COMMAND mkdir -p ${DRIVE_BASE_DIR}) macro(add_app target) cross_target(${target}) - target_link_libraries(${target} libc) + target_link_libraries(${target} cinit libc) cross_target_binary(${target}) - add_custom_command(OUTPUT ${APPS_BASE_DIR}/${target} - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${target}.bin ${APPS_BASE_DIR}/${target} - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf ${APPS_BASE_DIR}/${target}.elf + # Build raw binary for execution in os + add_custom_command(OUTPUT ${DRIVE_BASE_DIR}/${target} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${target}.bin ${DRIVE_BASE_DIR}/${target} + + # Output from cross_target_binary DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${target}.bin) + # Build elf executable for future use + add_custom_command(OUTPUT ${DRIVE_BASE_DIR}/${target}.elf + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf ${DRIVE_BASE_DIR}/${target}.elf + + # Output from cross_target_binary + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${target}.elf) + add_custom_target(${target}_app - DEPENDS ${APPS_BASE_DIR}/${target}) + DEPENDS ${DRIVE_BASE_DIR}/${target} ${DRIVE_BASE_DIR}/${target}.elf) list(APPEND APPS_TARGETS ${target} ${target}_app) set(APPS_TARGETS ${APPS_TARGETS} PARENT_SCOPE) endmacro() +# Code to run before calling app main (includes __start entrypoint) +add_subdirectory(cinit) + +# Programs loaded from disk add_subdirectory(foo) add_subdirectory(bar) add_subdirectory(init) @@ -30,20 +43,25 @@ add_subdirectory(getpid) message("App targets are ${APPS_TARGETS}") add_custom_command( - OUTPUT ${APPS_BASE_DIR}/data/ - COMMAND rm -rf ${APPS_BASE_DIR}/data/ - COMMAND mkdir -p ${APPS_BASE_DIR}/data/ - COMMAND cp -r ${CMAKE_SOURCE_DIR}/drive/* ${APPS_BASE_DIR}/data - DEPENDS ${CMAKE_SOURCE_DIR}/drive/ -) + OUTPUT ${DRIVE_BASE_DIR}/data/ + COMMAND rm -rf ${DRIVE_BASE_DIR}/data/ + COMMAND mkdir -p ${DRIVE_BASE_DIR}/data/ + COMMAND cp -r ${CMAKE_SOURCE_DIR}/drive/* ${DRIVE_BASE_DIR}/data + DEPENDS ${CMAKE_SOURCE_DIR}/drive/) add_custom_target(apps_data - DEPENDS ${APPS_BASE_DIR}/data/) + DEPENDS ${DRIVE_BASE_DIR}/data/) + +# Delete files in build/apps/data so it can be removed +set_property( + TARGET apps_data + APPEND + PROPERTY ADDITIONAL_CLEAN_FILES ${DRIVE_BASE_DIR}/data/) add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/apps.tar COMMAND tar -cf ${CMAKE_BINARY_DIR}/apps.tar * DEPENDS ${APPS_TARGETS} apps_data - WORKING_DIRECTORY ${APPS_BASE_DIR}) + WORKING_DIRECTORY ${DRIVE_BASE_DIR}) add_custom_target(apps_image ALL DEPENDS ${CMAKE_BINARY_DIR}/apps.tar) diff --git a/src/apps/bar/src/bar.c b/src/apps/bar/src/bar.c index 9235242b..6008f4e1 100644 --- a/src/apps/bar/src/bar.c +++ b/src/apps/bar/src/bar.c @@ -3,7 +3,7 @@ #include "libc/stdio.h" -int __start(size_t argc, char ** argv) { +int main(size_t argc, char ** argv) { printf("Bar got %u arguments\n", argc); for (size_t i = 0; i < argc; i++) { diff --git a/src/apps/cinit/CMakeLists.txt b/src/apps/cinit/CMakeLists.txt new file mode 100644 index 00000000..e2d18641 --- /dev/null +++ b/src/apps/cinit/CMakeLists.txt @@ -0,0 +1,4 @@ +set(TARGET cinit) + +cross_target(${TARGET}) +target_link_libraries(${TARGET} libc) diff --git a/src/apps/cinit/link.ld b/src/apps/cinit/link.ld new file mode 100644 index 00000000..28e2cfdc --- /dev/null +++ b/src/apps/cinit/link.ld @@ -0,0 +1,30 @@ +ENTRY(__start) + +SECTIONS { + . = 0x400000; + + .text : + { + *(.text.entry) + *(.text) + } + + /* Read-only data. */ + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + /* Read-write data (initialized) */ + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + /* Read-write data (uninitialized) and stack */ + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } +} \ No newline at end of file diff --git a/src/apps/cinit/src/cinit.c b/src/apps/cinit/src/cinit.c new file mode 100644 index 00000000..18a7c8ec --- /dev/null +++ b/src/apps/cinit/src/cinit.c @@ -0,0 +1,14 @@ +#include "libc/stdio.h" +#include "libc/proc.h" + +extern int main(size_t argc, char ** argv); + +void __cinit(size_t argc, char ** argv) { + printf("c init\n"); + // TODO init malloc + // TODO is there anything in signals or system calls to setup? + // TODO do stdio handles setup here? + int res = main(argc, argv); + printf("Main returned %d\n", res); + proc_exit(res); +} diff --git a/src/apps/cinit/src/entry.asm b/src/apps/cinit/src/entry.asm new file mode 100644 index 00000000..f1c10222 --- /dev/null +++ b/src/apps/cinit/src/entry.asm @@ -0,0 +1,9 @@ +extern __cinit +extern main + +section .text.entry + +global __start +__start: + call __cinit + ; jmp main diff --git a/src/apps/demo/src/demo.c b/src/apps/demo/src/demo.c index 31803f0e..2b6d6429 100644 --- a/src/apps/demo/src/demo.c +++ b/src/apps/demo/src/demo.c @@ -2,7 +2,7 @@ #include "libc/proc.h" #include "libc/stdio.h" -int __start(size_t argc, char ** argv) { +int main(size_t argc, char ** argv) { printf("Lets demo some cool features of printf\n"); int len = printf("Like the percent sign %%, \na signed int %d, a signed int with width formatting %4d, \nleading zeros %04d, left align %-4d\n", 10, 10, 10, 10); len += printf("How about negative numbers: signed %d and unsigned %u\n", -10, -10); diff --git a/src/apps/foo/src/foo.c b/src/apps/foo/src/foo.c index 293b553a..765ee444 100644 --- a/src/apps/foo/src/foo.c +++ b/src/apps/foo/src/foo.c @@ -13,6 +13,6 @@ void foo() { proc_exit(0); } -void __start() { +void main() { foo(); } diff --git a/src/apps/getpid/src/getpid.c b/src/apps/getpid/src/getpid.c index 2c6f3679..e02eadc8 100644 --- a/src/apps/getpid/src/getpid.c +++ b/src/apps/getpid/src/getpid.c @@ -1,7 +1,7 @@ #include "libc/proc.h" #include "libc/stdio.h" -void __start() { +void main() { int pid = getpid(); printf("PID is %u\n"); } diff --git a/src/apps/ping/src/ping.c b/src/apps/ping/src/ping.c index 5495f2a4..3d3bf97f 100644 --- a/src/apps/ping/src/ping.c +++ b/src/apps/ping/src/ping.c @@ -7,7 +7,3 @@ void main() { yield(); } } - -void __start() { - main(); -} diff --git a/src/apps/pong/src/pong.c b/src/apps/pong/src/pong.c index 1bf4053c..d1c41aa1 100644 --- a/src/apps/pong/src/pong.c +++ b/src/apps/pong/src/pong.c @@ -7,7 +7,3 @@ void main() { yield(); } } - -void __start() { - main(); -} diff --git a/src/apps/shell/src/shell.c b/src/apps/shell/src/shell.c index 73cc24f6..8fb26547 100644 --- a/src/apps/shell/src/shell.c +++ b/src/apps/shell/src/shell.c @@ -48,7 +48,7 @@ static size_t buff_read(const cb_t * cb, uint8_t * data, size_t count); static size_t buff_remove(cb_t * cb, size_t count); static void exec_buff(); -int __start(size_t argc, char ** argv) { +int main(size_t argc, char ** argv) { term_command_add("help", help_cmd); init_commands(); From 3d375765d78deca80cd6a1fc56162fe41a7f438d Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:08:51 -0400 Subject: [PATCH 02/10] Assign foreground process --- src/kernel/src/process_manager.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/kernel/src/process_manager.c b/src/kernel/src/process_manager.c index 7f4bf13d..b54a4838 100644 --- a/src/kernel/src/process_manager.c +++ b/src/kernel/src/process_manager.c @@ -173,6 +173,8 @@ int pm_resume_process(proc_man_t * pm, int pid) { return -1; } + pm->foreground_task = proc; + if (proc->filter_event.event_id) { // TODO assert next_event has an event of the correct type // TODO push to process next_event instead of event_queue From a11f9e470e9bae003841c0bf3c9d569284f62d5b Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:09:35 -0400 Subject: [PATCH 03/10] Fix check if process is alive --- src/kernel/src/process_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/src/process_manager.c b/src/kernel/src/process_manager.c index b54a4838..16973a12 100644 --- a/src/kernel/src/process_manager.c +++ b/src/kernel/src/process_manager.c @@ -198,7 +198,7 @@ process_t * pm_get_next(proc_man_t * pm) { do { // KLOG_TRACE("Looking at pid %u in state %u to see if it's ready", proc->pid, proc->state); - if (PROCESS_STATE_LOADED <= proc->state <= PROCESS_STATE_DEAD) { + if (proc->state > PROCESS_STATE_LOADED && proc->state < PROCESS_STATE_DEAD) { if (!proc->filter_event.event_id) { // KLOG_TRACE("Process %u has no filter event, so it's ready", proc->pid); return proc; From bd08581114e9d0b4ada390cd458d42a4eda21876 Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:09:43 -0400 Subject: [PATCH 04/10] Re-enable a bunch of logging --- src/kernel/src/process_manager.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/kernel/src/process_manager.c b/src/kernel/src/process_manager.c index 16973a12..9e21fafb 100644 --- a/src/kernel/src/process_manager.c +++ b/src/kernel/src/process_manager.c @@ -193,14 +193,14 @@ process_t * pm_get_next(proc_man_t * pm) { process_t * proc = pm->foreground_task->next; - // KLOG_TRACE("Start looking for next process"); + KLOG_TRACE("Start looking for next process after %u", pm->foreground_task->pid); do { - // KLOG_TRACE("Looking at pid %u in state %u to see if it's ready", proc->pid, proc->state); + KLOG_TRACE("Looking at pid %u in state %u to see if it's ready", proc->pid, proc->state); if (proc->state > PROCESS_STATE_LOADED && proc->state < PROCESS_STATE_DEAD) { if (!proc->filter_event.event_id) { - // KLOG_TRACE("Process %u has no filter event, so it's ready", proc->pid); + KLOG_TRACE("Process %u has no filter event, so it's ready", proc->pid); return proc; } // This handles the above case but is split for trace log @@ -208,20 +208,20 @@ process_t * pm_get_next(proc_man_t * pm) { KLOG_TRACE("Process %u has ready event %u", proc->pid, proc->next_event.event_id); return proc; } - // KLOG_TRACE("Process %u is not ready, waiting for %u", proc->pid, proc->filter_event.event_id); + KLOG_TRACE("Process %u is not ready, waiting for %u", proc->pid, proc->filter_event.event_id); } else { - // KLOG_TRACE("Process with pid %u is not alive", proc->pid); + KLOG_TRACE("Process with pid %u is not alive", proc->pid); } - // KLOG_TRACE("Going to next process %u, fg is %u", proc->next->pid, pm->foreground_task->pid); + KLOG_TRACE("Going to next process %u, fg is %u", proc->next->pid, pm->foreground_task->pid); proc = proc->next; } while (proc != pm->foreground_task->next); - // KLOG_TRACE("Finish looking for next process"); + KLOG_TRACE("Finish looking for next process"); if (PROCESS_STATE_LOADED <= proc->state <= PROCESS_STATE_DEAD) { - // KLOG_TRACE("Next process is the foreground process with pid %u", proc->pid); + KLOG_TRACE("Next process is the foreground process with pid %u", proc->pid); return proc; } From fa9411262ef05e4d079075ad5baa965e0d624bb3 Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:10:07 -0400 Subject: [PATCH 05/10] Finish proc exit and proc abort system calls --- src/kernel/src/kernel/system_call_proc.c | 43 ++++++++++-------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/kernel/src/kernel/system_call_proc.c b/src/kernel/src/kernel/system_call_proc.c index a822da0a..264bb45c 100644 --- a/src/kernel/src/kernel/system_call_proc.c +++ b/src/kernel/src/kernel/system_call_proc.c @@ -27,28 +27,20 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) { break; } - // TODO this isn't fully updated with task switching - case SYS_CALL_PROC_EXIT: { - KLOG_DEBUG("System call proc exit"); - struct _args { - uint8_t code; - } * args = (struct _args *)args_data; - printf("Proc exit with code %u\n", args->code); - enable_interrupts(); + KLOG_DEBUG("Setting process %u state from %u to %u", proc->pid, proc->state, PROCESS_STATE_DEAD); + proc->state = PROCESS_STATE_DEAD; - ebus_event_t event = {0}; - event.event_id = EBUS_EVENT_PROC_CLOSE; - event.proc_close.pid = get_active_task()->pid; - event.proc_close.status_code = args->code; + enable_interrupts(); + process_t * next = pm_get_next(kernel_get_proc_man()); + KLOG_DEBUG("Next after %u is %u in state %u", proc->pid, next->pid, next->state); + if (pm_resume_process(kernel_get_proc_man(), next->pid)) { + KPANIC("Failed to resume process"); + } - queue_event(&event); - kernel_switch_task(); - KPANIC("Unexpected return from kernel_switch_task"); + KPANIC("Unexpected return from pm_resume_process in SYS_CALL_PROC_EXIT"); } break; - // TODO this isn't fully updated with task switching - case SYS_CALL_PROC_ABORT: { KLOG_DEBUG("System call proc abort"); struct _args { @@ -57,17 +49,16 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) { } * args = (struct _args *)args_data; printf("Proc abort with code %u\n", args->code); puts(args->msg); - process_t * proc = get_current_process(); - enable_interrupts(); + proc->state = PROCESS_STATE_DEAD; - ebus_event_t event = {0}; - event.event_id = EBUS_EVENT_PROC_CLOSE; - event.proc_close.pid = get_active_task()->pid; - event.proc_close.status_code = args->code; + enable_interrupts(); + process_t * next = pm_get_next(kernel_get_proc_man()); + KLOG_DEBUG("Next after %u is %u in state %u", proc->pid, next->pid, next->state); + if (pm_resume_process(kernel_get_proc_man(), next->pid)) { + KPANIC("Failed to resume process"); + } - queue_event(&event); - kernel_switch_task(); - KPANIC("Unexpected return from kernel_switch_task"); + KPANIC("Unexpected return from pm_resume_process in SYS_CALL_PROC_ABORT"); } break; case SYS_CALL_PROC_PANIC: { From f6a76812b31e69232c217418bfae9c9911f0358b Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:29:03 -0400 Subject: [PATCH 06/10] format --- src/apps/cinit/src/cinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/cinit/src/cinit.c b/src/apps/cinit/src/cinit.c index 18a7c8ec..2c601456 100644 --- a/src/apps/cinit/src/cinit.c +++ b/src/apps/cinit/src/cinit.c @@ -1,5 +1,5 @@ -#include "libc/stdio.h" #include "libc/proc.h" +#include "libc/stdio.h" extern int main(size_t argc, char ** argv); From 842cf1213fc0e485d5726432675150e8056da3bc Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:29:21 -0400 Subject: [PATCH 07/10] Update scheduler to use current task switch logic --- src/kernel/src/kernel/scheduler.c | 69 +++++++++---------------------- 1 file changed, 19 insertions(+), 50 deletions(-) diff --git a/src/kernel/src/kernel/scheduler.c b/src/kernel/src/kernel/scheduler.c index a38e597a..aa164a27 100644 --- a/src/kernel/src/kernel/scheduler.c +++ b/src/kernel/src/kernel/scheduler.c @@ -10,75 +10,44 @@ static void idle(); int scheduler_init(scheduler_t * scheduler, proc_man_t * pm) { - if (!scheduler || !pm) { + if (!scheduler) { + KLOG_ERROR("scheduler_init received a null pointer for the scheduler struct"); + return -1; + } + if (!pm) { + KLOG_ERROR("scheduler_init received a null pointer for the process manager struct"); return -1; } + KLOG_TRACE("Clearing scheduler struct"); kmemset(scheduler, 0, sizeof(scheduler_t)); + KLOG_TRACE("Useing process manager %p in scheduler %p", pm, scheduler); scheduler->pm = pm; + KLOG_TRACE("Finished init of scheduler %p", scheduler); + return 0; } // TODO this is just a copy of the kernel / process manager current behavior int scheduler_run(scheduler_t * scheduler) { if (!scheduler) { + KLOG_ERROR("scheduler_run received a null pointer"); return -1; } - if (cb_len(&get_kernel()->event_queue.queue) > 0) { - KLOG_DEBUG("There are %u events ready", cb_len(&get_kernel()->event_queue.queue)); - ebus_event_t event; - - if (cb_pop(&get_kernel()->event_queue.queue, &event) < 0) { - KPANIC("Failed to pop from event queue"); - } - - switch (event.event_id) { - case EBUS_EVENT_EXEC: { - int pid = kernel_exec(event.exec.filename, event.exec.argc, event.exec.argv); - if (pid > 0) { - ebus_event_t proc_event = {0}; - proc_event.event_id = EBUS_EVENT_PROC_MADE; - proc_event.proc_made.pid = pid; - if (ebus_push(&get_kernel()->event_queue, &proc_event)) { - KPANIC("Ebus push failed"); - } - } - } break; - - case EBUS_EVENT_PROC_CLOSE: { - process_t * proc = kernel_find_pid(event.proc_close.pid); - if (!proc) { - KPANIC("Failed to find pid"); - } - if (pm_remove_proc(&get_kernel()->pm, proc->pid)) { - KPANIC("Failed to remove process from pm"); - } - process_free(proc); - } break; - - default: { - if (pm_push_event(&get_kernel()->pm, &event)) { - KPANIC("Failed to push event to process manager"); - } - } break; - } + process_t * proc = get_active_task(); + if (!proc) { + KPANIC("Failed to get active process"); } - process_t * next = pm_get_next(scheduler->pm); + process_t * next = pm_get_next(kernel_get_proc_man()); + KLOG_TRACE("Next after %u is %u in state %u", proc->pid, next->pid, next->state); - if (next) { - // TODO ebus events - process_resume(next, 0); - KPANIC("PROCESS SHOULD NOT RETURN TO SCHEDULER!"); + if (pm_resume_process(kernel_get_proc_man(), next->pid)) { + KPANIC("Failed to resume process"); } - else { - idle(); - } -} -static void idle() { - asm("hlt"); + KLOG_TRACE("Returned to process %u", proc->pid); } From 0618da2f3938f41ec2d8b4b2fadf9017b9a250de Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:29:56 -0400 Subject: [PATCH 08/10] Update sys call proc panic to switch tasks instead of halting kernel --- src/kernel/src/kernel/system_call_proc.c | 37 ++++++++++++++---------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/kernel/src/kernel/system_call_proc.c b/src/kernel/src/kernel/system_call_proc.c index 264bb45c..ef8f0bbc 100644 --- a/src/kernel/src/kernel/system_call_proc.c +++ b/src/kernel/src/kernel/system_call_proc.c @@ -62,29 +62,36 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) { } break; case SYS_CALL_PROC_PANIC: { - KLOG_DEBUG("System call proc panic"); struct _args { const char * msg; const char * file; unsigned int line; } * args = (struct _args *)args_data; - vga_color(VGA_FG_WHITE | VGA_BG_RED); - vga_puts("[PANIC]"); - if (args->file) { - vga_putc('['); - vga_puts(args->file); - vga_puts("]:"); - vga_putu(args->line); + + // Default empty string if not provided by process + const char * file = ""; + if (!file) { + file = args->file; } - if (args->msg) { - vga_putc(' '); - vga_puts(args->msg); + + // Default empty string if not provided by process + const char * msg = ""; + if (!msg) { + msg = args->msg; } - vga_cursor_hide(); - asm("cli"); - for (;;) { - asm("hlt"); + + KLOG_WARNING("Process %u panicked in %s at line %s: %s", proc->pid, file, args->line, msg); + + proc->state = PROCESS_STATE_DEAD; + + enable_interrupts(); + process_t * next = pm_get_next(kernel_get_proc_man()); + KLOG_DEBUG("Next after %u is %u in state %u", proc->pid, next->pid, next->state); + if (pm_resume_process(kernel_get_proc_man(), next->pid)) { + KPANIC("Failed to resume process"); } + + KPANIC("Unexpected return from pm_resume_process in SYS_CALL_PROC_PANIC"); } break; case SYS_CALL_PROC_REG_SIG: { From d98ca107df62a93b7bc19e3bca9141e0ad6184d0 Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:46:20 -0400 Subject: [PATCH 09/10] Catch error from scheduler_run in kernel_switch_task --- src/kernel/include/kernel.h | 4 +--- src/kernel/src/kernel.c | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/kernel/include/kernel.h b/src/kernel/include/kernel.h index 5b74647e..67c0aa5e 100644 --- a/src/kernel/include/kernel.h +++ b/src/kernel/include/kernel.h @@ -48,8 +48,6 @@ void kernel_queue_event(ebus_event_t * event); typedef int (*_proc_call_t)(void * data); -int kernel_call_as_proc(int pid, _proc_call_t fn, void * data); - -int kernel_switch_task(); +void kernel_switch_task(); #endif // KERNEL_H diff --git a/src/kernel/src/kernel.c b/src/kernel/src/kernel.c index 4c2ff789..60b96401 100644 --- a/src/kernel/src/kernel.c +++ b/src/kernel/src/kernel.c @@ -154,8 +154,10 @@ int kernel_exec(const char * filename, size_t argc, char ** argv) { return pid; } -int kernel_switch_task() { - return scheduler_run(&__kernel.scheduler); +void kernel_switch_task() { + if (scheduler_run(&__kernel.scheduler)) { + KPANIC("Failed to switch tasks"); + } } process_t * get_current_process() { From c90f8efe3000019f0554678fd9f34d220409cddd Mon Sep 17 00:00:00 2001 From: Thomas Harrison Date: Thu, 19 Mar 2026 17:46:44 -0400 Subject: [PATCH 10/10] Use kernel_switch_task for all task switching --- src/kernel/src/kernel/scheduler.c | 3 --- src/kernel/src/kernel/system_call_event.c | 15 +++--------- src/kernel/src/kernel/system_call_proc.c | 30 ++++++----------------- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/src/kernel/src/kernel/scheduler.c b/src/kernel/src/kernel/scheduler.c index aa164a27..b2348621 100644 --- a/src/kernel/src/kernel/scheduler.c +++ b/src/kernel/src/kernel/scheduler.c @@ -7,8 +7,6 @@ #include "kernel/logs.h" #include "libc/string.h" -static void idle(); - int scheduler_init(scheduler_t * scheduler, proc_man_t * pm) { if (!scheduler) { KLOG_ERROR("scheduler_init received a null pointer for the scheduler struct"); @@ -30,7 +28,6 @@ int scheduler_init(scheduler_t * scheduler, proc_man_t * pm) { return 0; } -// TODO this is just a copy of the kernel / process manager current behavior int scheduler_run(scheduler_t * scheduler) { if (!scheduler) { KLOG_ERROR("scheduler_run received a null pointer"); diff --git a/src/kernel/src/kernel/system_call_event.c b/src/kernel/src/kernel/system_call_event.c index 4a105dd1..b5695b8c 100644 --- a/src/kernel/src/kernel/system_call_event.c +++ b/src/kernel/src/kernel/system_call_event.c @@ -46,10 +46,7 @@ int sys_call_event_cb(uint32_t call_id, void * args_data, registers_t * regs) { proc->state = PROCESS_STATE_WAITING; enable_interrupts(); - process_t * next = pm_get_next(kernel_get_proc_man()); - if (pm_resume_process(kernel_get_proc_man(), next->pid)) { - KPANIC("Failed to resume process"); - } + kernel_switch_task(); // args->filter doesn't appear to be valid here, why not? if (!(proc->next_event.event_id == proc->filter_event.event_id)) { @@ -65,10 +62,7 @@ int sys_call_event_cb(uint32_t call_id, void * args_data, registers_t * regs) { case SYS_CALL_EVENT_TIME: { enable_interrupts(); - process_t * next = pm_get_next(kernel_get_proc_man()); - if (pm_resume_process(kernel_get_proc_man(), next->pid)) { - KPANIC("Failed to resume process"); - } + kernel_switch_task(); return time_s(); } break; @@ -103,10 +97,7 @@ int sys_call_event_cb(uint32_t call_id, void * args_data, registers_t * regs) { do { enable_interrupts(); - process_t * next = pm_get_next(kernel_get_proc_man()); - if (pm_resume_process(kernel_get_proc_man(), next->pid)) { - KPANIC("Failed to resume process"); - } + kernel_switch_task(); KLOG_TRACE("Back from timer %u", timer_id); } while (proc->next_event.timer.id != timer_id); } break; diff --git a/src/kernel/src/kernel/system_call_proc.c b/src/kernel/src/kernel/system_call_proc.c index ef8f0bbc..7f64008e 100644 --- a/src/kernel/src/kernel/system_call_proc.c +++ b/src/kernel/src/kernel/system_call_proc.c @@ -10,6 +10,7 @@ #include "exec.h" #include "kernel.h" #include "kernel/logs.h" +#include "kernel/scheduler.h" #include "libc/proc.h" #include "libc/stdio.h" #include "libc/string.h" @@ -32,13 +33,9 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) { proc->state = PROCESS_STATE_DEAD; enable_interrupts(); - process_t * next = pm_get_next(kernel_get_proc_man()); - KLOG_DEBUG("Next after %u is %u in state %u", proc->pid, next->pid, next->state); - if (pm_resume_process(kernel_get_proc_man(), next->pid)) { - KPANIC("Failed to resume process"); - } + kernel_switch_task(); - KPANIC("Unexpected return from pm_resume_process in SYS_CALL_PROC_EXIT"); + KPANIC("Unexpected return from task switch in SYS_CALL_PROC_EXIT"); } break; case SYS_CALL_PROC_ABORT: { @@ -52,13 +49,9 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) { proc->state = PROCESS_STATE_DEAD; enable_interrupts(); - process_t * next = pm_get_next(kernel_get_proc_man()); - KLOG_DEBUG("Next after %u is %u in state %u", proc->pid, next->pid, next->state); - if (pm_resume_process(kernel_get_proc_man(), next->pid)) { - KPANIC("Failed to resume process"); - } + kernel_switch_task(); - KPANIC("Unexpected return from pm_resume_process in SYS_CALL_PROC_ABORT"); + KPANIC("Unexpected return from task switch in SYS_CALL_PROC_ABORT"); } break; case SYS_CALL_PROC_PANIC: { @@ -85,13 +78,9 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) { proc->state = PROCESS_STATE_DEAD; enable_interrupts(); - process_t * next = pm_get_next(kernel_get_proc_man()); - KLOG_DEBUG("Next after %u is %u in state %u", proc->pid, next->pid, next->state); - if (pm_resume_process(kernel_get_proc_man(), next->pid)) { - KPANIC("Failed to resume process"); - } + kernel_switch_task(); - KPANIC("Unexpected return from pm_resume_process in SYS_CALL_PROC_PANIC"); + KPANIC("Unexpected return from task switch in SYS_CALL_PROC_PANIC"); } break; case SYS_CALL_PROC_REG_SIG: { @@ -133,10 +122,7 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) { proc->state = PROCESS_STATE_SUSPENDED; enable_interrupts(); - process_t * next = pm_get_next(kernel_get_proc_man()); - if (pm_resume_process(kernel_get_proc_man(), next->pid)) { - KPANIC("Failed to resume process"); - } + kernel_switch_task(); } break; case SYS_CALL_PROC_EXEC: {