[ld.so] Add a minimal dynamic linker
This commit includes a number of changes to enable loading of PIE executables: - The loader in srv.init checks for a `PT_INTERP` segment in the program its loading, and if it exists, loads the specified interpreter and passes control to it instead of the program itself. - Added ld.so the dynamic linker executable and set it as the interpreter for all user-target programs. - Program initial stack changed again to now contain a number of possible tagged structures, including a new one for ld.so's arguments, and for passing handles tagged with protocol ids. - Added a stub for a new VFS protocol. Unused so far, but srv.init will need to serve VFS requests from ld.so once I transition libraries to shared libs for user-target programs. (Right now all executables are PIE but statically linked, so they only need internal relocations.) - Added 16 and 8 bit variants of `util::bitset`. This ended up not being used, but could be useful.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <j6/init.h>
|
||||
#include <j6/syscalls.h>
|
||||
#include <j6/syslog.hh>
|
||||
#include <j6/thread.hh>
|
||||
#include <j6/types.h>
|
||||
|
||||
#include <bootproto/acpi.h>
|
||||
@@ -14,6 +15,7 @@
|
||||
#include <bootproto/devices/framebuffer.h>
|
||||
|
||||
#include "acpi.h"
|
||||
#include "initfs.h"
|
||||
#include "j6romfs.h"
|
||||
#include "loader.h"
|
||||
#include "modules.h"
|
||||
@@ -22,30 +24,7 @@
|
||||
using bootproto::module;
|
||||
using bootproto::module_type;
|
||||
|
||||
void
|
||||
load_driver(
|
||||
j6romfs::fs &initrd,
|
||||
const j6romfs::inode *dir,
|
||||
const char *name,
|
||||
j6_handle_t sys,
|
||||
j6_handle_t slp,
|
||||
const module *arg = nullptr)
|
||||
{
|
||||
const j6romfs::inode *in = initrd.lookup_inode_in_dir(dir, name);
|
||||
|
||||
if (in->type != j6romfs::inode_type::file)
|
||||
return;
|
||||
|
||||
j6::syslog("Loading driver: %s", name);
|
||||
|
||||
uint8_t *data = new uint8_t [in->size];
|
||||
util::buffer program {data, in->size};
|
||||
|
||||
initrd.load_inode_data(in, program);
|
||||
load_program(name, program, sys, slp, arg);
|
||||
|
||||
delete [] data;
|
||||
}
|
||||
constexpr uintptr_t stack_top = 0xf80000000;
|
||||
|
||||
int
|
||||
driver_main(unsigned argc, const char **argv, const char **env, const j6_init_args *initp)
|
||||
@@ -58,6 +37,9 @@ driver_main(unsigned argc, const char **argv, const char **env, const j6_init_ar
|
||||
j6_handle_t sys = j6_handle_invalid;
|
||||
j6_handle_t sys_child = j6_handle_invalid;
|
||||
|
||||
j6_handle_t vfs_mb = j6_handle_invalid;
|
||||
j6_handle_t vfs_mb_child = j6_handle_invalid;
|
||||
|
||||
j6_log("srv.init starting");
|
||||
|
||||
sys = j6_find_first_handle(j6_object_type_system);
|
||||
@@ -82,6 +64,16 @@ driver_main(unsigned argc, const char **argv, const char **env, const j6_init_ar
|
||||
if (s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
s = j6_mailbox_create(&vfs_mb);
|
||||
if (s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
s = j6_handle_clone(vfs_mb, &vfs_mb_child,
|
||||
j6_cap_mailbox_send |
|
||||
j6_cap_object_clone);
|
||||
if (s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
uintptr_t modules_addr = initp->args[0];
|
||||
|
||||
std::vector<const module*> mods;
|
||||
@@ -130,19 +122,17 @@ driver_main(unsigned argc, const char **argv, const char **env, const j6_init_ar
|
||||
// have driver_source objects..
|
||||
j6romfs::fs initrd {initrd_buf};
|
||||
|
||||
j6::thread vfs_thread {[=, &initrd](){ initfs_start(initrd, vfs_mb); }, stack_top};
|
||||
j6_status_t result = vfs_thread.start();
|
||||
|
||||
load_acpi(sys, acpi_module);
|
||||
|
||||
const j6romfs::inode *driver_dir = initrd.lookup_inode("/jsix/drivers");
|
||||
if (!driver_dir) {
|
||||
j6_log("Could not load drivers directory");
|
||||
return 1;
|
||||
}
|
||||
load_program("/jsix/drivers/drv.uart.elf", initrd, sys_child, slp_mb_child, vfs_mb_child);
|
||||
|
||||
load_driver(initrd, driver_dir, "drv.uart.elf", sys_child, slp_mb_child);
|
||||
for (const module *m : devices) {
|
||||
switch (m->type_id) {
|
||||
case bootproto::devices::type_id_uefi_fb:
|
||||
load_driver(initrd, driver_dir, "drv.uefi_fb.elf", sys_child, slp_mb_child, m);
|
||||
load_program("/jsix/drivers/drv.uefi_fb.elf", initrd, sys_child, slp_mb_child, vfs_mb_child, m);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -155,16 +145,10 @@ driver_main(unsigned argc, const char **argv, const char **env, const j6_init_ar
|
||||
if (in->type != j6romfs::inode_type::file)
|
||||
return;
|
||||
|
||||
j6::syslog("Loading service: %s", name);
|
||||
|
||||
uint8_t *data = new uint8_t [in->size];
|
||||
util::buffer program {data, in->size};
|
||||
|
||||
initrd.load_inode_data(in, program);
|
||||
load_program(name, program, sys_child, slp_mb_child);
|
||||
|
||||
delete [] data;
|
||||
});
|
||||
char path [128];
|
||||
sprintf(path, "/jsix/services/%s", name);
|
||||
load_program(path, initrd, sys_child, slp_mb_child, vfs_mb_child);
|
||||
});
|
||||
|
||||
service_locator_start(slp_mb);
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user