mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
[srv.init] Rework init to use module iterator
Init now uses a module iterator that facilitates filtering on module type.
This commit is contained in:
@@ -1,6 +1,13 @@
|
|||||||
|
#include <stdio.h>
|
||||||
#include "j6/syscalls.h"
|
#include "j6/syscalls.h"
|
||||||
|
#include "init_args.h"
|
||||||
|
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
|
|
||||||
|
using kernel::init::module;
|
||||||
|
using kernel::init::module_type;
|
||||||
|
using kernel::init::module_program;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
int main(int, const char **);
|
int main(int, const char **);
|
||||||
}
|
}
|
||||||
@@ -14,7 +21,15 @@ int
|
|||||||
main(int argc, const char **argv)
|
main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
j6_system_log("srv.init starting");
|
j6_system_log("srv.init starting");
|
||||||
modules::load_all(_arg_modules_phys);
|
|
||||||
|
modules mods = modules::load_modules(_arg_modules_phys, handle_system, handle_self);
|
||||||
|
|
||||||
|
char message[100];
|
||||||
|
for (auto &mod : mods.of_type(module_type::program)) {
|
||||||
|
auto &prog = static_cast<const module_program&>(mod);
|
||||||
|
sprintf(message, " program module '%s' at %lx", prog.filename, prog.base_address);
|
||||||
|
j6_system_log(message);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,68 +3,80 @@
|
|||||||
|
|
||||||
#include "j6/errors.h"
|
#include "j6/errors.h"
|
||||||
#include "j6/syscalls.h"
|
#include "j6/syscalls.h"
|
||||||
#include "init_args.h"
|
|
||||||
#include "pointer_manipulation.h"
|
|
||||||
|
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
|
|
||||||
using namespace kernel::init;
|
using module = kernel::init::module;
|
||||||
|
using modules_page = kernel::init::modules_page;
|
||||||
extern j6_handle_t handle_self;
|
|
||||||
extern j6_handle_t handle_system;
|
|
||||||
|
|
||||||
namespace modules {
|
|
||||||
|
|
||||||
static const modules_page *
|
static const modules_page *
|
||||||
load_page(uintptr_t address)
|
get_page(const module *mod)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const modules_page*>(
|
||||||
|
reinterpret_cast<uintptr_t>(mod) & ~0xfffull);
|
||||||
|
}
|
||||||
|
|
||||||
|
const module *
|
||||||
|
module_iterator::operator++()
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
m_mod = offset_ptr<module>(m_mod, m_mod->mod_length);
|
||||||
|
|
||||||
|
if (m_mod->mod_type == type::none) {
|
||||||
|
// We've reached the end of a page, see if there's another
|
||||||
|
const modules_page *page = get_page(m_mod);
|
||||||
|
if (!page->next) {
|
||||||
|
m_mod = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mod = page->modules;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (m_type != type::none && m_type != m_mod->mod_type);
|
||||||
|
|
||||||
|
return m_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
const module *
|
||||||
|
module_iterator::operator++(int)
|
||||||
|
{
|
||||||
|
const module *tmp = m_mod;
|
||||||
|
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_handle_t mods_vma = j6_handle_invalid;
|
||||||
j6_status_t s = j6_system_map_phys(handle_system, &mods_vma, address, 0x1000, 0);
|
j6_status_t s = j6_system_map_phys(system, &mods_vma, address, 0x1000, 0);
|
||||||
if (s != j6_status_ok)
|
if (s != j6_status_ok)
|
||||||
exit(s);
|
exit(s);
|
||||||
|
|
||||||
s = j6_vma_map(mods_vma, handle_self, address);
|
s = j6_vma_map(mods_vma, self, address);
|
||||||
if (s != j6_status_ok)
|
if (s != j6_status_ok)
|
||||||
exit(s);
|
exit(s);
|
||||||
|
|
||||||
return reinterpret_cast<modules_page*>(address);
|
return reinterpret_cast<const modules_page*>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
modules
|
||||||
load_all(uintptr_t address)
|
modules::load_modules(uintptr_t address, j6_handle_t system, j6_handle_t self)
|
||||||
{
|
{
|
||||||
module_framebuffer const *framebuffer = nullptr;
|
const module *first = nullptr;
|
||||||
|
|
||||||
while (address) {
|
while (address) {
|
||||||
const modules_page *page = load_page(address);
|
const modules_page *page = load_page(address, system, self);
|
||||||
|
|
||||||
char message[100];
|
char message[100];
|
||||||
sprintf(message, "srv.init loading %d modules from page at 0x%lx", page->count, address);
|
sprintf(message, "srv.init found %d modules from page at 0x%lx", page->count, address);
|
||||||
j6_system_log(message);
|
j6_system_log(message);
|
||||||
|
|
||||||
module *mod = page->modules;
|
if (!first)
|
||||||
size_t count = page->count;
|
first = page->modules;
|
||||||
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;
|
address = page->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return modules {first};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace modules
|
|
||||||
|
|||||||
@@ -2,10 +2,61 @@
|
|||||||
/// \file modules.h
|
/// \file modules.h
|
||||||
/// Routines for loading initial argument modules
|
/// Routines for loading initial argument modules
|
||||||
|
|
||||||
namespace modules {
|
#include "j6/types.h"
|
||||||
|
#include "init_args.h"
|
||||||
|
#include "pointer_manipulation.h"
|
||||||
|
|
||||||
/// Load all modules
|
|
||||||
/// \arg address The physical address of the first page of modules
|
|
||||||
void load_all(uintptr_t address);
|
|
||||||
|
|
||||||
} // namespace modules
|
class module_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using type = kernel::init::module_type;
|
||||||
|
using module = kernel::init::module;
|
||||||
|
|
||||||
|
module_iterator(const module *m, type t = type::none) :
|
||||||
|
m_mod {m}, m_type {t} {}
|
||||||
|
|
||||||
|
const module * operator++();
|
||||||
|
const module * operator++(int);
|
||||||
|
|
||||||
|
bool operator==(const module* m) const { return m == m_mod; }
|
||||||
|
bool operator!=(const module* m) const { return m != m_mod; }
|
||||||
|
bool operator==(const module_iterator &i) const { return i.m_mod == m_mod; }
|
||||||
|
bool operator!=(const module_iterator &i) const { return i.m_mod != m_mod; }
|
||||||
|
|
||||||
|
const module & operator*() const { return *m_mod; }
|
||||||
|
operator const module & () const { return *m_mod; }
|
||||||
|
const module * operator->() const { return m_mod; }
|
||||||
|
|
||||||
|
// Allow iterators to be used in for(:) statments
|
||||||
|
module_iterator & begin() { return *this; }
|
||||||
|
module_iterator end() const { return nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
module const * m_mod;
|
||||||
|
type m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class modules
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using type = kernel::init::module_type;
|
||||||
|
using iterator = module_iterator;
|
||||||
|
|
||||||
|
static modules load_modules(
|
||||||
|
uintptr_t address,
|
||||||
|
j6_handle_t system,
|
||||||
|
j6_handle_t self);
|
||||||
|
|
||||||
|
iterator of_type(type t) const { return iterator {m_root, t}; }
|
||||||
|
|
||||||
|
iterator begin() const { return iterator {m_root}; }
|
||||||
|
iterator end() const { return nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
using module = kernel::init::module;
|
||||||
|
|
||||||
|
modules(const module* root) : m_root {root} {}
|
||||||
|
|
||||||
|
const module *m_root;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user