bootstrap: replace fs stub msg handlers with libfs

This commit is contained in:
2026-03-06 20:18:54 +00:00
parent d0abe3333d
commit 5ad1babd03
3 changed files with 110 additions and 34 deletions

View File

@@ -5,10 +5,12 @@ set_property(SOURCE ${arch_sources} PROPERTY LANGUAGE C)
add_executable(bootstrap ${c_sources} ${arch_sources})
target_link_libraries(bootstrap libmango ulibc liblaunch interface::fs)
target_link_libraries(bootstrap
libmango libc-core libc-malloc libfs-static liblaunch
interface::fs)
target_compile_options(bootstrap PRIVATE
-fPIC -pie -fno-stack-protector -nostdlib -ffreestanding)
-fno-stack-protector -nostdlib -ffreestanding)
target_link_options(bootstrap PRIVATE
-fPIC -static -pie -nostdlib -ffreestanding
-T ${CMAKE_CURRENT_SOURCE_DIR}/arch/${TARGET_ARCH}/layout.ld)
-static -nostdlib -ffreestanding)
#-T ${CMAKE_CURRENT_SOURCE_DIR}/arch/${TARGET_ARCH}/layout.ld)

View File

@@ -15,6 +15,5 @@ SECTIONS {
/DISCARD/ : {
*(.interp)
*(.dynamic)
}
}

View File

@@ -1,12 +1,17 @@
#define MSG_IMPLEMENTATION
#define MSG_NO_MALLOC
#include "tar.h"
#include <fs/allocator.h>
#include <fs/context.h>
#include <heap/heap.h>
#include <launch.h>
#include <mango/log.h>
#include <mango/msg.h>
#include <mango/task.h>
#include <mango/types.h>
#include <rosetta/bootstrap.h>
#include <rosetta/fs.h>
#include <stdint.h>
#include <stdio.h>
@@ -47,29 +52,41 @@ static enum launch_status resolve_dependency(
return LAUNCH_OK;
}
static kern_status_t open(const char *path, int flags, int *out_err)
static kern_status_t open(
const struct msg_endpoint *sender,
const char *path,
int flags,
int *out_err,
void *arg)
{
kern_logf("received msg: open(%s, %d)", path, flags);
kern_logf(
"received msg: [%u.%x] open(%s, %d)",
sender->e_task,
sender->e_port,
path,
flags);
*out_err = 13;
return KERN_OK;
}
static kern_status_t uppercase(const char *old, struct msg_string *new)
static void *_fs_alloc(struct fs_allocator *alloc, size_t count)
{
kern_logf("received msg: uppercase(%s)", old);
size_t i;
for (i = 0; old[i] && i < new->str_max - 1; i++) {
char c = old[i];
if (c >= 'a' && c <= 'z') {
new->str_buf[i] = old[i] - 'a' + 'A';
} else {
new->str_buf[i] = old[i];
}
}
return heap_alloc(alloc->fs_arg, count);
}
new->str_len = i - 1;
new->str_buf[i] = 0;
return KERN_OK;
static void *_fs_calloc(struct fs_allocator *alloc, size_t count, size_t sz)
{
return heap_calloc(alloc->fs_arg, count, sz);
}
static void *_fs_realloc(struct fs_allocator *alloc, void *p, size_t count)
{
return heap_realloc(alloc->fs_arg, p, count);
}
static void _fs_free(struct fs_allocator *alloc, void *p)
{
heap_free(alloc->fs_arg, p);
}
int main(
@@ -106,12 +123,36 @@ int main(
struct launch_ctx launch;
struct launch_result result;
const char *init_argv[] = {
"init",
"arg1",
"arg2",
"arg3",
};
const char *init_env[] = {
"TESTVAR=testvalue",
};
struct rosetta_bootstrap_channel init_channels[] = {
{
.c_type = RSBS_CHANNEL_SYSTEM,
.c_tid = 0,
.c_cid = 0,
},
};
struct launch_parameters params = {
.p_executable = image,
.p_parent_task = task,
.p_task_name = "init",
.p_local_address_space = address_space,
.p_resolver_arg = &bsp,
.p_argc = sizeof init_argv / sizeof init_argv[0],
.p_argv = init_argv,
.p_envc = sizeof init_env / sizeof init_env[0],
.p_envp = init_env,
.p_channel_count
= sizeof init_channels / sizeof init_channels[0],
.p_channels = init_channels,
};
kern_handle_t channel;
@@ -122,33 +163,67 @@ int main(
enum launch_status status
= launch_ctx_execute(&launch, &params, LAUNCH_F_NONE, &result);
kern_logf("launch result: %d", status);
if (status != KERN_OK) {
kern_logf("failed to start init: %d", status);
return -1;
}
const struct fs_vtable fs_vtable = {
.open = open,
.uppercase = uppercase,
heap_t heap = HEAP_INIT;
struct fs_allocator fs_allocator = {
.fs_alloc = _fs_alloc,
.fs_calloc = _fs_calloc,
.fs_realloc = _fs_realloc,
.fs_free = _fs_free,
.fs_arg = &heap,
};
#if 1
struct fs_context *fs = fs_context_create(&fs_allocator, NULL);
if (!fs) {
kern_logf("cannot initialise fs");
return -1;
}
while (1) {
msgid_t id;
struct msg_endpoint sender;
struct msg_header hdr;
kern_status_t status = msg_recv_generic(channel, &id, &hdr);
kern_msg_handle_t handles[KERN_MSG_MAX_HANDLES] = {0};
kern_status_t status = msg_recv_generic(
channel,
&sender,
&hdr,
handles,
KERN_MSG_MAX_HANDLES);
if (status != KERN_OK) {
kern_logf("message recv error %d", status);
msg_reply_generic(
channel,
&sender,
&hdr,
KERN_UNSUPPORTED);
continue;
}
if (hdr.hdr_protocol != PROTOCOL_FS) {
switch (hdr.hdr_protocol) {
case PROTOCOL_FS:
status = fs_context_dispatch_msg(
fs,
channel,
&sender,
&hdr);
break;
default:
kern_logf(
"unknown message protocol %u",
hdr.hdr_protocol);
continue;
msg_reply_generic(
channel,
&sender,
&hdr,
KERN_UNSUPPORTED);
break;
}
}
status = fs_dispatch(channel, &fs_vtable, id, &hdr);
}
#endif
return 102;
return 0;
}