mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
[init] Switch init to driver_main instead of custom _start
init still uses a custom _start to set up the stack, but then jumps to _libc_crt0_start. The modules data passed to it is taken from the j6_init_args instead of having it stashed into a global variable. Also replace several uses of snprintf/j6_log with j6::syslog.
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#include <j6/errors.h>
|
#include <j6/errors.h>
|
||||||
#include <j6/flags.h>
|
#include <j6/flags.h>
|
||||||
#include <j6/syscalls.h>
|
#include <j6/syscalls.h>
|
||||||
|
#include <j6/syslog.hh>
|
||||||
#include <util/enum_bitfields.h>
|
#include <util/enum_bitfields.h>
|
||||||
|
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
@@ -40,7 +41,6 @@ load_program(
|
|||||||
const char *name,
|
const char *name,
|
||||||
util::const_buffer data,
|
util::const_buffer data,
|
||||||
j6_handle_t sys, j6_handle_t slp,
|
j6_handle_t sys, j6_handle_t slp,
|
||||||
char *err_msg,
|
|
||||||
const module *arg)
|
const module *arg)
|
||||||
{
|
{
|
||||||
uintptr_t base_address = reinterpret_cast<uintptr_t>(data.pointer);
|
uintptr_t base_address = reinterpret_cast<uintptr_t>(data.pointer);
|
||||||
@@ -48,26 +48,26 @@ load_program(
|
|||||||
elf::file progelf {data};
|
elf::file progelf {data};
|
||||||
|
|
||||||
if (!progelf.valid()) {
|
if (!progelf.valid()) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': ELF is invalid", name);
|
j6::syslog(" ** error loading program '%s': ELF is invalid", name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
j6_handle_t proc = j6_handle_invalid;
|
j6_handle_t proc = j6_handle_invalid;
|
||||||
j6_status_t res = j6_process_create(&proc);
|
j6_status_t res = j6_process_create(&proc);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': creating process: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': creating process: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = j6_process_give_handle(proc, sys);
|
res = j6_process_give_handle(proc, sys);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': giving system handle: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': giving system handle: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = j6_process_give_handle(proc, slp);
|
res = j6_process_give_handle(proc, slp);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': giving SLP handle: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': giving SLP handle: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ load_program(
|
|||||||
j6_handle_t sub_vma = j6_handle_invalid;
|
j6_handle_t sub_vma = j6_handle_invalid;
|
||||||
res = j6_vma_create_map(&sub_vma, seg.mem_size+prologue, load_addr, flags);
|
res = j6_vma_create_map(&sub_vma, seg.mem_size+prologue, load_addr, flags);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': creating sub vma: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': creating sub vma: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,13 +100,13 @@ load_program(
|
|||||||
|
|
||||||
res = j6_vma_map(sub_vma, proc, seg.vaddr & ~0xfffull);
|
res = j6_vma_map(sub_vma, proc, seg.vaddr & ~0xfffull);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': mapping sub vma to child: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': mapping sub vma to child: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = j6_vma_unmap(sub_vma, 0);
|
res = j6_vma_unmap(sub_vma, 0);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': unmapping sub vma: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': unmapping sub vma: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ load_program(
|
|||||||
j6_handle_t stack_vma = j6_handle_invalid;
|
j6_handle_t stack_vma = j6_handle_invalid;
|
||||||
res = j6_vma_create_map(&stack_vma, stack_size, load_addr, j6_vm_flag_write);
|
res = j6_vma_create_map(&stack_vma, stack_size, load_addr, j6_vm_flag_write);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': creating stack vma: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': creating stack vma: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,20 +136,20 @@ load_program(
|
|||||||
|
|
||||||
res = j6_vma_map(stack_vma, proc, stack_top-stack_size);
|
res = j6_vma_map(stack_vma, proc, stack_top-stack_size);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': mapping stack vma: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': mapping stack vma: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = j6_vma_unmap(stack_vma, 0);
|
res = j6_vma_unmap(stack_vma, 0);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': unmapping stack vma: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': unmapping stack vma: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
j6_handle_t thread = j6_handle_invalid;
|
j6_handle_t thread = j6_handle_invalid;
|
||||||
res = j6_thread_create(&thread, proc, stack_top - stack_consumed, progelf.entrypoint(), arg0, 0);
|
res = j6_thread_create(&thread, proc, stack_top - stack_consumed, progelf.entrypoint(), arg0, 0);
|
||||||
if (res != j6_status_ok) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': creating thread: %lx", name, res);
|
j6::syslog(" ** error loading program '%s': creating thread: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ bool load_program(
|
|||||||
const char *name,
|
const char *name,
|
||||||
util::const_buffer data,
|
util::const_buffer data,
|
||||||
j6_handle_t sys, j6_handle_t slp,
|
j6_handle_t sys, j6_handle_t slp,
|
||||||
char *err_msg,
|
|
||||||
const bootproto::module *arg = nullptr);
|
const bootproto::module *arg = nullptr);
|
||||||
|
|
||||||
j6_handle_t map_phys(j6_handle_t sys, uintptr_t phys, size_t len, uintptr_t addr = 0);
|
j6_handle_t map_phys(j6_handle_t sys, uintptr_t phys, size_t len, uintptr_t addr = 0);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <j6/errors.h>
|
#include <j6/errors.h>
|
||||||
#include <j6/init.h>
|
#include <j6/init.h>
|
||||||
#include <j6/syscalls.h>
|
#include <j6/syscalls.h>
|
||||||
|
#include <j6/syslog.hh>
|
||||||
#include <j6/types.h>
|
#include <j6/types.h>
|
||||||
|
|
||||||
#include <bootproto/init.h>
|
#include <bootproto/init.h>
|
||||||
@@ -19,12 +20,6 @@
|
|||||||
using bootproto::module;
|
using bootproto::module;
|
||||||
using bootproto::module_type;
|
using bootproto::module_type;
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
int main(int, const char **);
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t _arg_modules_phys; // This gets filled in in _start
|
|
||||||
|
|
||||||
void
|
void
|
||||||
load_driver(
|
load_driver(
|
||||||
j6romfs::fs &initrd,
|
j6romfs::fs &initrd,
|
||||||
@@ -39,23 +34,19 @@ load_driver(
|
|||||||
if (in->type != j6romfs::inode_type::file)
|
if (in->type != j6romfs::inode_type::file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char message [128];
|
j6::syslog("Loading driver: %s", name);
|
||||||
sprintf(message, "Loading driver: %s", name);
|
|
||||||
j6_log(message);
|
|
||||||
|
|
||||||
uint8_t *data = new uint8_t [in->size];
|
uint8_t *data = new uint8_t [in->size];
|
||||||
util::buffer program {data, in->size};
|
util::buffer program {data, in->size};
|
||||||
|
|
||||||
initrd.load_inode_data(in, program);
|
initrd.load_inode_data(in, program);
|
||||||
if (!load_program(name, program, sys, slp, message, arg)) {
|
load_program(name, program, sys, slp, arg);
|
||||||
j6_log(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] data;
|
delete [] data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, const char **argv)
|
driver_main(unsigned argc, const char **argv, const char **env, const j6_init_args *initp)
|
||||||
{
|
{
|
||||||
j6_status_t s;
|
j6_status_t s;
|
||||||
|
|
||||||
@@ -89,10 +80,12 @@ main(int argc, const char **argv)
|
|||||||
if (s != j6_status_ok)
|
if (s != j6_status_ok)
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
std::vector<const module*> mods;
|
uintptr_t modules_addr = initp->args[0];
|
||||||
load_modules(_arg_modules_phys, sys, 0, mods);
|
|
||||||
|
|
||||||
module const *initrd_module;
|
std::vector<const module*> mods;
|
||||||
|
load_modules(modules_addr, sys, 0, mods);
|
||||||
|
|
||||||
|
module const *initrd_module = nullptr;
|
||||||
std::vector<module const*> devices;
|
std::vector<module const*> devices;
|
||||||
|
|
||||||
for (auto mod : mods) {
|
for (auto mod : mods) {
|
||||||
@@ -120,14 +113,13 @@ main(int argc, const char **argv)
|
|||||||
map_phys(sys, initrd_buf.pointer, initrd_buf.count);
|
map_phys(sys, initrd_buf.pointer, initrd_buf.count);
|
||||||
if (initrd_vma == j6_handle_invalid) {
|
if (initrd_vma == j6_handle_invalid) {
|
||||||
j6_log(" ** error loading ramdisk: mapping physical vma");
|
j6_log(" ** error loading ramdisk: mapping physical vma");
|
||||||
return 1;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: encapsulate this all in a driver_manager, or maybe
|
// TODO: encapsulate this all in a driver_manager, or maybe
|
||||||
// have driver_source objects..
|
// have driver_source objects..
|
||||||
j6romfs::fs initrd {initrd_buf};
|
j6romfs::fs initrd {initrd_buf};
|
||||||
|
|
||||||
char message[256];
|
|
||||||
|
|
||||||
const j6romfs::inode *driver_dir = initrd.lookup_inode("/jsix/drivers");
|
const j6romfs::inode *driver_dir = initrd.lookup_inode("/jsix/drivers");
|
||||||
if (!driver_dir) {
|
if (!driver_dir) {
|
||||||
@@ -143,26 +135,22 @@ main(int argc, const char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sprintf(message, "Unknown device type id: %lx", m->type_id);
|
j6::syslog("Unknown device type id: %lx", m->type_id);
|
||||||
j6_log(message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initrd.for_each("/jsix/services",
|
initrd.for_each("/jsix/services",
|
||||||
[=, &message](const j6romfs::inode *in, const char *name) {
|
[=](const j6romfs::inode *in, const char *name) {
|
||||||
if (in->type != j6romfs::inode_type::file)
|
if (in->type != j6romfs::inode_type::file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sprintf(message, "Loading service: %s", name);
|
j6::syslog("Loading service: %s", name);
|
||||||
j6_log(message);
|
|
||||||
|
|
||||||
uint8_t *data = new uint8_t [in->size];
|
uint8_t *data = new uint8_t [in->size];
|
||||||
util::buffer program {data, in->size};
|
util::buffer program {data, in->size};
|
||||||
|
|
||||||
initrd.load_inode_data(in, program);
|
initrd.load_inode_data(in, program);
|
||||||
if (!load_program(name, program, sys_child, slp_mb_child, message)) {
|
load_program(name, program, sys_child, slp_mb_child);
|
||||||
j6_log(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] data;
|
delete [] data;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,24 +12,11 @@ init_stack_top:
|
|||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
|
extern _libc_crt0_start
|
||||||
global _start:function (_start.end - _start)
|
global _start:function (_start.end - _start)
|
||||||
_start:
|
_start:
|
||||||
; No parent process exists to have created init's stack, so we create a
|
; No parent process exists to have created init's stack, so we create a
|
||||||
; stack in BSS and assign that to be init's first stack
|
; stack in BSS and assign that to be init's first stack
|
||||||
mov [_arg_modules_phys], rdi
|
|
||||||
mov rsp, init_stack_top
|
mov rsp, init_stack_top
|
||||||
push 0
|
jmp _libc_crt0_start
|
||||||
push 0
|
|
||||||
|
|
||||||
mov rbp, rsp
|
|
||||||
mov rdi, rsp
|
|
||||||
call __init_libj6
|
|
||||||
call __init_libc
|
|
||||||
|
|
||||||
pop rdi
|
|
||||||
mov rsi, rsp
|
|
||||||
call main
|
|
||||||
|
|
||||||
mov rdi, rax
|
|
||||||
call exit
|
|
||||||
.end:
|
.end:
|
||||||
|
|||||||
Reference in New Issue
Block a user