Files
cleonos/clks/kernel/kmain.c

363 lines
10 KiB
C
Raw Normal View History

2026-04-11 16:11:16 +08:00
// Kernel main function
2026-04-09 21:47:13 +08:00
#include <clks/boot.h>
2026-04-16 20:04:22 +08:00
#include <clks/audio.h>
2026-04-09 21:47:13 +08:00
#include <clks/cpu.h>
2026-04-12 18:14:59 +08:00
#include <clks/desktop.h>
2026-04-10 20:22:45 +08:00
#include <clks/driver.h>
2026-04-10 16:55:48 +08:00
#include <clks/elfrunner.h>
2026-04-10 21:01:31 +08:00
#include <clks/exec.h>
2026-04-09 21:47:13 +08:00
#include <clks/framebuffer.h>
2026-04-10 17:05:46 +08:00
#include <clks/fs.h>
2026-04-09 22:02:00 +08:00
#include <clks/heap.h>
2026-04-09 22:12:29 +08:00
#include <clks/interrupts.h>
2026-04-11 12:48:51 +08:00
#include <clks/keyboard.h>
2026-04-10 20:40:28 +08:00
#include <clks/kelf.h>
2026-04-09 21:47:13 +08:00
#include <clks/kernel.h>
#include <clks/log.h>
2026-04-12 18:14:59 +08:00
#include <clks/mouse.h>
2026-04-09 22:02:00 +08:00
#include <clks/pmm.h>
2026-04-09 22:35:11 +08:00
#include <clks/scheduler.h>
2026-04-09 21:47:13 +08:00
#include <clks/serial.h>
2026-04-10 20:32:03 +08:00
#include <clks/service.h>
2026-04-11 14:18:59 +08:00
#include <clks/shell.h>
2026-04-10 16:55:48 +08:00
#include <clks/syscall.h>
2026-04-09 21:47:13 +08:00
#include <clks/tty.h>
#include <clks/types.h>
2026-04-10 20:16:20 +08:00
#include <clks/userland.h>
2026-04-09 21:47:13 +08:00
2026-04-18 15:37:24 +08:00
#ifndef CLKS_CFG_AUDIO
#define CLKS_CFG_AUDIO 1
#endif
#ifndef CLKS_CFG_MOUSE
#define CLKS_CFG_MOUSE 1
#endif
#ifndef CLKS_CFG_DESKTOP
#define CLKS_CFG_DESKTOP 1
#endif
#ifndef CLKS_CFG_DRIVER_MANAGER
#define CLKS_CFG_DRIVER_MANAGER 1
#endif
#ifndef CLKS_CFG_KELF
#define CLKS_CFG_KELF 1
#endif
#ifndef CLKS_CFG_HEAP_SELFTEST
#define CLKS_CFG_HEAP_SELFTEST 1
#endif
#ifndef CLKS_CFG_EXTERNAL_PSF
#define CLKS_CFG_EXTERNAL_PSF 1
#endif
#ifndef CLKS_CFG_KEYBOARD
#define CLKS_CFG_KEYBOARD 1
#endif
#ifndef CLKS_CFG_ELFRUNNER_PROBE
#define CLKS_CFG_ELFRUNNER_PROBE 1
#endif
#ifndef CLKS_CFG_KLOGD_TASK
#define CLKS_CFG_KLOGD_TASK 1
#endif
#ifndef CLKS_CFG_KWORKER_TASK
#define CLKS_CFG_KWORKER_TASK 1
#endif
#ifndef CLKS_CFG_USRD_TASK
#define CLKS_CFG_USRD_TASK 1
#endif
2026-04-10 20:32:03 +08:00
static void clks_task_klogd(u64 tick) {
static u64 last_emit = 0ULL;
clks_service_heartbeat(CLKS_SERVICE_LOG, tick);
if (tick - last_emit >= 1000ULL) {
clks_log_hex(CLKS_LOG_DEBUG, "TASK", "KLOGD_TICK", tick);
last_emit = tick;
}
}
static void clks_task_kworker(u64 tick) {
static u32 phase = 0U;
clks_service_heartbeat(CLKS_SERVICE_SCHED, tick);
switch (phase) {
case 0U:
clks_service_heartbeat(CLKS_SERVICE_MEM, tick);
break;
case 1U:
clks_service_heartbeat(CLKS_SERVICE_FS, tick);
break;
case 2U:
clks_service_heartbeat(CLKS_SERVICE_DRIVER, tick);
break;
default:
clks_service_heartbeat(CLKS_SERVICE_LOG, tick);
break;
}
phase = (phase + 1U) & 3U;
}
2026-04-10 20:40:28 +08:00
static void clks_task_kelfd(u64 tick) {
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_KELF
2026-04-10 20:40:28 +08:00
clks_service_heartbeat(CLKS_SERVICE_KELF, tick);
clks_kelf_tick(tick);
2026-04-18 15:37:24 +08:00
#else
(void)tick;
#endif
2026-04-10 20:40:28 +08:00
}
2026-04-10 21:10:16 +08:00
static void clks_task_usrd(u64 tick) {
clks_service_heartbeat(CLKS_SERVICE_USER, tick);
2026-04-14 18:13:35 +08:00
clks_exec_tick(tick);
2026-04-10 21:10:16 +08:00
clks_userland_tick(tick);
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_DESKTOP
2026-04-12 18:14:59 +08:00
clks_desktop_tick(tick);
2026-04-18 15:37:24 +08:00
#endif
2026-04-11 18:32:52 +08:00
clks_tty_tick(tick);
2026-04-11 14:18:59 +08:00
clks_shell_tick(tick);
2026-04-10 21:10:16 +08:00
}
2026-04-09 21:47:13 +08:00
void clks_kernel_main(void) {
const struct limine_framebuffer *boot_fb;
2026-04-09 22:02:00 +08:00
const struct limine_memmap_response *boot_memmap;
struct clks_pmm_stats pmm_stats;
struct clks_heap_stats heap_stats;
2026-04-09 22:35:11 +08:00
struct clks_scheduler_stats sched_stats;
2026-04-10 17:05:46 +08:00
struct clks_fs_node_info fs_system_dir = {0};
2026-04-10 16:55:48 +08:00
u64 syscall_ticks;
2026-04-10 17:05:46 +08:00
u64 fs_root_children;
2026-04-09 21:47:13 +08:00
clks_serial_init();
if (clks_boot_base_revision_supported() == CLKS_FALSE) {
clks_serial_write("[ERROR][BOOT] LIMINE BASE REVISION NOT SUPPORTED\n");
clks_cpu_halt_forever();
}
boot_fb = clks_boot_get_framebuffer();
if (boot_fb != CLKS_NULL) {
clks_fb_init(boot_fb);
clks_tty_init();
}
2026-04-16 21:50:56 +08:00
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS START");
2026-04-09 21:47:13 +08:00
if (boot_fb == CLKS_NULL) {
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
} else {
clks_log_hex(CLKS_LOG_INFO, "VIDEO", "WIDTH", boot_fb->width);
clks_log_hex(CLKS_LOG_INFO, "VIDEO", "HEIGHT", boot_fb->height);
clks_log_hex(CLKS_LOG_INFO, "VIDEO", "PITCH", boot_fb->pitch);
clks_log_hex(CLKS_LOG_INFO, "VIDEO", "BPP", boot_fb->bpp);
}
#if defined(CLKS_ARCH_X86_64)
clks_log(CLKS_LOG_INFO, "ARCH", "X86_64 ONLINE");
#elif defined(CLKS_ARCH_AARCH64)
clks_log(CLKS_LOG_INFO, "ARCH", "AARCH64 ONLINE");
#endif
2026-04-09 22:02:00 +08:00
boot_memmap = clks_boot_get_memmap();
if (boot_memmap == CLKS_NULL) {
clks_log(CLKS_LOG_ERROR, "MEM", "NO LIMINE MEMMAP RESPONSE");
clks_cpu_halt_forever();
}
clks_pmm_init(boot_memmap);
pmm_stats = clks_pmm_get_stats();
clks_log_hex(CLKS_LOG_INFO, "PMM", "MANAGED_PAGES", pmm_stats.managed_pages);
clks_log_hex(CLKS_LOG_INFO, "PMM", "FREE_PAGES", pmm_stats.free_pages);
clks_log_hex(CLKS_LOG_INFO, "PMM", "USED_PAGES", pmm_stats.used_pages);
clks_log_hex(CLKS_LOG_INFO, "PMM", "DROPPED_PAGES", pmm_stats.dropped_pages);
clks_heap_init();
heap_stats = clks_heap_get_stats();
clks_log_hex(CLKS_LOG_INFO, "HEAP", "TOTAL_BYTES", heap_stats.total_bytes);
clks_log_hex(CLKS_LOG_INFO, "HEAP", "FREE_BYTES", heap_stats.free_bytes);
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_HEAP_SELFTEST
void *heap_probe = clks_kmalloc(128);
2026-04-09 22:02:00 +08:00
if (heap_probe == CLKS_NULL) {
clks_log(CLKS_LOG_ERROR, "HEAP", "KMALLOC SELFTEST FAILED");
} else {
clks_log(CLKS_LOG_INFO, "HEAP", "KMALLOC SELFTEST OK");
clks_kfree(heap_probe);
}
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "HEAP SELFTEST DISABLED BY MENUCONFIG");
#endif
2026-04-09 22:02:00 +08:00
2026-04-10 17:05:46 +08:00
clks_fs_init();
if (clks_fs_is_ready() == CLKS_FALSE) {
clks_log(CLKS_LOG_ERROR, "FS", "RAMDISK FS INIT FAILED");
clks_cpu_halt_forever();
}
fs_root_children = clks_fs_count_children("/");
clks_log_hex(CLKS_LOG_INFO, "FS", "ROOT_CHILDREN", fs_root_children);
if (clks_fs_stat("/system", &fs_system_dir) == CLKS_FALSE || fs_system_dir.type != CLKS_FS_NODE_DIR) {
clks_log(CLKS_LOG_ERROR, "FS", "/SYSTEM DIRECTORY CHECK FAILED");
clks_cpu_halt_forever();
}
2026-04-11 16:11:16 +08:00
if (boot_fb != CLKS_NULL) {
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_EXTERNAL_PSF
const void *tty_psf_blob;
u64 tty_psf_size = 0ULL;
2026-04-11 16:11:16 +08:00
tty_psf_blob = clks_fs_read_all("/system/tty.psf", &tty_psf_size);
if (tty_psf_blob != CLKS_NULL && clks_fb_load_psf_font(tty_psf_blob, tty_psf_size) == CLKS_TRUE) {
clks_tty_init();
clks_log(CLKS_LOG_INFO, "TTY", "EXTERNAL PSF LOADED /SYSTEM/TTY.PSF");
clks_log_hex(CLKS_LOG_INFO, "TTY", "PSF_SIZE", tty_psf_size);
} else {
clks_log(CLKS_LOG_WARN, "TTY", "EXTERNAL PSF LOAD FAILED, USING BUILTIN");
}
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "EXTERNAL PSF LOADING DISABLED BY MENUCONFIG");
#endif
2026-04-11 16:11:16 +08:00
}
2026-04-10 21:10:16 +08:00
clks_exec_init();
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_AUDIO
2026-04-16 20:04:22 +08:00
clks_audio_init();
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "AUDIO DISABLED BY MENUCONFIG");
#endif
#if CLKS_CFG_KEYBOARD
2026-04-11 12:48:51 +08:00
clks_keyboard_init();
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "KEYBOARD DISABLED BY MENUCONFIG");
#endif
#if CLKS_CFG_MOUSE
2026-04-12 18:14:59 +08:00
clks_mouse_init();
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "MOUSE DISABLED BY MENUCONFIG");
#endif
#if CLKS_CFG_DESKTOP
2026-04-12 18:14:59 +08:00
clks_desktop_init();
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "DESKTOP DISABLED BY MENUCONFIG");
#endif
2026-04-10 21:10:16 +08:00
2026-04-10 20:16:20 +08:00
if (clks_userland_init() == CLKS_FALSE) {
clks_log(CLKS_LOG_ERROR, "USER", "USERLAND INIT FAILED");
clks_cpu_halt_forever();
}
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_DRIVER_MANAGER
2026-04-10 20:22:45 +08:00
clks_driver_init();
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "DRIVER MANAGER DISABLED BY MENUCONFIG");
#endif
#if CLKS_CFG_KELF
2026-04-10 20:40:28 +08:00
clks_kelf_init();
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "KELF DISABLED BY MENUCONFIG");
#endif
2026-04-10 20:22:45 +08:00
2026-04-09 22:35:11 +08:00
clks_scheduler_init();
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_KLOGD_TASK
2026-04-10 20:32:03 +08:00
if (clks_scheduler_add_kernel_task_ex("klogd", 4U, clks_task_klogd) == CLKS_FALSE) {
2026-04-09 22:35:11 +08:00
clks_log(CLKS_LOG_WARN, "SCHED", "FAILED TO ADD KLOGD TASK");
}
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "SCHED", "KLOGD TASK DISABLED BY MENUCONFIG");
#endif
2026-04-09 22:35:11 +08:00
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_KWORKER_TASK
2026-04-10 20:32:03 +08:00
if (clks_scheduler_add_kernel_task_ex("kworker", 3U, clks_task_kworker) == CLKS_FALSE) {
2026-04-09 22:35:11 +08:00
clks_log(CLKS_LOG_WARN, "SCHED", "FAILED TO ADD KWORKER TASK");
}
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "SCHED", "KWORKER TASK DISABLED BY MENUCONFIG");
#endif
2026-04-09 22:35:11 +08:00
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_KELF
2026-04-10 20:40:28 +08:00
if (clks_scheduler_add_kernel_task_ex("kelfd", 5U, clks_task_kelfd) == CLKS_FALSE) {
clks_log(CLKS_LOG_WARN, "SCHED", "FAILED TO ADD KELFD TASK");
}
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "SCHED", "KELFD TASK DISABLED BY MENUCONFIG");
#endif
2026-04-10 20:40:28 +08:00
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_USRD_TASK
2026-04-11 16:58:43 +08:00
if (clks_scheduler_add_kernel_task_ex("usrd", 4U, clks_task_usrd) == CLKS_FALSE) {
2026-04-10 21:10:16 +08:00
clks_log(CLKS_LOG_WARN, "SCHED", "FAILED TO ADD USRD TASK");
}
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "SCHED", "USRD TASK DISABLED BY MENUCONFIG");
#endif
2026-04-10 21:10:16 +08:00
2026-04-09 22:35:11 +08:00
sched_stats = clks_scheduler_get_stats();
clks_log_hex(CLKS_LOG_INFO, "SCHED", "TASK_COUNT", sched_stats.task_count);
2026-04-10 20:32:03 +08:00
clks_service_init();
2026-04-10 16:55:48 +08:00
clks_elfrunner_init();
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_ELFRUNNER_PROBE
2026-04-10 16:55:48 +08:00
if (clks_elfrunner_probe_kernel_executable() == CLKS_FALSE) {
clks_log(CLKS_LOG_ERROR, "ELF", "KERNEL ELF PROBE FAILED");
}
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "CFG", "ELFRUNNER PROBE DISABLED BY MENUCONFIG");
#endif
2026-04-10 16:55:48 +08:00
clks_syscall_init();
2026-04-09 22:12:29 +08:00
clks_interrupts_init();
clks_log(CLKS_LOG_INFO, "INT", "IDT + PIC INITIALIZED");
2026-04-10 16:55:48 +08:00
syscall_ticks = clks_syscall_invoke_kernel(CLKS_SYSCALL_TIMER_TICKS, 0ULL, 0ULL, 0ULL);
clks_log_hex(CLKS_LOG_INFO, "SYSCALL", "TICKS", syscall_ticks);
2026-04-11 14:18:59 +08:00
clks_shell_init();
2026-04-13 22:37:39 +08:00
2026-04-18 15:37:24 +08:00
#if CLKS_CFG_USRD_TASK
2026-04-13 22:37:39 +08:00
if (clks_userland_shell_auto_exec_enabled() == CLKS_TRUE) {
clks_log(CLKS_LOG_INFO, "SHELL", "DEFAULT ENTER USER SHELL MODE");
} else {
clks_log(CLKS_LOG_INFO, "SHELL", "KERNEL SHELL ACTIVE");
}
2026-04-18 15:37:24 +08:00
#else
clks_log(CLKS_LOG_WARN, "SHELL", "USRD TASK DISABLED; INTERACTIVE SHELL TICK OFF");
#endif
2026-04-10 21:01:31 +08:00
2026-04-11 14:18:59 +08:00
clks_log_hex(CLKS_LOG_INFO, "TTY", "COUNT", (u64)clks_tty_count());
clks_log_hex(CLKS_LOG_INFO, "TTY", "ACTIVE", (u64)clks_tty_active());
2026-04-09 21:47:13 +08:00
clks_log(CLKS_LOG_INFO, "TTY", "VIRTUAL TTY0 READY");
2026-04-11 16:46:10 +08:00
clks_log(CLKS_LOG_INFO, "TTY", "CURSOR ENABLED");
2026-04-09 21:47:13 +08:00
clks_log(CLKS_LOG_DEBUG, "KERNEL", "IDLE LOOP ENTER");
2026-04-12 19:55:42 +08:00
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
}
}