// SPDX-License-Identifier: ISC #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const char zinnia_banner[] = "Zinnia " ZINNIA_VERSION " " CONFIG_KERNEL_FLAVOR " (" ZINNIA_ARCH ", " ZINNIA_COMPILER_ID ", " ZINNIA_LINKER_ID ")"; // Path to the init executable. static const char* init_path = "/init"; static void init_option(const char* value) { init_path = value; } CMDLINE_OPTION("init", "Path to the init executable", init_option); static void kernel_main_task(uintptr_t arg0) { errno_t status = 0; struct boot_info* info = (struct boot_info*)arg0; log("Hello from main task!\n"); // Finish the initgraph. initgraph_run(nullptr, info); // After everything is loaded, load all builtin drivers. module_init(); // Load all initramfs files. initramfs_load_boot_modules(info); const char* init_argv[] = {init_path, nullptr}; const char* init_envp[] = {"HOME=/", "TERM=console", nullptr}; log("Starting init \"%s\"\n", init_path); log("With arguments:\n"); for (const char** arg = init_argv; *arg; arg++) log(" %s\n", *arg); log("With environment:\n"); for (const char** env = init_envp; *env; env++) log(" %s\n", *env); status = process_spawn_init(init_path, init_argv, init_envp); assert(status == 0, "Failed to start init \"%s\" (%i)", init_path, status); } [[__init]] void kernel_early_init() { percpu_bsp_init(); percpu_get()->online = true; irq_lock(); } [[noreturn]] void kernel_main(struct boot_info* info) { cmdline_parse(info->cmdline); log("%s\n", zinnia_banner); // Say hello! log("Command line: %s\n", info->cmdline); initgraph_run(sched_stage, info); struct task* main_task; task_create("main", process_kernel(), kernel_main_task, (uintptr_t)info, &main_task); sched_add_task(&percpu_get()->sched, main_task); irq_unlock(); sched_yield(&percpu_get()->sched); unreachable(); }