91 lines
2.5 KiB
C
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();
|
|
}
|