#define MSG_IMPLEMENTATION #define MSG_NO_MALLOC #include "tar.h" #include #include #include #include #include #include #include #include #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, 0, &channel); launch_ctx_init(&launch); launch.ctx_resolve_library = resolve_dependency; enum launch_status status = launch_ctx_execute(&launch, ¶ms, 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; }