process: Rewrite ELF loading, processes

This commit is contained in:
2026-10-25 19:12:24 +01:00
parent 9991c1ddcb
commit 0e13d1c0b4
11 changed files with 697 additions and 117 deletions
+28 -35
View File
@@ -1,3 +1,5 @@
// SPDX-License-Identifier: ISC
#include <zinnia/alloc.h>
#include <zinnia/assert.h>
#include <zinnia/clock.h>
@@ -5,15 +7,17 @@
#include <zinnia/compiler.h>
#include <zinnia/console.h>
#include <zinnia/elf.h>
#include <zinnia/exec.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>
@@ -22,52 +26,41 @@
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("main: Hello from main task!\n");
log("Hello from main task!\n");
// Finish the initgraph.
initgraph_run(nullptr, info);
// After everything is loaded, load all builtin drivers.
module_init();
// TODO: Try to run init.
// Load all initramfs files.
initramfs_load_boot_modules(info);
assert(info->num_files >= 1, "No init executable provided");
const char* init_argv[] = {init_path, nullptr};
const char* init_envp[] = {"HOME=/", "TERM=console", nullptr};
struct vma* init_space;
assert(vma_new(&init_space) == 0, "");
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);
struct boot_file* file_data = &info->files[0];
struct task* init_task = nullptr;
struct vmo* init_file;
status = vmo_new_anon(&init_file);
assert(status == 0, "Failed to allocate a memory object");
vmo_write(init_file, 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,
.argv = init_argv,
.envp = init_envp,
};
vmo_unref(init_file);
assert(status == 0, "Failed to load init process (%i)", status);
sched_add_task(&percpu_get()->sched, init_task);
while (true) {
irq_wait();
}
status = process_spawn_init(init_path, init_argv, init_envp);
assert(status == 0, "Failed to start init \"%s\" (%i)", init_path, status);
}
[[__init]]
@@ -87,7 +80,7 @@ void kernel_main(struct boot_info* info) {
initgraph_run(sched_stage, info);
struct task* main_task;
task_create("main", &kernel_vma, kernel_main_task, (uintptr_t)info, &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();