spawn: Move code to correct function
This commit is contained in:
parent
8bd3bd5f55
commit
e5632b050f
@ -50,73 +50,6 @@ 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
|
||||
* the child. It will be filled out by this function. Must not be NULL.
|
||||
* \param pid A pointer to a domainid_t variable that will be
|
||||
* assigned to by this function. 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_argv(int argc, char *argv[], struct spawninfo *si,
|
||||
domainid_t *pid) {
|
||||
// TODO: Implement me
|
||||
// - Initialize the spawn_info struct
|
||||
// - Get the module from the multiboot image
|
||||
// and map it (take a look at multiboot.c)
|
||||
// - Setup the child's cspace
|
||||
// - Setup the child's vspace
|
||||
// - Load the ELF binary
|
||||
// - Setup the dispatcher
|
||||
// - Setup the environment
|
||||
// - Make the new dispatcher runnable
|
||||
|
||||
// afeer: script page 84/85
|
||||
cnode_create_l1(&si->cspace_l1_cnode_cap, &si->cspace_l1_cnode_info);
|
||||
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_TASKCN, &si->cspace_l2_cnode_taskcn);
|
||||
|
||||
// afeer: (script page 84) is this correct?
|
||||
si->cspace_cap_selfep.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_selfep.slot = TASKCN_SLOT_SELFEP;
|
||||
|
||||
si->cspace_cap_dispatcher.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_dispatcher.slot = TASKCN_SLOT_DISPATCHER;
|
||||
|
||||
si->cspace_cap_rootcn.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_rootcn.slot = TASKCN_SLOT_ROOTCN;
|
||||
|
||||
si->cspace_cap_dispframe.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_dispframe.slot = TASKCN_SLOT_DISPFRAME;
|
||||
|
||||
si->cspace_cap_argspage.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_argspage.slot = TASKCN_SLOT_ARGSPAGE;
|
||||
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC0, &si->cspace_l2_cnode_slot_alloc_0);
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC1, &si->cspace_l2_cnode_slot_alloc_1);
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC2, &si->cspace_l2_cnode_slot_alloc_2);
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_BASE_PAGE_CN, &si->cspace_l2_cnode_base_pagecn);
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_PAGECN, &si->cspace_l2_cnode_pagecn); // < afeer: TODO: script page 85: fill this with pagetable capabilities
|
||||
|
||||
// afeer: populate some capabilities
|
||||
dispatcher_create(si->cspace_cap_dispatcher);
|
||||
cap_retype(si->cspace_cap_selfep, si->cspace_cap_dispatcher, 0, ObjType_EndPointLMP, 0, 1);
|
||||
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
struct allocate_state {
|
||||
// TODO: add fields
|
||||
};
|
||||
@ -152,11 +85,131 @@ static errval_t elf_allocate(
|
||||
|
||||
// TODO: Map into child address space
|
||||
|
||||
// TODO: Keep track of the mapped regions, so you can unmap them later.
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO(M2): Implement this function.
|
||||
* (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
|
||||
* the child. It will be filled out by this function. Must not be NULL.
|
||||
* \param pid A pointer to a domainid_t variable that will be
|
||||
* assigned to by this function. 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_argv(int argc, char *argv[], struct spawninfo *si,
|
||||
domainid_t *pid) {
|
||||
errval_t err;
|
||||
// - Initialize the spawn_info struct
|
||||
// TODO
|
||||
|
||||
// - Get the module from the multiboot image
|
||||
// and map it (take a look at multiboot.c)
|
||||
|
||||
assert(argc > 0);
|
||||
struct mem_region *module = multiboot_find_module(bi, argv[0]);
|
||||
if (module == NULL) return SPAWN_ERR_FIND_MODULE;
|
||||
size_t elf_bytes = module->mrmod_size;
|
||||
|
||||
// Get the frame of the ELF
|
||||
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 < elf_bytes) return SPAWN_ERR_MODULE_FRAME_TOO_SMALL;
|
||||
|
||||
// Map the ELF into the current address space
|
||||
char *elf_base;
|
||||
err = paging_map_frame_attr(
|
||||
get_current_paging_state(), (void **)&elf_base,
|
||||
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, size: %"PRIuPTR", magic: %"PRIx8" %c%c%c\n",
|
||||
argv[0], elf_bytes, elf_base[0], elf_base[1], elf_base[2], elf_base[3]);
|
||||
|
||||
// - Setup the child's cspace
|
||||
|
||||
// afeer: script page 84/85
|
||||
cnode_create_l1(&si->cspace_l1_cnode_cap, &si->cspace_l1_cnode_info);
|
||||
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_TASKCN, &si->cspace_l2_cnode_taskcn);
|
||||
|
||||
// afeer: (script page 84) is this correct?
|
||||
si->cspace_cap_selfep.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_selfep.slot = TASKCN_SLOT_SELFEP;
|
||||
|
||||
si->cspace_cap_dispatcher.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_dispatcher.slot = TASKCN_SLOT_DISPATCHER;
|
||||
|
||||
si->cspace_cap_rootcn.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_rootcn.slot = TASKCN_SLOT_ROOTCN;
|
||||
|
||||
si->cspace_cap_dispframe.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_dispframe.slot = TASKCN_SLOT_DISPFRAME;
|
||||
|
||||
si->cspace_cap_argspage.cnode = si->cspace_l2_cnode_taskcn;
|
||||
si->cspace_cap_argspage.slot = TASKCN_SLOT_ARGSPAGE;
|
||||
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC0, &si->cspace_l2_cnode_slot_alloc_0);
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC1, &si->cspace_l2_cnode_slot_alloc_1);
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_SLOT_ALLOC2, &si->cspace_l2_cnode_slot_alloc_2);
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_BASE_PAGE_CN, &si->cspace_l2_cnode_base_pagecn);
|
||||
cnode_create_foreign_l2(si->cspace_l1_cnode_cap, ROOTCN_SLOT_PAGECN, &si->cspace_l2_cnode_pagecn); // < afeer: TODO: script page 85: fill this with pagetable capabilities
|
||||
|
||||
// afeer: populate some capabilities
|
||||
dispatcher_create(si->cspace_cap_dispatcher);
|
||||
cap_retype(si->cspace_cap_selfep, si->cspace_cap_dispatcher, 0, ObjType_EndPointLMP, 0, 1);
|
||||
|
||||
// - Setup the child's vspace
|
||||
// TODO
|
||||
|
||||
// - Load the ELF binary
|
||||
struct allocate_state st = {};
|
||||
genvaddr_t entry;
|
||||
err = elf_load(EM_AARCH64, elf_allocate, &st, (lvaddr_t)elf_base, elf_bytes, &entry);
|
||||
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_ELF_LOAD);
|
||||
|
||||
uint64_t got_addr = 0;
|
||||
struct Elf64_Shdr* got_shdr =
|
||||
elf64_find_section_header_name((lvaddr_t)elf_base, elf_bytes, ".got");
|
||||
if (got_shdr) {
|
||||
got_addr = got_shdr->sh_addr;
|
||||
}
|
||||
|
||||
// - Setup the dispatcher
|
||||
// TODO
|
||||
|
||||
// - Setup the environment
|
||||
// TODO
|
||||
|
||||
// - Make the new dispatcher runnable
|
||||
// TODO
|
||||
|
||||
|
||||
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* (M2): Implement this function.
|
||||
* \brief Spawn a new dispatcher executing 'binary_name'
|
||||
*
|
||||
* \param binary_name The name of the binary.
|
||||
@ -173,40 +226,17 @@ errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si,
|
||||
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;
|
||||
|
||||
// - Get the frame of the ELF
|
||||
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->mrmod_size) return SPAWN_ERR_MODULE_FRAME_TOO_SMALL;
|
||||
|
||||
// - Map the ELF into the current addess space
|
||||
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, size: %"PRIx64", magic: %"PRIx8" %c%c%c\n",
|
||||
binary_name, module->mrmod_size, module_data[0], module_data[1], module_data[2], module_data[3]);
|
||||
|
||||
// - Parse the ELF
|
||||
struct allocate_state st = {};
|
||||
genvaddr_t entry;
|
||||
err = elf_load(EM_AARCH64, elf_allocate, &st, (lvaddr_t)module_data, module->mrmod_size, &entry);
|
||||
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_ELF_LOAD);
|
||||
// TODO
|
||||
|
||||
// - Fill in argc/argv from the multiboot command line
|
||||
// - Call spawn_load_argv
|
||||
// TODO
|
||||
int argc = 1;
|
||||
char *argv[1];
|
||||
argv[0] = binary_name;
|
||||
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
// - Call spawn_load_argv
|
||||
err = spawn_load_argv(argc, argv, si, pid);
|
||||
if (err_is_fail(err)) return err;
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user