Files
rosetta/sys/bootstrap/main.c

155 lines
3.2 KiB
C

#define MSG_IMPLEMENTATION
#define MSG_NO_MALLOC
#include "tar.h"
#include <launch.h>
#include <mango/log.h>
#include <mango/msg.h>
#include <mango/task.h>
#include <mango/types.h>
#include <rosetta/fs.h>
#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(const char *path, int flags, int *out_err)
{
kern_logf("received msg: open(%s, %d)", path, flags);
*out_err = 13;
return KERN_OK;
}
static kern_status_t uppercase(const char *old, struct msg_string *new)
{
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];
}
}
new->str_len = i - 1;
new->str_buf[i] = 0;
return KERN_OK;
}
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;
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,
};
kern_handle_t channel;
channel_create(0, &channel);
launch_ctx_init(&launch);
launch.ctx_resolve_library = resolve_dependency;
enum launch_status status
= launch_ctx_execute(&launch, &params, LAUNCH_F_NONE, &result);
kern_logf("launch result: %d", status);
const struct fs_vtable fs_vtable = {
.open = open,
.uppercase = uppercase,
};
#if 1
while (1) {
msgid_t id;
struct msg_header hdr;
kern_status_t status = msg_recv_generic(channel, &id, &hdr);
if (status != KERN_OK) {
kern_logf("message recv error %d", status);
continue;
}
if (hdr.hdr_protocol != PROTOCOL_FS) {
kern_logf(
"unknown message protocol %u",
hdr.hdr_protocol);
continue;
}
status = fs_dispatch(channel, &fs_vtable, id, &hdr);
}
#endif
return 102;
}