#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if CONFIG_ACPI #include #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(); }