From fbbb2ae5b2f2f9fd18bdfabc9a01a3c748bbddc0 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Thu, 28 Apr 2022 14:02:31 +0200 Subject: [PATCH] work on bootinfo transfer --- include/aos/aos_rpc.h | 5 +++ include/barrelfish_kpi/init.h | 22 +++++++++++ lib/aos/aos_rpc.c | 21 ++++++++++ lib/spawn/rpc_server.c | 72 +++++++++++++++++++++++++++++++++++ usr/init/main.c | 58 +++++++++++++++++++++++++++- 5 files changed, 176 insertions(+), 2 deletions(-) diff --git a/include/aos/aos_rpc.h b/include/aos/aos_rpc.h index cdd4d45..cb9d239 100644 --- a/include/aos/aos_rpc.h +++ b/include/aos/aos_rpc.h @@ -32,6 +32,7 @@ enum rpc_mtype { RPC_MTYPE_PROCESS_SPAWN, RPC_MTYPE_PROCESS_GET_NAME, RPC_MTYPE_PROCESS_GET_ALL_PIDS, + RPC_MTYPE_GET_BOOTINFO, RPC_MTYPE_COUNT // How many message types exist }; @@ -129,6 +130,10 @@ errval_t aos_rpc_process_get_name(struct aos_rpc *chan, domainid_t pid, errval_t aos_rpc_process_get_all_pids(struct aos_rpc *chan, domainid_t **pids, size_t *pid_count); +/** + * \brief Get bootinfo from rsp core + */ +errval_t aos_rpc_get_bootinfo(struct aos_rpc * rpc, struct bootinfo_serialized ** ret); /** * \brief Returns the RPC channel to init. diff --git a/include/barrelfish_kpi/init.h b/include/barrelfish_kpi/init.h index 4465180..e78bc41 100644 --- a/include/barrelfish_kpi/init.h +++ b/include/barrelfish_kpi/init.h @@ -159,6 +159,19 @@ struct mem_region { int mrmod_slot;///< First slot containing caps (module only) }; +struct mem_region_serialized { + genpaddr_t mr_base;///< Address of the start of the region + enum region_type mr_type;///< Type of region + gensize_t mr_bytes;///< Size in bytes + bool mr_consumed;///< Flag for user code to mark region consumed + size_t mrmod_size;///< Size in bytes (module type only) + ptrdiff_t mrmod_data;///< Offset of module string (module type only) + int mrmod_slot;///< First slot containing caps (module only) + + genpaddr_t mrmod_frame_base; ///< base of the frame that contains the elf file + size_t mrmod_frame_bytes; ///< size of the frame that contains the elf file +}; + /** * This structure holds essential information for the init process to * allocate and manage its address space. @@ -176,4 +189,13 @@ struct bootinfo { struct mem_region regions[]; }; +struct bootinfo_serialized { + uint64_t host_msg; + uint8_t host_msg_bits; + + size_t regions_length; + size_t mem_spawn_core; + struct mem_region_serialized regions[]; +}; + #endif diff --git a/lib/aos/aos_rpc.c b/lib/aos/aos_rpc.c index 90021b4..46e3331 100644 --- a/lib/aos/aos_rpc.c +++ b/lib/aos/aos_rpc.c @@ -351,6 +351,27 @@ aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids, return err; } +errval_t aos_rpc_get_bootinfo(struct aos_rpc * rpc, struct bootinfo_serialized ** ret) +{ + size_t ret_len; + errval_t err; + thread_mutex_lock(&rpc->shared_mem_lock); + err = do_aos_rpc( + rpc, RPC_MTYPE_GET_BOOTINFO, + NULL_CAP, 0, 0, 0, + NULL, &ret_len, NULL, NULL + ); + if (err_is_fail(err)) { + thread_mutex_unlock(&rpc->shared_mem_lock); + return err; + } + + memcpy(*ret, rpc->shared_mem, ret_len); + + thread_mutex_unlock(&rpc->shared_mem_lock); + return SYS_ERR_OK; +} + // We are allowed to change the signature for this one errval_t aos_rpc_init(struct aos_rpc *rpc, struct lmp_chan *chan, void *shared_mem) { diff --git a/lib/spawn/rpc_server.c b/lib/spawn/rpc_server.c index 6d8cbb1..904cd9a 100644 --- a/lib/spawn/rpc_server.c +++ b/lib/spawn/rpc_server.c @@ -8,6 +8,7 @@ extern coreid_t my_core_id; rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT]; +extern struct bootinfo *bi; extern struct aos_urpc urpc_to_app; extern struct waitset urpc_to_app_ws; @@ -339,6 +340,76 @@ static errval_t handle_rpc_process_get_all_pids( return SYS_ERR_OK; } +static errval_t serialize_bootinfo(struct bootinfo * bootinfo, struct bootinfo_serialized * ret) { + errval_t err; + assert(bootinfo != NULL); + // struct capref serialized_bootinfo_frame; + + //allocate space for serialized + // size_t bootinfo_size = sizeof(struct bootinfo_serialized) + bootinfo->regions_length * sizeof(struct mem_region_serialized); + // err = frame_alloc(&serialized_bootinfo_frame, bootinfo_size, NULL); + // if (err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_ALLOC); + + struct bootinfo_serialized * serialized_bootinfo = ret; + // struct bootinfo_serialized * serialized_bootinfo; + // err = paging_map_frame(get_current_paging_state(), (void **) &serialized_bootinfo, bootinfo_size, serialized_bootinfo_frame); + // if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_MAP); + + serialized_bootinfo->host_msg = bootinfo->host_msg; + serialized_bootinfo->host_msg_bits = bootinfo->host_msg_bits; + serialized_bootinfo->mem_spawn_core = bootinfo->mem_spawn_core; + serialized_bootinfo->regions_length = bootinfo->regions_length; + + for (int i = 0; i < bootinfo->regions_length; ++i) { + serialized_bootinfo->regions[i].mr_base = bootinfo->regions[i].mr_base; + serialized_bootinfo->regions[i].mr_bytes = bootinfo->regions[i].mr_bytes; + serialized_bootinfo->regions[i].mr_type = bootinfo->regions[i].mr_type; + serialized_bootinfo->regions[i].mr_consumed = bootinfo->regions[i].mr_consumed; + + serialized_bootinfo->regions[i].mrmod_slot = bootinfo->regions[i].mrmod_slot; + serialized_bootinfo->regions[i].mrmod_data = bootinfo->regions[i].mrmod_data; + serialized_bootinfo->regions[i].mrmod_size = bootinfo->regions[i].mrmod_size; + + if (bootinfo->regions[i].mr_type != RegionType_Module) { + serialized_bootinfo->regions[i].mrmod_frame_base = 0; + serialized_bootinfo->regions[i].mrmod_frame_bytes = 0; + continue; + } + + struct capref elf_frame_cap = { + .cnode = cnode_module, + .slot = bootinfo->regions[i].mrmod_slot, + }; + + struct capability elf_frame_id; + err = cap_direct_identify(elf_frame_cap, &elf_frame_id); + if (err_is_fail(err)) return err; + assert(elf_frame_id.type == ObjType_Frame); + + serialized_bootinfo->regions[i].mrmod_frame_base = elf_frame_id.u.frame.base; + serialized_bootinfo->regions[i].mrmod_frame_bytes = elf_frame_id.u.frame.bytes; + } + + return SYS_ERR_OK; +} + + +static errval_t handle_rpc_get_bootinfo( + struct generic_rpc_server *rpc, + struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1, + struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1 +) { + errval_t err; + size_t bootinfo_serialized_size = sizeof(struct bootinfo_serialized) + bi->regions_length * sizeof(struct mem_region_serialized); + assert(bootinfo_serialized_size <= RPC_SHARED_SIZE); + + err = serialize_bootinfo(bi, (struct bootinfo_serialized *) rpc->shared_mem); + if (err_is_fail(err)) return err; + + *ret_size = bootinfo_serialized_size; + + return SYS_ERR_OK; +} rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = { [RPC_MTYPE_SEND_NUMBER] = handle_rpc_send_number, @@ -351,4 +422,5 @@ rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = { [RPC_MTYPE_PROCESS_SPAWN] = handle_rpc_process_spawn, [RPC_MTYPE_PROCESS_GET_NAME] = handle_rpc_process_get_name, [RPC_MTYPE_PROCESS_GET_ALL_PIDS] = handle_rpc_process_get_all_pids, + [RPC_MTYPE_GET_BOOTINFO] = handle_rpc_get_bootinfo, }; diff --git a/usr/init/main.c b/usr/init/main.c index a7dbf53..6e831db 100644 --- a/usr/init/main.c +++ b/usr/init/main.c @@ -27,6 +27,7 @@ #include "mem_alloc.h" #include #include +#include #include @@ -162,6 +163,53 @@ bsp_main(int argc, char *argv[]) { return EXIT_SUCCESS; } +static errval_t deserialize_bootinfo(struct bootinfo_serialized * serialized, struct bootinfo ** ret) { + errval_t err; + assert(serialized != NULL); + + size_t bootinfo_size = sizeof(struct bootinfo) + serialized->regions_length * sizeof(struct mem_region); + + struct capref ret_frame; + err = frame_alloc(&ret_frame, bootinfo_size, NULL); + if (err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_ALLOC); + + err = paging_map_frame(get_current_paging_state(), (void **) ret, bootinfo_size, ret_frame); + if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_MAP); + // *ret = malloc(bootinfo_size); + + (*ret)->host_msg = serialized->host_msg; + (*ret)->host_msg_bits = serialized->host_msg_bits; + (*ret)->mem_spawn_core = serialized->mem_spawn_core; + (*ret)->regions_length = serialized->regions_length; + + for (int i = 0; i < serialized->regions_length; ++i) { + (*ret)->regions[i].mr_base = serialized->regions[i].mr_base; + (*ret)->regions[i].mr_bytes = serialized->regions[i].mr_bytes; + (*ret)->regions[i].mr_type = serialized->regions[i].mr_type; + (*ret)->regions[i].mr_consumed = serialized->regions[i].mr_consumed; + + (*ret)->regions[i].mrmod_size = serialized->regions[i].mrmod_size; + (*ret)->regions[i].mrmod_data = serialized->regions[i].mrmod_data; + (*ret)->regions[i].mrmod_slot = serialized->regions[i].mrmod_slot; + + if (serialized->regions[i].mr_type != RegionType_Module) { + continue; + } + + //forge cap + struct capref forge_destination = { + .cnode = cnode_module, + .slot = serialized->regions[i].mrmod_slot, + }; + + err = frame_forge(forge_destination, serialized->regions[i].mrmod_frame_base, serialized->regions[i].mrmod_frame_bytes, my_core_id); + if (err_is_fail(err)) return err; + } + + return SYS_ERR_OK; +} + + static int app_main(int argc, char *argv[]) { errval_t err; @@ -174,8 +222,14 @@ app_main(int argc, char *argv[]) { // - grading_test_early(); // - grading_test_late(); - // TODO: get the bootinfo - bi = NULL; + struct bootinfo_serialized * bi_ser; + err = aos_rpc_get_bootinfo(aos_rpc_get_init_channel(), &bi_ser); + if (err_is_fail(err)) return err; + err = deserialize_bootinfo(bi_ser, &bi); + if (err_is_fail(err)) return err; + + debug_printf("[app_main]: received bootinfo with %d regions\n", bi->regions_length); + // Grading grading_setup_app_init(bi);