Files
zinnia/boot/main.c
T

91 lines
2.5 KiB
C

// SPDX-License-Identifier: ISC
#include <zinnia/alloc.h>
#include <zinnia/assert.h>
#include <zinnia/clock.h>
#include <zinnia/cmdline.h>
#include <zinnia/compiler.h>
#include <zinnia/console.h>
#include <zinnia/elf.h>
#include <zinnia/init.h>
#include <zinnia/initgraph.h>
#include <zinnia/initramfs.h>
#include <zinnia/irq.h>
#include <zinnia/module.h>
#include <zinnia/percpu.h>
#include <zinnia/print.h>
#include <zinnia/process.h>
#include <zinnia/sched.h>
#include <zinnia/utils.h>
#include <zinnia/vfs.h>
#include <zinnia/vma.h>
#include <zinnia/vmo.h>
#include <config.h>
#include <stdint.h>
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();
}