Stage 26 v2

This commit is contained in:
2026-04-12 19:55:42 +08:00
parent aa8c0bd8d1
commit 901b63b9ba
8 changed files with 102 additions and 36 deletions

View File

@@ -1,27 +1,45 @@
#include <clks/elf64.h>
#include <clks/exec.h>
#include <clks/fs.h>
#include <clks/heap.h>
#include <clks/log.h>
#include <clks/string.h>
#include <clks/types.h>
typedef u64 (*clks_exec_entry_fn)(void);
#define CLKS_EXEC_STATUS_UNSUPPORTED 0xFFFFFFFFFFFFFFFEULL
#define CLKS_EXEC_RUN_STACK_BYTES (64ULL * 1024ULL)
#if defined(CLKS_ARCH_X86_64)
extern u64 clks_exec_call_on_stack_x86_64(void *entry_ptr, void *stack_top);
#endif
static u64 clks_exec_requests = 0ULL;
static u64 clks_exec_success = 0ULL;
static clks_bool clks_exec_is_sync_unsupported(const char *path) {
if (path == CLKS_NULL) {
static clks_bool clks_exec_invoke_entry(void *entry_ptr, u64 *out_ret) {
if (entry_ptr == CLKS_NULL || out_ret == CLKS_NULL) {
return CLKS_FALSE;
}
if (clks_strcmp(path, "/shell/shell.elf") == 0) {
#if defined(CLKS_ARCH_X86_64)
{
void *stack_base = clks_kmalloc((usize)CLKS_EXEC_RUN_STACK_BYTES);
void *stack_top;
if (stack_base == CLKS_NULL) {
clks_log(CLKS_LOG_WARN, "EXEC", "RUN STACK ALLOC FAILED");
return CLKS_FALSE;
}
stack_top = (void *)((u8 *)stack_base + (usize)CLKS_EXEC_RUN_STACK_BYTES);
*out_ret = clks_exec_call_on_stack_x86_64(entry_ptr, stack_top);
clks_kfree(stack_base);
return CLKS_TRUE;
}
return CLKS_FALSE;
#else
*out_ret = ((clks_exec_entry_fn)entry_ptr)();
return CLKS_TRUE;
#endif
}
void clks_exec_init(void) {
@@ -49,17 +67,6 @@ clks_bool clks_exec_run_path(const char *path, u64 *out_status) {
return CLKS_FALSE;
}
if (clks_exec_is_sync_unsupported(path) == CLKS_TRUE) {
clks_log(CLKS_LOG_WARN, "EXEC", "SYNC EXEC UNSUPPORTED FOR INTERACTIVE ELF");
clks_log(CLKS_LOG_WARN, "EXEC", path);
if (out_status != CLKS_NULL) {
*out_status = CLKS_EXEC_STATUS_UNSUPPORTED;
}
return CLKS_FALSE;
}
image = clks_fs_read_all(path, &image_size);
if (image == CLKS_NULL || image_size == 0ULL) {
@@ -93,7 +100,12 @@ clks_bool clks_exec_run_path(const char *path, u64 *out_status) {
clks_log_hex(CLKS_LOG_INFO, "EXEC", "ENTRY", info.entry);
clks_log_hex(CLKS_LOG_INFO, "EXEC", "PHNUM", (u64)info.phnum);
run_ret = ((clks_exec_entry_fn)entry_ptr)();
if (clks_exec_invoke_entry(entry_ptr, &run_ret) == CLKS_FALSE) {
clks_log(CLKS_LOG_WARN, "EXEC", "EXEC RUN INVOKE FAILED");
clks_log(CLKS_LOG_WARN, "EXEC", path);
clks_elf64_unload(&loaded);
return CLKS_FALSE;
}
clks_log(CLKS_LOG_INFO, "EXEC", "RUN RETURNED");
clks_log(CLKS_LOG_INFO, "EXEC", path);

View File

@@ -174,9 +174,7 @@ void clks_keyboard_handle_scancode(u8 scancode) {
clks_kbd_e0_prefix = CLKS_FALSE;
if (ext != '\0' && clks_keyboard_shell_input_enabled() == CLKS_TRUE) {
if (clks_keyboard_queue_push(ext) == CLKS_TRUE) {
clks_shell_pump_input(1U);
}
(void)clks_keyboard_queue_push(ext);
}
return;
@@ -204,9 +202,7 @@ void clks_keyboard_handle_scancode(u8 scancode) {
char translated = clks_keyboard_translate_scancode(code);
if (translated != '\0' && clks_keyboard_shell_input_enabled() == CLKS_TRUE) {
if (clks_keyboard_queue_push(translated) == CLKS_TRUE) {
clks_shell_pump_input(1U);
}
(void)clks_keyboard_queue_push(translated);
}
}
}
@@ -242,3 +238,4 @@ u64 clks_keyboard_push_count(void) {
u64 clks_keyboard_pop_count(void) {
return clks_kbd_pop_count;
}

View File

@@ -232,5 +232,13 @@ void clks_kernel_main(void) {
clks_log(CLKS_LOG_INFO, "TTY", "CURSOR ENABLED");
clks_log(CLKS_LOG_DEBUG, "KERNEL", "IDLE LOOP ENTER");
clks_cpu_halt_forever();
}
for (;;) {
u64 tick_now = clks_interrupts_timer_ticks();
clks_scheduler_dispatch_current(tick_now);
#if defined(CLKS_ARCH_X86_64)
__asm__ volatile("hlt");
#elif defined(CLKS_ARCH_AARCH64)
__asm__ volatile("wfe");
#endif
}
}

View File

@@ -11,6 +11,7 @@ static u32 clks_task_count = 0;
static u32 clks_current_task = 0;
static u64 clks_total_timer_ticks = 0;
static u64 clks_context_switch_count = 0;
static clks_bool clks_dispatch_active = CLKS_FALSE;
static void clks_sched_copy_name(char *dst, const char *src) {
u32 i = 0;
@@ -43,6 +44,7 @@ void clks_scheduler_init(void) {
clks_current_task = 0;
clks_total_timer_ticks = 0;
clks_context_switch_count = 0;
clks_dispatch_active = CLKS_FALSE;
clks_scheduler_add_kernel_task_ex("idle", 1U, CLKS_NULL);
@@ -94,6 +96,10 @@ void clks_scheduler_dispatch_current(u64 tick) {
return;
}
if (clks_dispatch_active == CLKS_TRUE) {
return;
}
current = &clks_tasks[clks_current_task];
if (current->state != CLKS_TASK_RUNNING && current->state != CLKS_TASK_READY) {
@@ -105,7 +111,9 @@ void clks_scheduler_dispatch_current(u64 tick) {
current->last_run_tick = tick;
if (current->entry != CLKS_NULL) {
clks_dispatch_active = CLKS_TRUE;
current->entry(tick);
clks_dispatch_active = CLKS_FALSE;
}
}
@@ -117,6 +125,11 @@ void clks_scheduler_on_timer_tick(u64 tick) {
}
clks_total_timer_ticks = tick;
if (clks_dispatch_active == CLKS_TRUE) {
return;
}
current = &clks_tasks[clks_current_task];
if (current->state == CLKS_TASK_RUNNING || current->state == CLKS_TASK_READY) {
@@ -144,8 +157,6 @@ void clks_scheduler_on_timer_tick(u64 tick) {
clks_context_switch_count++;
}
}
clks_scheduler_dispatch_current(tick);
}
struct clks_scheduler_stats clks_scheduler_get_stats(void) {