Files
rosetta/sys/bootstrap/main.c

226 lines
4.6 KiB
C
Raw Normal View History

#define MSG_IMPLEMENTATION
#define MSG_NO_MALLOC
2026-02-19 19:31:15 +00:00
#include "tar.h"
#include <fs/allocator.h>
#include <fs/context.h>
#include <heap/heap.h>
2026-02-19 19:31:15 +00:00
#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>
2026-02-19 19:31:15 +00:00
#include <stdint.h>
#include <stdio.h>
#define INIT_PATH "/usr/bin/test"
static enum launch_status resolve_dependency(
struct launch_ctx *ctx,
const char *name,
kern_handle_t *out,
void *arg)
{
char s[128];
while (*name == '/') {
name++;
}
snprintf(s, sizeof s, "searching for library %s", name);
kern_log(s);
struct tar *fs = arg;
struct tar_file file = {0};
if (tar_open(fs, name, &file) != 0) {
snprintf(s, sizeof s, "cannot find library %s", name);
kern_log(s);
return LAUNCH_ERR_CANNOT_RESOLVE_DEPENDENCY;
}
kern_handle_t image = KERN_HANDLE_INVALID;
int err = tar_file_create_vm_object(&file, &image);
if (err != 0) {
snprintf(s, sizeof s, "cannot load library %s", name);
kern_log(s);
return -1;
}
*out = image;
return LAUNCH_OK;
}
static kern_status_t open(
xpc_context_t *ctx,
const xpc_endpoint_t *sender,
const char *path,
int flags,
int *out_err,
void *arg)
{
kern_logf(
"received msg: [%u.%x] open(%s, %d)",
sender->e_task,
sender->e_port,
path,
flags);
*out_err = 13;
return KERN_OK;
}
static void *_fs_alloc(struct fs_allocator *alloc, size_t count)
{
return heap_alloc(alloc->fs_arg, count);
}
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);
}
2026-02-19 19:31:15 +00:00
int main(
int argc,
const char **argv,
kern_handle_t task,
kern_handle_t address_space,
uintptr_t bsp_base)
{
struct tar bsp = {0};
if (tar_init(&bsp, bsp_base) != 0) {
kern_log("cannot access bsp");
return -1;
}
struct tar_file init = {0};
if (tar_open(&bsp, INIT_PATH, &init) != 0) {
kern_log("cannot find init program " INIT_PATH);
return -1;
}
kern_trace("loading " INIT_PATH);
kern_handle_t image = KERN_HANDLE_INVALID;
int err = tar_file_create_vm_object(&init, &image);
if (err != 0) {
kern_log("cannot load executable " INIT_PATH);
return -1;
}
kern_trace("loaded executable vm-object " INIT_PATH);
kern_tracef("task=%x, region=%x", task, address_space);
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,
},
};
2026-02-19 19:31:15 +00:00
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,
2026-02-19 19:31:15 +00:00
};
kern_handle_t channel;
2026-02-26 20:51:19 +00:00
channel_create(0, &channel);
2026-02-19 19:31:15 +00:00
launch_ctx_init(&launch);
launch.ctx_resolve_library = resolve_dependency;
enum launch_status status
= launch_ctx_execute(&launch, &params, LAUNCH_F_NONE, &result);
if (status != KERN_OK) {
kern_logf("failed to start init: %d", status);
return -1;
}
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,
};
struct fs_context *fs = fs_context_create(&fs_allocator);
if (!fs) {
kern_logf("cannot initialise fs");
return -1;
}
enum fs_status fs_status = fs_context_mount_filesystem(
fs,
tar_mount,
(void *)bsp_base,
0);
if (fs_status != FS_SUCCESS) {
kern_logf("cannot mount filesustem (%d)", fs_status);
return -1;
}
while (1) {
xpc_msg_t msg;
kern_status_t status = xpc_msg_recv(channel, &msg);
if (status != KERN_OK) {
kern_logf("message recv error %d", status);
continue;
}
switch (msg.msg_header.hdr_interface) {
case INTERFACE_FS:
status = fs_context_dispatch_msg(fs, &msg);
break;
default:
kern_logf(
"unknown message protocol %u",
msg.msg_header.hdr_interface);
xpc_msg_reply_error(&msg, KERN_UNSUPPORTED);
break;
}
if (status != KERN_OK) {
kern_logf("message reply error %d", status);
continue;
}
}
2026-02-19 19:31:15 +00:00
return 0;
2026-02-19 19:31:15 +00:00
}