103 lines
2.6 KiB
C
103 lines
2.6 KiB
C
#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/irq.h>
|
|
#include <zinnia/module.h>
|
|
#include <zinnia/percpu.h>
|
|
#include <zinnia/print.h>
|
|
#include <zinnia/sched.h>
|
|
#include <zinnia/utils.h>
|
|
#include <zinnia/vma.h>
|
|
#include <zinnia/vmo.h>
|
|
#include <config.h>
|
|
#include <stdint.h>
|
|
|
|
#if CONFIG_ACPI
|
|
#include <zinnia/acpi.h>
|
|
#endif
|
|
|
|
static const char zinnia_banner[] = "Zinnia " ZINNIA_VERSION " " CONFIG_KERNEL_FLAVOR " (" ZINNIA_ARCH
|
|
", " ZINNIA_COMPILER_ID ", " ZINNIA_LINKER_ID ")";
|
|
|
|
static void kernel_main_task(uintptr_t arg0) {
|
|
struct boot_info* info = (struct boot_info*)arg0;
|
|
|
|
log("main: Hello from main task!\n");
|
|
|
|
// Initialize built-in modules.
|
|
module_init();
|
|
|
|
assert(info->num_files >= 1, "No init executable provided");
|
|
|
|
struct vma* init_space;
|
|
assert(vma_new(&init_space) == EOK, "");
|
|
|
|
struct boot_file* file_data = &info->files[0];
|
|
struct paged_vmo* init_file;
|
|
assert(vmo_new_phys(&init_file) == EOK, "");
|
|
vmo_write(&init_file->object, 0, HHDM_PTR(file_data->data), file_data->length, nullptr);
|
|
|
|
// Load init.
|
|
const char* init_argv[] = {"init", nullptr};
|
|
const char* init_envp[] = {nullptr};
|
|
|
|
struct exec_info exec = {
|
|
.space = init_space,
|
|
.file_obj = &init_file->object,
|
|
.argv = init_argv,
|
|
.envp = init_envp,
|
|
};
|
|
|
|
struct task* init_task = nullptr;
|
|
errno_t status = elf_load(&exec, &init_task);
|
|
vmo_unref(&init_file->object);
|
|
|
|
assert(status == 0, "Failed to load init process (%i)\n", status);
|
|
sched_add_task(&percpu_get()->sched, init_task);
|
|
|
|
while (true) {
|
|
irq_wait();
|
|
}
|
|
}
|
|
|
|
[[__init]]
|
|
void kernel_early_init() {
|
|
percpu_bsp_init();
|
|
percpu_get()->online = true;
|
|
irq_lock();
|
|
}
|
|
|
|
[[noreturn]]
|
|
void kernel_main(struct boot_info* info) {
|
|
// TODO: Initialize in-memory log ring.
|
|
kprintf("%s\n", zinnia_banner); // Say hello!
|
|
kprintf("Command line: %s\n", info->cmdline);
|
|
|
|
cmdline_parse(info->cmdline);
|
|
console_init();
|
|
kprintf("\ec");
|
|
|
|
mem_init(info->mem_map, info->num_mem_maps, info->virt_base, info->phys_base, info->hhdm_base);
|
|
|
|
#if CONFIG_ACPI
|
|
acpi_init(info);
|
|
#endif
|
|
|
|
percpu_init();
|
|
sched_init(&percpu_get()->sched);
|
|
|
|
struct task* main_task;
|
|
task_create("main", &kernel_vma, kernel_main_task, (uintptr_t)info, &main_task);
|
|
sched_add_task(&percpu_get()->sched, main_task);
|
|
|
|
irq_unlock();
|
|
sched_yield(&percpu_get()->sched);
|
|
|
|
unreachable();
|
|
}
|