process: Rewrite ELF loading, processes
This commit is contained in:
+28
-35
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user