[boot] Build, load, and pass initrd from boot to init
The initrd image is now created by the build system, loaded by the bootloader, and passed to srv.init, which loads it (but doesn't do anything with it yet, so this is actually a functional regression). This simplifies a lot of the modules code between boot and init as well: Gone are the many subclasses of module and all the data being inline with the module structs, except for any loaded files. Now the only modules loaded and passed will be the initrd, and any devices only the bootloader has knowledge of, like the UEFI framebuffer.
This commit is contained in:
@@ -9,8 +9,9 @@
|
||||
#include <j6/syscalls.h>
|
||||
#include <util/enum_bitfields.h>
|
||||
|
||||
using bootproto::module_flags;
|
||||
using bootproto::module_program;
|
||||
#include "loader.h"
|
||||
|
||||
using bootproto::module;
|
||||
|
||||
extern j6_handle_t __handle_self;
|
||||
|
||||
@@ -18,54 +19,62 @@ constexpr uintptr_t load_addr = 0xf8000000;
|
||||
constexpr size_t stack_size = 0x10000;
|
||||
constexpr uintptr_t stack_top = 0x80000000000;
|
||||
|
||||
j6_handle_t
|
||||
map_phys(j6_handle_t sys, uintptr_t phys, size_t len, uintptr_t addr)
|
||||
{
|
||||
j6_handle_t vma = j6_handle_invalid;
|
||||
j6_status_t res = j6_system_map_phys(sys, &vma, phys, len, 0);
|
||||
if (res != j6_status_ok)
|
||||
return j6_handle_invalid;
|
||||
|
||||
if (!addr)
|
||||
addr = phys;
|
||||
|
||||
res = j6_vma_map(vma, __handle_self, addr);
|
||||
if (res != j6_status_ok)
|
||||
return j6_handle_invalid;
|
||||
|
||||
return vma;
|
||||
}
|
||||
|
||||
bool
|
||||
load_program(
|
||||
const module_program &prog,
|
||||
const char *name,
|
||||
uintptr_t base_address,
|
||||
size_t size,
|
||||
j6_handle_t sys, j6_handle_t slp,
|
||||
char *err_msg)
|
||||
{
|
||||
if (prog.mod_flags && module_flags::no_load) {
|
||||
sprintf(err_msg, " skipping pre-loaded program module '%s' at %lx", prog.filename, prog.base_address);
|
||||
return true;
|
||||
}
|
||||
|
||||
j6_handle_t elf_vma = j6_handle_invalid;
|
||||
j6_status_t res = j6_system_map_phys(sys, &elf_vma, prog.base_address, prog.size, 0);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': creating physical vma: %lx", prog.filename, res);
|
||||
j6_handle_t elf_vma = map_phys(sys, base_address, size);
|
||||
if (elf_vma == j6_handle_invalid) {
|
||||
sprintf(err_msg, " ** error loading program '%s': creating physical vma", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_vma_map(elf_vma, __handle_self, prog.base_address);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': mapping vma: %lx", prog.filename, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
const void *addr = reinterpret_cast<const void *>(prog.base_address);
|
||||
elf::file progelf {addr, prog.size};
|
||||
const void *addr = reinterpret_cast<const void *>(base_address);
|
||||
elf::file progelf {addr, size};
|
||||
|
||||
if (!progelf.valid()) {
|
||||
sprintf(err_msg, " ** error loading program '%s': ELF is invalid", prog.filename);
|
||||
sprintf(err_msg, " ** error loading program '%s': ELF is invalid", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
j6_handle_t proc = j6_handle_invalid;
|
||||
res = j6_process_create(&proc);
|
||||
j6_status_t res = j6_process_create(&proc);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': creating process: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': creating process: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_process_give_handle(proc, sys);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': giving system handle: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': giving system handle: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_process_give_handle(proc, slp);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': giving SLP handle: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': giving SLP handle: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -79,14 +88,14 @@ load_program(
|
||||
if (seg.flags && elf::segment_flags::exec)
|
||||
flags |= j6_vm_flag_exec;
|
||||
|
||||
uintptr_t start = prog.base_address + seg.offset;
|
||||
uintptr_t start = base_address + seg.offset;
|
||||
size_t prologue = start & 0xfff;
|
||||
size_t epilogue = seg.mem_size - (prologue+seg.file_size);
|
||||
|
||||
j6_handle_t sub_vma = j6_handle_invalid;
|
||||
res = j6_vma_create_map(&sub_vma, seg.mem_size+prologue, load_addr, flags);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': creating sub vma: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': creating sub vma: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -98,13 +107,13 @@ load_program(
|
||||
|
||||
res = j6_vma_map(sub_vma, proc, seg.vaddr & ~0xfffull);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': mapping sub vma to child: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': mapping sub vma to child: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_vma_unmap(sub_vma, __handle_self);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': unmapping sub vma: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': unmapping sub vma: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -112,7 +121,7 @@ load_program(
|
||||
j6_handle_t stack_vma = j6_handle_invalid;
|
||||
res = j6_vma_create_map(&stack_vma, stack_size, load_addr, j6_vm_flag_write);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': creating stack vma: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': creating stack vma: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -121,26 +130,26 @@ load_program(
|
||||
|
||||
res = j6_vma_map(stack_vma, proc, stack_top-stack_size);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': mapping stack vma: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': mapping stack vma: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_vma_unmap(stack_vma, __handle_self);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': unmapping stack vma: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': unmapping stack vma: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
j6_handle_t thread = j6_handle_invalid;
|
||||
res = j6_thread_create(&thread, proc, stack_top - 6*sizeof(uint64_t), progelf.entrypoint());
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': creating thread: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': creating thread: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_vma_unmap(elf_vma, __handle_self);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': unmapping elf vma: %lx", prog.filename, res);
|
||||
sprintf(err_msg, " ** error loading program '%s': unmapping elf vma: %lx", name, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user