static ER _dmloader_ins_ldm(const uint8_t *mod_data, uint32_t mod_data_sz, ID ldm_can_id) { if (ldm_can_id != 1) return E_ID; T_LDM_CAN *ldm_can = &ldm_cans[ldm_can_id - 1]; ER ercd; ercd = loc_mtx(DMLOADER_MTX); if(ercd != E_OK) { syslog(LOG_ERROR, "%s(): Acquire mutex failed.", __FUNCTION__); goto error_exit; } if (ldm_can->status != LDM_CAN_FREE) { syslog(LOG_ERROR, "%s(): LDM container is not free.", __FUNCTION__); ercd = E_OBJ; goto error_exit; } elf32_ldctx_t ctx; ctx.data_buf = ldm_can->data_mempool; ctx.data_bufsz = ldm_can->data_mempool_size; ctx.text_buf = ldm_can->text_mempool; ctx.text_bufsz = ldm_can->text_mempool_size; /** * Load ELF32 data */ ercd = elf32_load(mod_data, mod_data_sz, &ctx); if(ercd != E_OK) goto error_exit; dmloader_instruction_memory_barrier(); uint32_t mod_pil_version = *(uint32_t*)ctx.sym__module_pil_version; if (PIL_VERSION != mod_pil_version) { syslog(LOG_ERROR, "%s(): Wrong PIL version. FW PIL VER: %d, APP PIL VER: %d.", __FUNCTION__, PIL_VERSION, mod_pil_version); ercd = E_PAR; goto error_exit; } /** * Handle module configuration */ ldm_can->cfg_table = ctx.sym__module_cfg_tab; ldm_can->cfg_entry_num = *(SIZE*)ctx.sym__module_cfg_entry_num; ercd = handle_module_cfg_tab(ldm_can); if(ercd != E_OK) goto error_exit; ercd = unl_mtx(DMLOADER_MTX); assert(ercd == E_OK); ldm_can->status = LDM_CAN_RUNNING; /* Fall through */ error_exit: unl_mtx(DMLOADER_MTX); return ercd; }
BOOT_CODE static paddr_t load_boot_module(node_id_t node, multiboot_module_t* boot_module, paddr_t load_paddr) { Elf32_Header_t* elf_file = (Elf32_Header_t*)boot_module->start; v_region_t v_reg; if (!elf32_checkFile(elf_file)) { printf("Boot module does not contain a valid ELF32 image\n"); return 0; } v_reg = elf32_getMemoryBounds(elf_file); if (v_reg.end == 0) { printf("ELF32 image in boot module does not contain any segments\n"); return 0; } v_reg.end = ROUND_UP(v_reg.end, PAGE_BITS); printf("size=0x%x v_entry=0x%x v_start=0x%x v_end=0x%x ", v_reg.end - v_reg.start, elf_file->e_entry, v_reg.start, v_reg.end ); if (!IS_ALIGNED(v_reg.start, PAGE_BITS)) { printf("Userland image virtual start address must be 4KB-aligned\n"); return 0; } if (v_reg.end + 2 * BIT(PAGE_BITS) > PPTR_USER_TOP) { /* for IPC buffer frame and bootinfo frame, need 2*4K of additional userland virtual memory */ printf("Userland image virtual end address too high\n"); return 0; } if ((elf_file->e_entry < v_reg.start) || (elf_file->e_entry >= v_reg.end)) { printf("Userland image entry point does not lie within userland image\n"); return 0; } /* fill ui_info struct */ glks.ui_info_list[node].pv_offset = load_paddr - v_reg.start; glks.ui_info_list[node].p_reg.start = load_paddr; load_paddr += v_reg.end - v_reg.start; glks.ui_info_list[node].p_reg.end = load_paddr; glks.ui_info_list[node].v_entry = elf_file->e_entry; printf("p_start=0x%x p_end=0x%x\n", glks.ui_info_list[node].p_reg.start, glks.ui_info_list[node].p_reg.end ); if (load_paddr > glks.avail_p_reg.end) { printf("End of loaded userland image lies outside of usable physical memory\n"); return 0; } /* initialise all initial userland memory and load potentially sparse ELF image */ memzero( (void*)glks.ui_info_list[node].p_reg.start, glks.ui_info_list[node].p_reg.end - glks.ui_info_list[node].p_reg.start ); elf32_load(elf_file, glks.ui_info_list[node].pv_offset); return load_paddr; }