[srv.init] Serve a service locator protocol from init
The init process now serves as a service locator for its children, passing all children a mailbox handle on which it is serving the service locator protocol.
This commit is contained in:
@@ -2,8 +2,10 @@
|
||||
|
||||
j6 = module("j6",
|
||||
kind = "lib",
|
||||
deps = [ "util" ],
|
||||
sources = [
|
||||
"init.cpp",
|
||||
"protocol_ids.cpp",
|
||||
"syscalls.s.cog",
|
||||
"sysconf.cpp.cog",
|
||||
],
|
||||
@@ -12,6 +14,8 @@ j6 = module("j6",
|
||||
"j6/errors.h",
|
||||
"j6/flags.h",
|
||||
"j6/init.h",
|
||||
"j6/protocols.h",
|
||||
"j6/protocols/service_locator.h",
|
||||
"j6/syscalls.h.cog",
|
||||
"j6/sysconf.h.cog",
|
||||
"j6/types.h",
|
||||
|
||||
12
src/libraries/j6/j6/protocols.h
Normal file
12
src/libraries/j6/j6/protocols.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
/// \file j6/protocols.h
|
||||
/// Common definition for j6 user-mode IPC protocols
|
||||
|
||||
enum j6_proto_base_tag
|
||||
{
|
||||
j6_proto_base_status,
|
||||
j6_proto_base_get_proto_id,
|
||||
j6_proto_base_proto_id,
|
||||
|
||||
j6_proto_base_first_proto_id /// The first protocol-specific ID
|
||||
};
|
||||
14
src/libraries/j6/j6/protocols/service_locator.h
Normal file
14
src/libraries/j6/j6/protocols/service_locator.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
/// \file j6/protocols/service_locator.h
|
||||
/// Definitions for the service locator protocol
|
||||
|
||||
#include <j6/protocols.h>
|
||||
|
||||
extern const uint64_t j6_proto_sl_id;
|
||||
|
||||
enum j6_proto_sl_tag
|
||||
{
|
||||
j6_proto_sl_register = j6_proto_base_first_proto_id,
|
||||
j6_proto_sl_find,
|
||||
j6_proto_sl_result,
|
||||
};
|
||||
4
src/libraries/j6/protocol_ids.cpp
Normal file
4
src/libraries/j6/protocol_ids.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <util/hash.h>
|
||||
|
||||
extern "C"
|
||||
const uint64_t j6_proto_sl_id = "jsix.protocol.service_locator"_id;
|
||||
@@ -8,6 +8,7 @@ init = module("srv.init",
|
||||
"loader.cpp",
|
||||
"main.cpp",
|
||||
"modules.cpp",
|
||||
"service_locator.cpp",
|
||||
"start.s",
|
||||
])
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ constexpr size_t stack_size = 0x10000;
|
||||
constexpr uintptr_t stack_top = 0x80000000000;
|
||||
|
||||
bool
|
||||
load_program(const module_program &prog, j6_handle_t sys, char *err_msg)
|
||||
load_program(
|
||||
const module_program &prog,
|
||||
j6_handle_t sys, j6_handle_t slp,
|
||||
char *err_msg)
|
||||
{
|
||||
if (prog.mod_flags && module_flags::no_load) {
|
||||
sprintf(err_msg, " skipping pre-loaded program module '%s' at %lx", prog.filename, prog.base_address);
|
||||
@@ -60,6 +63,12 @@ load_program(const module_program &prog, j6_handle_t sys, char *err_msg)
|
||||
return false;
|
||||
}
|
||||
|
||||
res = j6_process_give_handle(proc, slp, nullptr);
|
||||
if (res != j6_status_ok) {
|
||||
sprintf(err_msg, " ** error loading program '%s': giving SLP handle: %lx", prog.filename, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto &seg : progelf.programs()) {
|
||||
if (seg.type != elf::segment_type::load)
|
||||
continue;
|
||||
|
||||
@@ -8,4 +8,7 @@ namespace bootproto {
|
||||
struct module_program;
|
||||
}
|
||||
|
||||
bool load_program(const bootproto::module_program &prog, j6_handle_t sys, char *err_msg);
|
||||
bool load_program(
|
||||
const bootproto::module_program &prog,
|
||||
j6_handle_t sys, j6_handle_t slp,
|
||||
char *err_msg);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "loader.h"
|
||||
#include "modules.h"
|
||||
#include "service_locator.h"
|
||||
|
||||
using bootproto::module;
|
||||
using bootproto::module_type;
|
||||
@@ -28,6 +29,9 @@ main(int argc, const char **argv)
|
||||
{
|
||||
j6_status_t s;
|
||||
|
||||
j6_handle_t slp_mb = j6_handle_invalid;
|
||||
j6_handle_t slp_mb_child = j6_handle_invalid;
|
||||
|
||||
j6_handle_t sys = j6_handle_invalid;
|
||||
j6_handle_t sys_child = j6_handle_invalid;
|
||||
|
||||
@@ -45,6 +49,13 @@ main(int argc, const char **argv)
|
||||
if (s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
s = j6_mailbox_create(&slp_mb);
|
||||
if (s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
s = j6_handle_clone(slp_mb, &slp_mb_child,
|
||||
j6_cap_mailbox_send |
|
||||
j6_cap_object_clone);
|
||||
if (s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
@@ -57,11 +68,12 @@ main(int argc, const char **argv)
|
||||
sprintf(message, " loading program module '%s' at %lx", prog.filename, prog.base_address);
|
||||
j6_log(message);
|
||||
|
||||
if (!load_program(prog, sys_child, message)) {
|
||||
if (!load_program(prog, sys_child, slp_mb_child, message)) {
|
||||
j6_log(message);
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
service_locator_start(slp_mb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
97
src/user/srv.init/service_locator.cpp
Normal file
97
src/user/srv.init/service_locator.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <j6/errors.h>
|
||||
#include <j6/flags.h>
|
||||
#include <j6/types.h>
|
||||
#include <j6/protocols/service_locator.h>
|
||||
#include <j6/syscalls.h>
|
||||
#include <util/map.h>
|
||||
|
||||
#include "service_locator.h"
|
||||
|
||||
void
|
||||
service_locator_start(j6_handle_t mb)
|
||||
{
|
||||
// TODO: This should be a multimap
|
||||
util::map<uint64_t, j6_handle_t> services;
|
||||
|
||||
uint64_t tag;
|
||||
uint16_t reply_tag;
|
||||
|
||||
uint8_t data[100];
|
||||
size_t data_len = sizeof(data);
|
||||
|
||||
j6_handle_t handles[10];
|
||||
size_t handles_count = sizeof(handles)/sizeof(j6_handle_t);
|
||||
|
||||
j6_status_t s = j6_mailbox_receive(mb, &tag,
|
||||
data, &data_len,
|
||||
handles, &handles_count,
|
||||
&reply_tag, nullptr,
|
||||
j6_mailbox_block);
|
||||
|
||||
uint64_t proto_id;
|
||||
uint64_t *data_words = reinterpret_cast<uint64_t*>(data);
|
||||
|
||||
while (true) {
|
||||
j6_handle_t *found = nullptr;
|
||||
|
||||
switch (tag) {
|
||||
case j6_proto_base_get_proto_id:
|
||||
tag = j6_proto_base_proto_id;
|
||||
*data_words = j6_proto_sl_id;
|
||||
data_len = sizeof(j6_status_t);
|
||||
handles_count = 0;
|
||||
break;
|
||||
|
||||
case j6_proto_sl_register:
|
||||
proto_id = *data_words;
|
||||
if (handles_count != 1) {
|
||||
tag = j6_proto_base_status;
|
||||
*data_words = j6_err_invalid_arg;
|
||||
data_len = sizeof(j6_status_t);
|
||||
handles_count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
services.insert( proto_id, handles[0] );
|
||||
tag = j6_proto_base_status;
|
||||
*data_words = j6_status_ok;
|
||||
data_len = sizeof(j6_status_t);
|
||||
handles_count = 0;
|
||||
break;
|
||||
|
||||
case j6_proto_sl_find:
|
||||
proto_id = *data_words;
|
||||
tag = j6_proto_sl_result;
|
||||
data_len = 0;
|
||||
|
||||
found = services.find(proto_id);
|
||||
if (found) {
|
||||
handles_count = 1;
|
||||
handles[0] = *found;
|
||||
} else {
|
||||
handles_count = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
tag = j6_proto_base_status;
|
||||
*data_words = j6_err_invalid_arg;
|
||||
data_len = sizeof(j6_status_t);
|
||||
handles_count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
size_t data_in = data_len;
|
||||
size_t handles_in = handles_count;
|
||||
data_len = sizeof(data);
|
||||
handles_count = sizeof(handles)/sizeof(j6_handle_t);
|
||||
|
||||
s = j6_mailbox_respond_receive(mb, &tag,
|
||||
data, &data_len, data_in,
|
||||
handles, &handles_count, handles_in,
|
||||
&reply_tag, nullptr,
|
||||
j6_mailbox_block);
|
||||
}
|
||||
}
|
||||
5
src/user/srv.init/service_locator.h
Normal file
5
src/user/srv.init/service_locator.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
/// \file service_locator.h
|
||||
/// Definitions for srv.init's implementation of the service locator protocol
|
||||
|
||||
void service_locator_start(j6_handle_t mb);
|
||||
Reference in New Issue
Block a user