mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
Stage 26 v2
This commit is contained in:
@@ -242,6 +242,18 @@ static int shell_resolve_exec_path(const char *arg, char *out_path, u64 out_size
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int shell_path_is_under_system(const char *path) {
|
||||||
|
if (path == (const char *)0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path[0] != '/' || path[1] != 's' || path[2] != 'y' || path[3] != 's' || path[4] != 't' || path[5] != 'e' || path[6] != 'm') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (path[7] == '\0' || path[7] == '/') ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void shell_cmd_help(void) {
|
static void shell_cmd_help(void) {
|
||||||
shell_writeln("commands:");
|
shell_writeln("commands:");
|
||||||
shell_writeln(" help");
|
shell_writeln(" help");
|
||||||
@@ -319,12 +331,19 @@ static void shell_cmd_exec(const char *arg) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shell_path_is_under_system(path) != 0) {
|
||||||
|
shell_writeln("exec: /system/*.elf is kernel-mode (KELF), not user-exec");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
status = cleonos_sys_exec_path(path);
|
status = cleonos_sys_exec_path(path);
|
||||||
|
|
||||||
if (status == 0ULL) {
|
if (status == (u64)-1) {
|
||||||
|
shell_writeln("exec: request failed");
|
||||||
|
} else if (status == 0ULL) {
|
||||||
shell_writeln("exec: request accepted");
|
shell_writeln("exec: request accepted");
|
||||||
} else {
|
} else {
|
||||||
shell_writeln("exec: request failed");
|
shell_writeln("exec: returned non-zero status");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
clks/arch/x86_64/exec_stack_call.S
Normal file
19
clks/arch/x86_64/exec_stack_call.S
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
.global clks_exec_call_on_stack_x86_64
|
||||||
|
.type clks_exec_call_on_stack_x86_64, @function
|
||||||
|
|
||||||
|
clks_exec_call_on_stack_x86_64:
|
||||||
|
mov r11, rsp
|
||||||
|
mov rsp, rsi
|
||||||
|
and rsp, -16
|
||||||
|
sub rsp, 8
|
||||||
|
mov [rsp], r11
|
||||||
|
|
||||||
|
call rdi
|
||||||
|
|
||||||
|
mov rsp, [rsp]
|
||||||
|
ret
|
||||||
|
|
||||||
|
.size clks_exec_call_on_stack_x86_64, .-clks_exec_call_on_stack_x86_64
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
@@ -1,27 +1,45 @@
|
|||||||
#include <clks/elf64.h>
|
#include <clks/elf64.h>
|
||||||
#include <clks/exec.h>
|
#include <clks/exec.h>
|
||||||
#include <clks/fs.h>
|
#include <clks/fs.h>
|
||||||
|
#include <clks/heap.h>
|
||||||
#include <clks/log.h>
|
#include <clks/log.h>
|
||||||
#include <clks/string.h>
|
|
||||||
#include <clks/types.h>
|
#include <clks/types.h>
|
||||||
|
|
||||||
typedef u64 (*clks_exec_entry_fn)(void);
|
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_requests = 0ULL;
|
||||||
static u64 clks_exec_success = 0ULL;
|
static u64 clks_exec_success = 0ULL;
|
||||||
|
|
||||||
static clks_bool clks_exec_is_sync_unsupported(const char *path) {
|
static clks_bool clks_exec_invoke_entry(void *entry_ptr, u64 *out_ret) {
|
||||||
if (path == CLKS_NULL) {
|
if (entry_ptr == CLKS_NULL || out_ret == CLKS_NULL) {
|
||||||
return CLKS_FALSE;
|
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_TRUE;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
return CLKS_FALSE;
|
*out_ret = ((clks_exec_entry_fn)entry_ptr)();
|
||||||
|
return CLKS_TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void clks_exec_init(void) {
|
void clks_exec_init(void) {
|
||||||
@@ -49,17 +67,6 @@ clks_bool clks_exec_run_path(const char *path, u64 *out_status) {
|
|||||||
return CLKS_FALSE;
|
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);
|
image = clks_fs_read_all(path, &image_size);
|
||||||
|
|
||||||
if (image == CLKS_NULL || image_size == 0ULL) {
|
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", "ENTRY", info.entry);
|
||||||
clks_log_hex(CLKS_LOG_INFO, "EXEC", "PHNUM", (u64)info.phnum);
|
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", "RUN RETURNED");
|
||||||
clks_log(CLKS_LOG_INFO, "EXEC", path);
|
clks_log(CLKS_LOG_INFO, "EXEC", path);
|
||||||
|
|||||||
@@ -174,9 +174,7 @@ void clks_keyboard_handle_scancode(u8 scancode) {
|
|||||||
clks_kbd_e0_prefix = CLKS_FALSE;
|
clks_kbd_e0_prefix = CLKS_FALSE;
|
||||||
|
|
||||||
if (ext != '\0' && clks_keyboard_shell_input_enabled() == CLKS_TRUE) {
|
if (ext != '\0' && clks_keyboard_shell_input_enabled() == CLKS_TRUE) {
|
||||||
if (clks_keyboard_queue_push(ext) == CLKS_TRUE) {
|
(void)clks_keyboard_queue_push(ext);
|
||||||
clks_shell_pump_input(1U);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -204,9 +202,7 @@ void clks_keyboard_handle_scancode(u8 scancode) {
|
|||||||
char translated = clks_keyboard_translate_scancode(code);
|
char translated = clks_keyboard_translate_scancode(code);
|
||||||
|
|
||||||
if (translated != '\0' && clks_keyboard_shell_input_enabled() == CLKS_TRUE) {
|
if (translated != '\0' && clks_keyboard_shell_input_enabled() == CLKS_TRUE) {
|
||||||
if (clks_keyboard_queue_push(translated) == CLKS_TRUE) {
|
(void)clks_keyboard_queue_push(translated);
|
||||||
clks_shell_pump_input(1U);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,3 +238,4 @@ u64 clks_keyboard_push_count(void) {
|
|||||||
u64 clks_keyboard_pop_count(void) {
|
u64 clks_keyboard_pop_count(void) {
|
||||||
return clks_kbd_pop_count;
|
return clks_kbd_pop_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -232,5 +232,13 @@ void clks_kernel_main(void) {
|
|||||||
clks_log(CLKS_LOG_INFO, "TTY", "CURSOR ENABLED");
|
clks_log(CLKS_LOG_INFO, "TTY", "CURSOR ENABLED");
|
||||||
clks_log(CLKS_LOG_DEBUG, "KERNEL", "IDLE LOOP ENTER");
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ static u32 clks_task_count = 0;
|
|||||||
static u32 clks_current_task = 0;
|
static u32 clks_current_task = 0;
|
||||||
static u64 clks_total_timer_ticks = 0;
|
static u64 clks_total_timer_ticks = 0;
|
||||||
static u64 clks_context_switch_count = 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) {
|
static void clks_sched_copy_name(char *dst, const char *src) {
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
@@ -43,6 +44,7 @@ void clks_scheduler_init(void) {
|
|||||||
clks_current_task = 0;
|
clks_current_task = 0;
|
||||||
clks_total_timer_ticks = 0;
|
clks_total_timer_ticks = 0;
|
||||||
clks_context_switch_count = 0;
|
clks_context_switch_count = 0;
|
||||||
|
clks_dispatch_active = CLKS_FALSE;
|
||||||
|
|
||||||
clks_scheduler_add_kernel_task_ex("idle", 1U, CLKS_NULL);
|
clks_scheduler_add_kernel_task_ex("idle", 1U, CLKS_NULL);
|
||||||
|
|
||||||
@@ -94,6 +96,10 @@ void clks_scheduler_dispatch_current(u64 tick) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clks_dispatch_active == CLKS_TRUE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
current = &clks_tasks[clks_current_task];
|
current = &clks_tasks[clks_current_task];
|
||||||
|
|
||||||
if (current->state != CLKS_TASK_RUNNING && current->state != CLKS_TASK_READY) {
|
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;
|
current->last_run_tick = tick;
|
||||||
|
|
||||||
if (current->entry != CLKS_NULL) {
|
if (current->entry != CLKS_NULL) {
|
||||||
|
clks_dispatch_active = CLKS_TRUE;
|
||||||
current->entry(tick);
|
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;
|
clks_total_timer_ticks = tick;
|
||||||
|
|
||||||
|
if (clks_dispatch_active == CLKS_TRUE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
current = &clks_tasks[clks_current_task];
|
current = &clks_tasks[clks_current_task];
|
||||||
|
|
||||||
if (current->state == CLKS_TASK_RUNNING || current->state == CLKS_TASK_READY) {
|
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_context_switch_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clks_scheduler_dispatch_current(tick);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct clks_scheduler_stats clks_scheduler_get_stats(void) {
|
struct clks_scheduler_stats clks_scheduler_get_stats(void) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
- Updated CMake ramdisk placement rules:
|
- Updated CMake ramdisk placement rules:
|
||||||
- `hello.elf` -> `/hello.elf`
|
- `hello.elf` -> `/hello.elf`
|
||||||
- Simplified user Rust library back to shared helper export (`cleonos_rust_guarded_len`).
|
- Simplified user Rust library back to shared helper export (`cleonos_rust_guarded_len`).
|
||||||
|
- Added x86_64 exec stack bridge (`clks_exec_call_on_stack_x86_64`) so ELF entry runs on a dedicated execution stack instead of inheriting deep shell call stack.
|
||||||
|
|
||||||
## Acceptance Criteria
|
## Acceptance Criteria
|
||||||
- No `elfloader.elf` is generated or packed.
|
- No `elfloader.elf` is generated or packed.
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
- In kernel shell:
|
- In kernel shell:
|
||||||
- `elfloader` loads and executes `/hello.elf`, then returns status.
|
- `elfloader` loads and executes `/hello.elf`, then returns status.
|
||||||
- `elfloader /path/to/app.elf` works for other absolute/relative paths.
|
- `elfloader /path/to/app.elf` works for other absolute/relative paths.
|
||||||
|
- `exec /shell/shell.elf` can take foreground control without immediate stack-chain crash.
|
||||||
|
|
||||||
## Build Targets
|
## Build Targets
|
||||||
- `make userapps`
|
- `make userapps`
|
||||||
@@ -33,5 +35,4 @@
|
|||||||
- If `elfloader` reports `file missing`, check ramdisk root packaging for `/hello.elf`.
|
- If `elfloader` reports `file missing`, check ramdisk root packaging for `/hello.elf`.
|
||||||
- If it reports `invalid elf64`, verify user app link script and ELF output format.
|
- If it reports `invalid elf64`, verify user app link script and ELF output format.
|
||||||
- If it reports `exec failed`, inspect `EXEC` channel logs for load/entry/return status.
|
- If it reports `exec failed`, inspect `EXEC` channel logs for load/entry/return status.
|
||||||
- `hello.elf` is supported in current synchronous exec mode.
|
- For long-running interactive ELF (such as `shell.elf`), no `RUN RETURNED` log is expected unless the app exits.
|
||||||
- `/shell/shell.elf` is intentionally blocked in synchronous mode (interactive loop requires process/task context switching stage).
|
|
||||||
|
|||||||
@@ -7,6 +7,5 @@ ls /
|
|||||||
ls /shell
|
ls /shell
|
||||||
ls /system
|
ls /system
|
||||||
cat /README.txt
|
cat /README.txt
|
||||||
run /system/elfrunner.elf
|
run /hello.elf
|
||||||
run /system/memc.elf
|
|
||||||
stats
|
stats
|
||||||
|
|||||||
Reference in New Issue
Block a user