[srv.init] Create init server and read init args

Create a new usermode program, srv.init, and have it read the initial
module_page args sent to it by the bootloader. Doesn't yet do anything
useful but sets up the way for loading the rest of the programs from
srv.init.

Other (mostly) related changes:

- bootloader: The allocator now has a function for allocating init
  modules out of a modules_page slab. Also changed how the allocator is
  initialized and passes the allocation register and modules_page list
  to efi_main().
- bootloader: Expose the simple wstrlen() to the rest of the program
- bootloader: Move check_cpu_supported() to hardware.cpp
- bootloader: Moved program_desc to loader.h and made the loader
  functions take it as an argument instead of paths.
- kernel: Rename the system_map_mmio syscall to system_map_phys, and
  stop having it default those VMAs to having the vm_flags::mmio flag.
  Added a new flag mask, vm_flags::driver_mask, so that drivers can be
  allowed to ask for the MMIO flag.
- kernel: Rename load_simple_process() to load_init_server() and got rid
  of all the stack setup routines in memory_bootstrap.cpp and task.s
- Fixed formatting in config/debug.toml, undefined __linux and other
  linux-specific defines, and got rid of _LIBCPP_HAS_THREAD_API_EXTERNAL
  because that's just not true.
This commit is contained in:
Justin C. Miller
2021-07-31 10:00:08 -07:00
parent 1802c5ea2e
commit 5524ca5b25
28 changed files with 464 additions and 270 deletions

View File

@@ -55,8 +55,9 @@ main(int argc, const char **argv)
j6_handle_t fb_handle = j6_handle_invalid;
uint32_t flags =
j6_vm_flag_write |
j6_vm_flag_write_combine;
j6_status_t s = j6_system_map_mmio(__handle_sys, &fb_handle, fb->addr, fb->size, flags);
j6_vm_flag_write_combine |
j6_vm_flag_mmio;
j6_status_t s = j6_system_map_phys(__handle_sys, &fb_handle, fb->addr, fb->size, flags);
if (s != j6_status_ok) {
return s;
}

View File

@@ -0,0 +1,20 @@
#include "j6/syscalls.h"
#include "modules.h"
extern "C" {
int main(int, const char **);
}
uintptr_t _arg_modules_phys; // This gets filled in in _start
j6_handle_t handle_self = 1; // Self program handle is always 1
j6_handle_t handle_system = 2; // boot protocol is that init gets the system as handle 2
int
main(int argc, const char **argv)
{
j6_system_log("srv.init starting");
modules::load_all(_arg_modules_phys);
return 0;
}

View File

@@ -0,0 +1,8 @@
name = "srv.init"
targets = ["user"]
deps = ["libc"]
sources = [
"main.cpp",
"modules.cpp",
"start.s",
]

View File

@@ -0,0 +1,70 @@
#include <stdlib.h>
#include <stdio.h>
#include "j6/errors.h"
#include "j6/syscalls.h"
#include "init_args.h"
#include "pointer_manipulation.h"
#include "modules.h"
using namespace kernel::init;
extern j6_handle_t handle_self;
extern j6_handle_t handle_system;
namespace modules {
static const modules_page *
load_page(uintptr_t address)
{
j6_handle_t mods_vma = j6_handle_invalid;
j6_status_t s = j6_system_map_phys(handle_system, &mods_vma, address, 0x1000, 0);
if (s != j6_status_ok)
exit(s);
s = j6_vma_map(mods_vma, handle_self, address);
if (s != j6_status_ok)
exit(s);
return reinterpret_cast<modules_page*>(address);
}
void
load_all(uintptr_t address)
{
module_framebuffer const *framebuffer = nullptr;
while (address) {
const modules_page *page = load_page(address);
char message[100];
sprintf(message, "srv.init loading %d modules from page at 0x%lx", page->count, address);
j6_system_log(message);
module *mod = page->modules;
size_t count = page->count;
while (count--) {
switch (mod->mod_type) {
case module_type::framebuffer:
framebuffer = reinterpret_cast<const module_framebuffer*>(mod);
break;
case module_type::program:
if (mod->mod_flags == module_flags::no_load)
j6_system_log("Loaded program module");
else
j6_system_log("Non-loaded program module");
break;
default:
j6_system_log("Unknown module");
}
mod = offset_ptr<module>(mod, mod->mod_length);
}
address = page->next;
}
}
} // namespace modules

View File

@@ -0,0 +1,11 @@
#pragma once
/// \file modules.h
/// Routines for loading initial argument modules
namespace modules {
/// Load all modules
/// \arg address The physical address of the first page of modules
void load_all(uintptr_t address);
} // namespace modules

38
src/user/srv.init/start.s Normal file
View File

@@ -0,0 +1,38 @@
extern main
extern exit
extern _init_libj6
extern _arg_modules_phys
section .bss
align 0x100
init_stack_start:
resb 0x8000 ; 16KiB stack space
init_stack_top:
section .text
global _start:function (_start.end - _start)
_start:
; No parent process exists to have created init's stack, so we override
; _start to deal with that in two ways:
; 1. We create a stack in BSS and assign that to be init's first stack
; 2. We take advantage of the fact that rsp is useless here as a way
; for the kernel to tell init where its initial modules page is.
mov [_arg_modules_phys], rsp
mov rsp, init_stack_top
push 0
push 0
mov rbp, rsp
mov rdi, rsp
call _init_libj6
pop rdi
mov rsi, rsp
call main
mov rdi, rax
call exit
.end: