Files
cleonos/clks/kernel/userland.c

159 lines
4.6 KiB
C
Raw Normal View History

2026-04-10 20:16:20 +08:00
#include <clks/elf64.h>
2026-04-10 21:10:16 +08:00
#include <clks/exec.h>
2026-04-10 20:16:20 +08:00
#include <clks/fs.h>
#include <clks/log.h>
#include <clks/types.h>
#include <clks/userland.h>
2026-04-10 21:10:16 +08:00
#define CLKS_USERLAND_RETRY_INTERVAL 500ULL
static clks_bool clks_user_shell_ready = CLKS_FALSE;
static clks_bool clks_user_shell_exec_requested_flag = CLKS_FALSE;
2026-04-11 16:46:10 +08:00
static clks_bool clks_user_shell_exec_enabled = CLKS_FALSE;
2026-04-10 21:10:16 +08:00
static u64 clks_user_launch_attempt_count = 0ULL;
static u64 clks_user_launch_success_count = 0ULL;
static u64 clks_user_launch_fail_count = 0ULL;
static u64 clks_user_last_try_tick = 0ULL;
2026-04-13 22:37:39 +08:00
static clks_bool clks_user_first_try_pending = CLKS_FALSE;
2026-04-10 21:10:16 +08:00
2026-04-10 20:16:20 +08:00
static clks_bool clks_userland_probe_elf(const char *path, const char *tag) {
const void *image;
u64 size = 0ULL;
struct clks_elf64_info info;
image = clks_fs_read_all(path, &size);
if (image == CLKS_NULL) {
clks_log(CLKS_LOG_ERROR, "USER", "ELF FILE MISSING");
clks_log(CLKS_LOG_ERROR, "USER", path);
return CLKS_FALSE;
}
if (clks_elf64_inspect(image, size, &info) == CLKS_FALSE) {
clks_log(CLKS_LOG_ERROR, "USER", "ELF INSPECT FAILED");
clks_log(CLKS_LOG_ERROR, "USER", path);
return CLKS_FALSE;
}
clks_log(CLKS_LOG_INFO, "USER", tag);
clks_log_hex(CLKS_LOG_INFO, "USER", "ELF_SIZE", size);
clks_log_hex(CLKS_LOG_INFO, "USER", "ENTRY", info.entry);
return CLKS_TRUE;
}
2026-04-10 21:16:22 +08:00
static void clks_userland_probe_init_script(void) {
const void *data;
u64 size = 0ULL;
data = clks_fs_read_all("/shell/init.cmd", &size);
if (data == CLKS_NULL || size == 0ULL) {
clks_log(CLKS_LOG_WARN, "USER", "INIT SCRIPT NOT FOUND /SHELL/INIT.CMD");
return;
}
clks_log(CLKS_LOG_INFO, "USER", "INIT SCRIPT READY /SHELL/INIT.CMD");
clks_log_hex(CLKS_LOG_INFO, "USER", "INIT_SCRIPT_SIZE", size);
}
2026-04-10 21:10:16 +08:00
static clks_bool clks_userland_request_shell_exec(void) {
u64 status = (u64)-1;
if (clks_user_shell_ready == CLKS_FALSE) {
return CLKS_FALSE;
}
clks_user_launch_attempt_count++;
if (clks_exec_run_path("/shell/shell.elf", &status) == CLKS_TRUE && status == 0ULL) {
clks_user_shell_exec_requested_flag = CLKS_TRUE;
clks_user_launch_success_count++;
clks_log(CLKS_LOG_INFO, "USER", "SHELL EXEC REQUESTED");
clks_log_hex(CLKS_LOG_INFO, "USER", "SHELL_STATUS", status);
return CLKS_TRUE;
}
clks_user_launch_fail_count++;
clks_log(CLKS_LOG_WARN, "USER", "SHELL EXEC REQUEST FAILED");
return CLKS_FALSE;
}
2026-04-10 20:16:20 +08:00
clks_bool clks_userland_init(void) {
clks_log(CLKS_LOG_INFO, "USER", "USERLAND FRAMEWORK ONLINE");
2026-04-10 21:10:16 +08:00
clks_user_shell_ready = CLKS_FALSE;
clks_user_shell_exec_requested_flag = CLKS_FALSE;
2026-04-13 22:37:39 +08:00
clks_user_shell_exec_enabled = CLKS_TRUE;
2026-04-10 21:10:16 +08:00
clks_user_launch_attempt_count = 0ULL;
clks_user_launch_success_count = 0ULL;
clks_user_launch_fail_count = 0ULL;
clks_user_last_try_tick = 0ULL;
2026-04-13 22:37:39 +08:00
clks_user_first_try_pending = CLKS_TRUE;
2026-04-10 21:10:16 +08:00
2026-04-10 20:16:20 +08:00
if (clks_userland_probe_elf("/shell/shell.elf", "SHELL ELF READY") == CLKS_FALSE) {
return CLKS_FALSE;
}
2026-04-10 21:10:16 +08:00
clks_user_shell_ready = CLKS_TRUE;
2026-04-10 21:01:31 +08:00
clks_log(CLKS_LOG_INFO, "USER", "SHELL COMMAND ABI READY");
2026-04-10 21:16:22 +08:00
clks_userland_probe_init_script();
2026-04-10 21:01:31 +08:00
2026-04-10 20:16:20 +08:00
if (clks_userland_probe_elf("/system/elfrunner.elf", "ELFRUNNER ELF READY") == CLKS_FALSE) {
return CLKS_FALSE;
}
if (clks_userland_probe_elf("/system/memc.elf", "MEMC ELF READY") == CLKS_FALSE) {
return CLKS_FALSE;
}
2026-04-13 22:37:39 +08:00
clks_log(CLKS_LOG_INFO, "USER", "USER SHELL AUTO EXEC ENABLED");
2026-04-10 20:16:20 +08:00
return CLKS_TRUE;
2026-04-10 21:10:16 +08:00
}
void clks_userland_tick(u64 tick) {
2026-04-11 16:46:10 +08:00
if (clks_user_shell_exec_enabled == CLKS_FALSE ||
clks_user_shell_ready == CLKS_FALSE ||
clks_user_shell_exec_requested_flag == CLKS_TRUE) {
2026-04-10 21:10:16 +08:00
return;
}
2026-04-13 22:37:39 +08:00
if (clks_user_first_try_pending == CLKS_TRUE) {
clks_user_first_try_pending = CLKS_FALSE;
clks_user_last_try_tick = tick;
(void)clks_userland_request_shell_exec();
return;
}
2026-04-10 21:10:16 +08:00
if (tick - clks_user_last_try_tick < CLKS_USERLAND_RETRY_INTERVAL) {
return;
}
clks_user_last_try_tick = tick;
(void)clks_userland_request_shell_exec();
}
clks_bool clks_userland_shell_ready(void) {
return clks_user_shell_ready;
}
clks_bool clks_userland_shell_exec_requested(void) {
return clks_user_shell_exec_requested_flag;
}
2026-04-13 22:37:39 +08:00
clks_bool clks_userland_shell_auto_exec_enabled(void) {
return clks_user_shell_exec_enabled;
}
2026-04-10 21:10:16 +08:00
u64 clks_userland_launch_attempts(void) {
return clks_user_launch_attempt_count;
}
u64 clks_userland_launch_success(void) {
return clks_user_launch_success_count;
}
u64 clks_userland_launch_failures(void) {
return clks_user_launch_fail_count;
2026-04-13 22:37:39 +08:00
}