From 6b911752f0950bcef8b8bb3852645a23296eca1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Tue, 22 Mar 2022 19:37:14 +0100 Subject: [PATCH] spawn: Find and map module, print magic, add test --- errors/errno.fugu | 1 + hake/menu.lst.armv8_a57_qemu | 1 + hake/menu.lst.armv8_imx8x | 2 +- include/test_spawn.h | 8 ++++++++ lib/grading/Hakefile | 3 ++- lib/grading/grading.c | 2 ++ lib/grading/test_spawn.c | 9 ++++++++ lib/spawn/spawn.c | 40 ++++++++++++++++++++++++++++-------- platforms/Hakefile | 2 +- usr/init/Hakefile | 2 +- 10 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 include/test_spawn.h create mode 100644 lib/grading/test_spawn.c diff --git a/errors/errno.fugu b/errors/errno.fugu index 0430e02..7db67d5 100755 --- a/errors/errno.fugu +++ b/errors/errno.fugu @@ -619,6 +619,7 @@ errors spawn SPAWN_ERR_ { failure FILL_SMALLCN "Failure filling smallcn of new domain", failure MAP_BOOTINFO "Failure mapping bootinfo to new domain", failure FIND_MODULE "Didn't find module to be spawned", + failure MODULE_FRAME_TOO_SMALL "Module frame is too small", failure MAP_MODULE "Failed mapping in module", failure UNMAP_MODULE "Failed unmapping module", failure CREATE_SEGCN "Failed to create segment CNode", diff --git a/hake/menu.lst.armv8_a57_qemu b/hake/menu.lst.armv8_a57_qemu index 00c5ed9..2e8b676 100644 --- a/hake/menu.lst.armv8_a57_qemu +++ b/hake/menu.lst.armv8_a57_qemu @@ -5,5 +5,6 @@ bootdriver /armv8/sbin/boot_armv8_generic cpudriver /armv8/sbin/cpu_a57_qemu loglevel=3 serial=0x9000000 logmask=128 module /armv8/sbin/init +module /armv8/sbin/hello # End of file, this needs to have a certain length... diff --git a/hake/menu.lst.armv8_imx8x b/hake/menu.lst.armv8_imx8x index ed99a62..0448e84 100644 --- a/hake/menu.lst.armv8_imx8x +++ b/hake/menu.lst.armv8_imx8x @@ -5,4 +5,4 @@ bootdriver /armv8/sbin/boot_armv8_generic cpudriver /armv8/sbin/cpu_imx8x module /armv8/sbin/init - +module /armv8/sbin/hello diff --git a/include/test_spawn.h b/include/test_spawn.h new file mode 100644 index 0000000..cc58a33 --- /dev/null +++ b/include/test_spawn.h @@ -0,0 +1,8 @@ +#ifndef __TEST_SPAWN_H +#define __TEST_SPAWN_H + +#include + +void do_test_spawn(void); + +#endif /* __TEST_SPAWN_H */ diff --git a/lib/grading/Hakefile b/lib/grading/Hakefile index de8629e..397a377 100644 --- a/lib/grading/Hakefile +++ b/lib/grading/Hakefile @@ -18,7 +18,8 @@ "grading.c", "test_helper.c", "test_mm.c", - "test_paging.c" + "test_paging.c", + "test_spawn.c" ], addLibraries = [ ] diff --git a/lib/grading/grading.c b/lib/grading/grading.c index 637a6b7..67e508e 100644 --- a/lib/grading/grading.c +++ b/lib/grading/grading.c @@ -11,6 +11,7 @@ #include #include #include +#include void grading_setup_bsp_init(int argc, char **argv) { @@ -34,6 +35,7 @@ grading_test_mm(struct mm *test) { void grading_test_early(void) { + do_test_spawn(); } void diff --git a/lib/grading/test_spawn.c b/lib/grading/test_spawn.c new file mode 100644 index 0000000..d4663e0 --- /dev/null +++ b/lib/grading/test_spawn.c @@ -0,0 +1,9 @@ +#include +#include +#include + +void do_test_spawn(void) { + struct spawninfo si; + domainid_t pid; + CHECK_ERR(spawn_load_by_name("hello", &si, &pid)); +} diff --git a/lib/spawn/spawn.c b/lib/spawn/spawn.c index ad2a363..4fb4bb5 100644 --- a/lib/spawn/spawn.c +++ b/lib/spawn/spawn.c @@ -22,7 +22,7 @@ extern coreid_t my_core_id; /** * \brief Set the base address of the .got (Global Offset Table) section of the ELF binary - * + * * \param arch_load_info This must be the base address of the .got section (local to the * child's VSpace). Must not be NULL. * \param handle The handle for the new dispatcher that is to be spawned. Must not be NULL. @@ -56,11 +56,11 @@ static void armv8_set_registers(void *arch_load_info, /** * TODO(M2): Implement this function. * \brief Spawn a new dispatcher called 'argv[0]' with 'argc' arguments. - * + * * This function spawns a new dispatcher running the ELF binary called * 'argv[0]' with 'argc' - 1 additional arguments. It fills out 'si' * and 'pid'. - * + * * \param argc The number of command line arguments. Must be > 0. * \param argv An array storing 'argc' command line arguments. * \param si A pointer to the spawninfo struct representing @@ -90,25 +90,47 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, /** * TODO(M2): Implement this function. * \brief Spawn a new dispatcher executing 'binary_name' - * + * * \param binary_name The name of the binary. * \param si A pointer to a spawninfo struct that will be * filled out by spawn_load_by_name. Must not be NULL. * \param pid A pointer to a domainid_t that will be * filled out by spawn_load_by_name. Must not be NULL. - * + * * \return Either SYS_ERR_OK if no error occured or an error * indicating what went wrong otherwise. */ errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si, domainid_t *pid) { - // TODO: Implement me + errval_t err; + // - Get the mem_region from the multiboot image + struct mem_region *module = multiboot_find_module(bi, binary_name); + if (module == NULL) return SPAWN_ERR_FIND_MODULE; + + struct capref child_frame = { + .cnode = cnode_module, + .slot = module->mrmod_slot, + }; + + struct capability c; + err = cap_direct_identify(child_frame, &c); + if (err_is_fail(err)) return err; + gensize_t frame_size = get_size(&c); + if (frame_size < module->mr_bytes) return SPAWN_ERR_MODULE_FRAME_TOO_SMALL; + + char *module_data; + err = paging_map_frame_attr( + get_current_paging_state(), (void **)&module_data, + frame_size, child_frame, VREGION_FLAGS_READ + ); + if (err_is_fail(err)) return err_push(err, SPAWN_ERR_MAP_MODULE); + + debug_printf("SPAWN: mapped %s, magic: %"PRIx8" %c%c%c\n", + binary_name, module_data[0], module_data[1], module_data[2], module_data[3]); + // - Fill in argc/argv from the multiboot command line // - Call spawn_load_argv return LIB_ERR_NOT_IMPLEMENTED; } - - - diff --git a/platforms/Hakefile b/platforms/Hakefile index 0c9bc36..707d721 100644 --- a/platforms/Hakefile +++ b/platforms/Hakefile @@ -12,7 +12,7 @@ let -- Default list of modules to build/install - modules_common = [ "/sbin/" ++ f | f <- [ "init" + modules_common = [ "/sbin/" ++ f | f <- [ "init", "hello" ] ] in [ diff --git a/usr/init/Hakefile b/usr/init/Hakefile index 6ceedc4..dc1e393 100644 --- a/usr/init/Hakefile +++ b/usr/init/Hakefile @@ -20,7 +20,7 @@ "mem_alloc.c" ], addLinkFlags = [ "-e _start_init"], -- this is only needed for init - addLibraries = [ "mm", "getopt", "elf", + addLibraries = [ "mm", "getopt", "elf", "spawn", "grading"], architectures = allArchitectures }