[init] Go back to boot modules having inline data
In order to pass along arguments like the framebuffer, it's far simpler to have that data stored along with the modules than mapping new pages for every structure. Also now optionally pass a module's data to a driver as init starts it.
This commit is contained in:
@@ -71,10 +71,10 @@ allocator::add_modules()
|
|||||||
allocate_pages(1, alloc_type::init_args, true));
|
allocate_pages(1, alloc_type::init_args, true));
|
||||||
|
|
||||||
if (m_modules)
|
if (m_modules)
|
||||||
m_modules->next = reinterpret_cast<uintptr_t>(mods);
|
m_modules->next = mods;
|
||||||
|
|
||||||
m_modules = mods;
|
m_modules = mods;
|
||||||
m_next_mod = mods->modules;
|
m_next_mod = reinterpret_cast<module*>(mods+1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +109,9 @@ allocator::allocate_pages(size_t count, alloc_type type, bool zero)
|
|||||||
}
|
}
|
||||||
|
|
||||||
module *
|
module *
|
||||||
allocator::allocate_module()
|
allocator::allocate_module(size_t extra)
|
||||||
{
|
{
|
||||||
static constexpr size_t size = sizeof(module);
|
size_t size = sizeof(module) + extra;
|
||||||
|
|
||||||
size_t remaining =
|
size_t remaining =
|
||||||
reinterpret_cast<uintptr_t>(m_modules) + page_size
|
reinterpret_cast<uintptr_t>(m_modules) + page_size
|
||||||
@@ -120,8 +120,8 @@ allocator::allocate_module()
|
|||||||
if (size > remaining)
|
if (size > remaining)
|
||||||
add_modules();
|
add_modules();
|
||||||
|
|
||||||
++m_modules->count;
|
|
||||||
module *m = m_next_mod;
|
module *m = m_next_mod;
|
||||||
|
m->bytes = size;
|
||||||
m_next_mod = util::offset_pointer(m_next_mod, size);
|
m_next_mod = util::offset_pointer(m_next_mod, size);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
|
|
||||||
void * allocate_pages(size_t count, alloc_type type, bool zero = false);
|
void * allocate_pages(size_t count, alloc_type type, bool zero = false);
|
||||||
|
|
||||||
module * allocate_module();
|
module * allocate_module(size_t extra = 0);
|
||||||
|
|
||||||
void memset(void *start, size_t size, uint8_t value);
|
void memset(void *start, size_t size, uint8_t value);
|
||||||
void copy(void *to, const void *from, size_t size);
|
void copy(void *to, const void *from, size_t size);
|
||||||
|
|||||||
@@ -167,15 +167,15 @@ load_module(
|
|||||||
fs::file &disk,
|
fs::file &disk,
|
||||||
const wchar_t *name,
|
const wchar_t *name,
|
||||||
const wchar_t *path,
|
const wchar_t *path,
|
||||||
bootproto::module_type type,
|
bootproto::module_type type)
|
||||||
uint16_t subtype)
|
|
||||||
{
|
{
|
||||||
status_line status(L"Loading module", name);
|
status_line status(L"Loading module", name);
|
||||||
|
|
||||||
bootproto::module *mod = g_alloc.allocate_module();
|
bootproto::module *mod = g_alloc.allocate_module(sizeof(util::buffer));
|
||||||
mod->type = type;
|
mod->type = type;
|
||||||
mod->subtype = subtype;
|
|
||||||
mod->data = load_file(disk, path);
|
util::buffer *data = mod->data<util::buffer>();
|
||||||
|
*data = load_file(disk, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace loader
|
} // namespace loader
|
||||||
|
|||||||
@@ -60,14 +60,12 @@ load_program(
|
|||||||
/// \arg name The human-readable name of the module
|
/// \arg name The human-readable name of the module
|
||||||
/// \arg path The path of the file to load the module from
|
/// \arg path The path of the file to load the module from
|
||||||
/// \arg type The major type to set on the module
|
/// \arg type The major type to set on the module
|
||||||
/// \arg subtype The subtype to set on the module
|
|
||||||
void
|
void
|
||||||
load_module(
|
load_module(
|
||||||
fs::file &disk,
|
fs::file &disk,
|
||||||
const wchar_t *name,
|
const wchar_t *name,
|
||||||
const wchar_t *path,
|
const wchar_t *path,
|
||||||
bootproto::module_type type,
|
bootproto::module_type type);
|
||||||
uint16_t subtype);
|
|
||||||
|
|
||||||
} // namespace loader
|
} // namespace loader
|
||||||
} // namespace boot
|
} // namespace boot
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ load_resources(
|
|||||||
loader::parse_program(L"init server", init, args->init);
|
loader::parse_program(L"init server", init, args->init);
|
||||||
|
|
||||||
loader::load_module(disk, L"initrd", bc.initrd(),
|
loader::load_module(disk, L"initrd", bc.initrd(),
|
||||||
bootproto::module_type::initrd, 0);
|
bootproto::module_type::initrd);
|
||||||
|
|
||||||
return reinterpret_cast<bootproto::entrypoint>(kentry);
|
return reinterpret_cast<bootproto::entrypoint>(kentry);
|
||||||
}
|
}
|
||||||
@@ -194,6 +194,7 @@ efi_main(uefi::handle image, uefi::system_table *st)
|
|||||||
|
|
||||||
change_pointer(args);
|
change_pointer(args);
|
||||||
change_pointer(args->pml4);
|
change_pointer(args->pml4);
|
||||||
|
change_pointer(args->symbol_table.pointer);
|
||||||
change_pointer(args->init.sections.pointer);
|
change_pointer(args->init.sections.pointer);
|
||||||
|
|
||||||
//status.next();
|
//status.next();
|
||||||
|
|||||||
@@ -109,20 +109,15 @@ make_module(screen *s)
|
|||||||
{
|
{
|
||||||
using bootproto::module;
|
using bootproto::module;
|
||||||
using bootproto::module_type;
|
using bootproto::module_type;
|
||||||
using bootproto::device_type;
|
namespace devices = bootproto::devices;
|
||||||
using bootproto::devices::uefi_fb;
|
|
||||||
|
|
||||||
uefi_fb *fb = new uefi_fb;
|
module *mod = g_alloc.allocate_module(sizeof(devices::uefi_fb));
|
||||||
|
mod->type = module_type::device;
|
||||||
|
mod->type_id = devices::type_id_uefi_fb;
|
||||||
|
|
||||||
|
devices::uefi_fb *fb = mod->data<devices::uefi_fb>();
|
||||||
fb->framebuffer = s->framebuffer;
|
fb->framebuffer = s->framebuffer;
|
||||||
fb->mode = s->mode;
|
fb->mode = s->mode;
|
||||||
|
|
||||||
module *mod = g_alloc.allocate_module();
|
|
||||||
mod->type = module_type::device;
|
|
||||||
mod->subtype = static_cast<uint16_t>(device_type::uefi_fb);
|
|
||||||
mod->data = {
|
|
||||||
.pointer = fb,
|
|
||||||
.count = sizeof(uefi_fb),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace video
|
} // namespace video
|
||||||
|
|||||||
@@ -3,10 +3,13 @@
|
|||||||
/// Data structures describing bootloader-passed framebuffer
|
/// Data structures describing bootloader-passed framebuffer
|
||||||
|
|
||||||
#include <util/counted.h>
|
#include <util/counted.h>
|
||||||
|
#include <util/hash.h>
|
||||||
|
|
||||||
namespace bootproto {
|
namespace bootproto {
|
||||||
namespace devices {
|
namespace devices {
|
||||||
|
|
||||||
|
inline constexpr uint64_t type_id_uefi_fb = "uefi.fb"_id;
|
||||||
|
|
||||||
enum class fb_layout : uint8_t { rgb8, bgr8, unknown = 0xff };
|
enum class fb_layout : uint8_t { rgb8, bgr8, unknown = 0xff };
|
||||||
|
|
||||||
struct video_mode
|
struct video_mode
|
||||||
|
|||||||
@@ -11,29 +11,21 @@
|
|||||||
namespace bootproto {
|
namespace bootproto {
|
||||||
|
|
||||||
enum class module_type : uint8_t { none, initrd, device, };
|
enum class module_type : uint8_t { none, initrd, device, };
|
||||||
enum class initrd_format : uint8_t { none, zstd, };
|
|
||||||
enum class device_type : uint16_t { none, uefi_fb, };
|
|
||||||
|
|
||||||
struct module
|
struct module
|
||||||
{
|
{
|
||||||
module_type type;
|
uint16_t bytes; //< Size of this module in bytes, including this header
|
||||||
// 1 byte padding
|
module_type type; //< Type of module
|
||||||
uint16_t subtype;
|
// 5 bytes padding
|
||||||
// 4 bytes padding
|
uint64_t type_id; //< Optional subtype or id
|
||||||
util::buffer data;
|
|
||||||
|
template <typename T> T * data() { return reinterpret_cast<T*>(this+1); }
|
||||||
|
template <typename T> const T * data() const { return reinterpret_cast<const T*>(this+1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct module_page_header
|
struct modules_page
|
||||||
{
|
{
|
||||||
uint8_t count;
|
modules_page *next;
|
||||||
uintptr_t next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct modules_page :
|
|
||||||
public module_page_header
|
|
||||||
{
|
|
||||||
static constexpr unsigned per_page = (0x1000 - sizeof(module_page_header)) / sizeof(module);
|
|
||||||
module modules[per_page];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace bootproto
|
} // namespace bootproto
|
||||||
|
|||||||
@@ -78,10 +78,10 @@ public:
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
const inode * lookup_inode(const char *path) const;
|
const inode * lookup_inode(const char *path) const;
|
||||||
const inode * lookup_inode_in_dir(const inode *in, const char *name) const;
|
const inode * lookup_inode_in_dir(const inode *in, const char *name) const;
|
||||||
|
|
||||||
|
private:
|
||||||
util::const_buffer m_data;
|
util::const_buffer m_data;
|
||||||
inode const *m_inodes;
|
inode const *m_inodes;
|
||||||
inode const *m_root;
|
inode const *m_root;
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ 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)
|
char *err_msg,
|
||||||
|
module *arg)
|
||||||
{
|
{
|
||||||
uintptr_t base_address = reinterpret_cast<uintptr_t>(data.pointer);
|
uintptr_t base_address = reinterpret_cast<uintptr_t>(data.pointer);
|
||||||
|
|
||||||
@@ -119,9 +120,23 @@ load_program(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t arg0 = 0;
|
||||||
|
|
||||||
uint64_t *stack = reinterpret_cast<uint64_t*>(load_addr + stack_size);
|
uint64_t *stack = reinterpret_cast<uint64_t*>(load_addr + stack_size);
|
||||||
memset(stack - 512, 0, 512 * sizeof(uint64_t)); // Zero top page
|
memset(stack - 512, 0, 512 * sizeof(uint64_t)); // Zero top page
|
||||||
|
|
||||||
|
stack -= 2; // add null frame
|
||||||
|
size_t stack_consumed = 2 * sizeof(uint64_t);
|
||||||
|
|
||||||
|
if (arg) {
|
||||||
|
size_t arg_size = arg->bytes - sizeof(module);
|
||||||
|
uint8_t *arg_data = arg->data<uint8_t>();
|
||||||
|
uint8_t *arg_dest = reinterpret_cast<uint8_t*>(stack) - arg_size;
|
||||||
|
memcpy(arg_dest, arg_data, arg_size);
|
||||||
|
stack_consumed += arg_size;
|
||||||
|
arg0 = stack_top - stack_consumed;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
sprintf(err_msg, " ** error loading program '%s': mapping stack vma: %lx", name, res);
|
||||||
@@ -135,7 +150,7 @@ load_program(
|
|||||||
}
|
}
|
||||||
|
|
||||||
j6_handle_t thread = j6_handle_invalid;
|
j6_handle_t thread = j6_handle_invalid;
|
||||||
res = j6_thread_create(&thread, proc, stack_top - 6*sizeof(uint64_t), progelf.entrypoint(), 0, 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);
|
sprintf(err_msg, " ** error loading program '%s': creating thread: %lx", name, res);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -3,16 +3,18 @@
|
|||||||
/// Routines for loading and starting other programs
|
/// Routines for loading and starting other programs
|
||||||
|
|
||||||
#include <j6/types.h>
|
#include <j6/types.h>
|
||||||
|
#include <util/counted.h>
|
||||||
|
|
||||||
namespace bootproto {
|
namespace bootproto {
|
||||||
struct module_program;
|
struct module;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_program(
|
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);
|
char *err_msg,
|
||||||
|
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);
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,35 @@ uintptr_t _arg_modules_phys; // This gets filled in in _start
|
|||||||
|
|
||||||
extern j6_handle_t __handle_self;
|
extern j6_handle_t __handle_self;
|
||||||
|
|
||||||
|
void
|
||||||
|
load_driver(
|
||||||
|
j6romfs::fs &initrd,
|
||||||
|
const j6romfs::inode *dir,
|
||||||
|
const char *name,
|
||||||
|
j6_handle_t sys,
|
||||||
|
j6_handle_t slp,
|
||||||
|
module *arg = nullptr)
|
||||||
|
{
|
||||||
|
const j6romfs::inode *in = initrd.lookup_inode_in_dir(dir, name);
|
||||||
|
|
||||||
|
if (in->type != j6romfs::inode_type::file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char message [128];
|
||||||
|
sprintf(message, "Loading driver: %s", name);
|
||||||
|
j6_log(message);
|
||||||
|
|
||||||
|
uint8_t *data = new uint8_t [in->size];
|
||||||
|
util::buffer program {data, in->size};
|
||||||
|
|
||||||
|
initrd.load_inode_data(in, program);
|
||||||
|
if (!load_program(name, program, sys, slp, message, arg)) {
|
||||||
|
j6_log(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] data;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, const char **argv)
|
main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
@@ -60,19 +89,20 @@ main(int argc, const char **argv)
|
|||||||
if (s != j6_status_ok)
|
if (s != j6_status_ok)
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
modules mods = modules::load_modules(_arg_modules_phys, sys, __handle_self);
|
std::vector<const module*> mods;
|
||||||
|
load_modules(_arg_modules_phys, sys, __handle_self, mods);
|
||||||
|
|
||||||
module const *initrd_module;
|
module const *initrd_module;
|
||||||
std::vector<module const*> devices;
|
std::vector<module const*> devices;
|
||||||
|
|
||||||
for (auto &mod : mods) {
|
for (auto mod : mods) {
|
||||||
switch (mod.type) {
|
switch (mod->type) {
|
||||||
case module_type::initrd:
|
case module_type::initrd:
|
||||||
initrd_module = &mod;
|
initrd_module = mod;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case module_type::device:
|
case module_type::device:
|
||||||
devices.push_back(&mod);
|
devices.push_back(mod);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -84,8 +114,10 @@ main(int argc, const char **argv)
|
|||||||
if (!initrd_module)
|
if (!initrd_module)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
util::const_buffer initrd_buf = *initrd_module->data<util::const_buffer>();
|
||||||
|
|
||||||
j6_handle_t initrd_vma =
|
j6_handle_t initrd_vma =
|
||||||
map_phys(sys, initrd_module->data.pointer, initrd_module->data.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 1;
|
||||||
@@ -93,28 +125,17 @@ main(int argc, const char **argv)
|
|||||||
|
|
||||||
// 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_module->data};
|
j6romfs::fs initrd {initrd_buf};
|
||||||
|
|
||||||
char message[256];
|
char message[256];
|
||||||
|
|
||||||
initrd.for_each("/jsix/drivers",
|
const j6romfs::inode *driver_dir = initrd.lookup_inode("/jsix/drivers");
|
||||||
[=, &message](const j6romfs::inode *in, const char *name) {
|
if (!driver_dir) {
|
||||||
if (in->type != j6romfs::inode_type::file)
|
j6_log("Could not load drivers directory");
|
||||||
return;
|
return 1;
|
||||||
|
|
||||||
sprintf(message, "Loading driver: %s", name);
|
|
||||||
j6_log(message);
|
|
||||||
|
|
||||||
uint8_t *data = new uint8_t [in->size];
|
|
||||||
util::buffer program {data, in->size};
|
|
||||||
|
|
||||||
initrd.load_inode_data(in, program);
|
|
||||||
if (!load_program(name, program, sys_child, slp_mb_child, message)) {
|
|
||||||
j6_log(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] data;
|
load_driver(initrd, driver_dir, "drv.uart.elf", sys_child, slp_mb_child);
|
||||||
});
|
|
||||||
|
|
||||||
initrd.for_each("/jsix/services",
|
initrd.for_each("/jsix/services",
|
||||||
[=, &message](const j6romfs::inode *in, const char *name) {
|
[=, &message](const j6romfs::inode *in, const char *name) {
|
||||||
@@ -138,3 +159,4 @@ main(int argc, const char **argv)
|
|||||||
service_locator_start(slp_mb);
|
service_locator_start(slp_mb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,78 +1,40 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <arch/memory.h>
|
||||||
#include <j6/errors.h>
|
#include <j6/errors.h>
|
||||||
#include <j6/syscalls.h>
|
#include <j6/syscalls.h>
|
||||||
|
|
||||||
|
#include "loader.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
|
|
||||||
using module = bootproto::module;
|
void
|
||||||
using modules_page = bootproto::modules_page;
|
load_modules(
|
||||||
|
uintptr_t address,
|
||||||
static const modules_page *
|
j6_handle_t system,
|
||||||
get_page(const module *mod)
|
j6_handle_t self,
|
||||||
|
std::vector<const bootproto::module *> &modules)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const modules_page*>(
|
using bootproto::module;
|
||||||
reinterpret_cast<uintptr_t>(mod) & ~0xfffull);
|
using bootproto::modules_page;
|
||||||
|
|
||||||
|
modules_page const *p = reinterpret_cast<const modules_page*>(address);
|
||||||
|
while (p) {
|
||||||
|
j6_handle_t mod_vma = map_phys(system, p, arch::frame_size);
|
||||||
|
if (mod_vma == j6_handle_invalid) {
|
||||||
|
j6_log(" ** error loading modules: mapping physical vma");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const module *
|
module const *m = reinterpret_cast<module const*>(p+1);
|
||||||
module_iterator::operator++()
|
|
||||||
{
|
while (m->bytes) {
|
||||||
do {
|
modules.push_back(m);
|
||||||
if (++m_idx >= modules_page::per_page) {
|
m = util::offset_pointer(m, m->bytes);
|
||||||
// We've reached the end of a page, see if there's another
|
|
||||||
if (!m_page->next) {
|
|
||||||
m_page = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
m_idx = 0;
|
|
||||||
m_page = reinterpret_cast<modules_page*>(m_page->next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (m_type != type::none && m_type != deref()->type);
|
|
||||||
return deref();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const module *
|
p = p->next;
|
||||||
module_iterator::operator++(int)
|
}
|
||||||
{
|
|
||||||
const module *tmp = deref();
|
|
||||||
operator++();
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
const modules_page *
|
|
||||||
load_page(uintptr_t address, j6_handle_t system, j6_handle_t self)
|
|
||||||
{
|
|
||||||
j6_handle_t mods_vma = j6_handle_invalid;
|
|
||||||
j6_status_t s = j6_system_map_phys(system, &mods_vma, address, 0x1000, 0);
|
|
||||||
if (s != j6_status_ok)
|
|
||||||
exit(s);
|
|
||||||
|
|
||||||
s = j6_vma_map(mods_vma, self, address);
|
|
||||||
if (s != j6_status_ok)
|
|
||||||
exit(s);
|
|
||||||
|
|
||||||
return reinterpret_cast<const modules_page*>(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
modules
|
|
||||||
modules::load_modules(uintptr_t address, j6_handle_t system, j6_handle_t self)
|
|
||||||
{
|
|
||||||
const modules_page *first = nullptr;
|
|
||||||
while (address) {
|
|
||||||
const modules_page *page = load_page(address, system, self);
|
|
||||||
|
|
||||||
char message[100];
|
|
||||||
sprintf(message, "srv.init found %d modules from page at 0x%lx", page->count, address);
|
|
||||||
j6_log(message);
|
|
||||||
|
|
||||||
if (!first)
|
|
||||||
first = page;
|
|
||||||
address = page->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return modules {first};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,73 +2,15 @@
|
|||||||
/// \file modules.h
|
/// \file modules.h
|
||||||
/// Routines for loading initial argument modules
|
/// Routines for loading initial argument modules
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <bootproto/init.h>
|
#include <bootproto/init.h>
|
||||||
#include <j6/types.h>
|
#include <j6/types.h>
|
||||||
#include <util/pointers.h>
|
#include <util/pointers.h>
|
||||||
|
|
||||||
|
void
|
||||||
class module_iterator
|
load_modules(
|
||||||
{
|
|
||||||
public:
|
|
||||||
using type = bootproto::module_type;
|
|
||||||
using module = bootproto::module;
|
|
||||||
|
|
||||||
module_iterator(const bootproto::modules_page *p, unsigned i, type t = type::none) :
|
|
||||||
m_page {p}, m_idx {i}, m_type {t} {
|
|
||||||
if ( t != type::none && p && deref()->type != t ) operator++();
|
|
||||||
}
|
|
||||||
|
|
||||||
const module * operator++();
|
|
||||||
const module * operator++(int);
|
|
||||||
|
|
||||||
bool operator==(const module* m) const { return m == deref(); }
|
|
||||||
bool operator!=(const module* m) const { return m != deref(); }
|
|
||||||
bool operator==(const module_iterator &i) const { return i.deref() == deref(); }
|
|
||||||
bool operator!=(const module_iterator &i) const { return i.deref() != deref(); }
|
|
||||||
|
|
||||||
const module & operator*() const { return *deref(); }
|
|
||||||
operator const module & () const { return *deref(); }
|
|
||||||
const module * operator->() const { return deref(); }
|
|
||||||
|
|
||||||
// Allow iterators to be used in for(:) statments
|
|
||||||
module_iterator & begin() { return *this; }
|
|
||||||
module_iterator end() const { return {nullptr, 0}; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline const module * deref() const {
|
|
||||||
if (m_page) {
|
|
||||||
const module &m = m_page->modules[m_idx];
|
|
||||||
if (m.type != type::none)
|
|
||||||
return &m;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned m_idx;
|
|
||||||
bootproto::modules_page const *m_page;
|
|
||||||
type m_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
class modules
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using type = bootproto::module_type;
|
|
||||||
using iterator = module_iterator;
|
|
||||||
|
|
||||||
static modules load_modules(
|
|
||||||
uintptr_t address,
|
uintptr_t address,
|
||||||
j6_handle_t system,
|
j6_handle_t system,
|
||||||
j6_handle_t self);
|
j6_handle_t self,
|
||||||
|
std::vector<const bootproto::module *> &modules);
|
||||||
iterator of_type(type t) const { return iterator {m_root, 0, t}; }
|
|
||||||
|
|
||||||
iterator begin() const { return iterator {m_root, 0}; }
|
|
||||||
iterator end() const { return {nullptr, 0}; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
using module = bootproto::module;
|
|
||||||
|
|
||||||
modules(const bootproto::modules_page* root) : m_root {root} {}
|
|
||||||
|
|
||||||
const bootproto::modules_page *m_root;
|
|
||||||
};
|
|
||||||
|
|||||||
Reference in New Issue
Block a user