bool ir_trampoline_init(void *UNUSED(unused)) { // Map the trampoline area into memory vm_mapPageRange(vm_getKernelDirectory(), (uintptr_t)IR_TRAMPOLINE_PHYSICAL, (vm_address_t)IR_TRAMPOLINE_BEGIN, IR_TRAMPOLINE_PAGES, VM_FLAGS_KERNEL); // Copy the IDT section into the trampoline vm_address_t _idt_sectionBegin = (vm_address_t)&idt_sectionBegin; vm_address_t _idt_sectionEnd = (vm_address_t)&idt_sectionEnd; vm_address_t _idt_entryHandler = (vm_address_t)&idt_entry_handler; memcpy(ir_trampoline_map->base, &idt_sectionBegin, _idt_sectionEnd - _idt_sectionBegin); ir_trampolineFixEntryCall(_idt_entryHandler - _idt_sectionBegin, _idt_sectionEnd - _idt_entryHandler); // Set IDT and GDT straight ir_idt_init(ir_trampoline_map->idt, IR_TRAMPOLINE_BEGIN - _idt_sectionBegin); gdt_init(ir_trampoline_map->gdt, &ir_trampoline_map->tss); return true; }
ld_exectuable_t *ld_exectuableCopy(vm_page_directory_t pdirectory, ld_exectuable_t *source) { if(!source) return NULL; ld_exectuable_t *executable = halloc(NULL, sizeof(ld_exectuable_t)); if(executable) { source->useCount ++; executable->pdirectory = pdirectory; executable->useCount = 1; executable->entry = source->entry; executable->source = source; executable->pimage = source->pimage; executable->vimage = source->vimage; executable->imagePages = source->imagePages; vm_mapPageRange(pdirectory, executable->pimage, executable->vimage, executable->imagePages, VM_FLAGS_USERLAND_R); } return executable; }
ld_exectuable_t *ld_exectuableCreate(vm_page_directory_t pdirectory, uint8_t *begin, size_t UNUSED(size)) { elf_header_t *header = (elf_header_t *)begin; if(strncmp((const char *)header->e_ident, ELF_MAGIC, strlen(ELF_MAGIC)) != 0) return NULL; ld_exectuable_t *executable = halloc(NULL, sizeof(ld_exectuable_t)); if(executable) { // Initialize the executable executable->useCount = 1; executable->entry = header->e_entry; executable->pdirectory = pdirectory; elf_program_header_t *programHeader = (elf_program_header_t *)(begin + header->e_phoff); vm_address_t minAddress = -1; vm_address_t maxAddress = 0; size_t pages = 0; // Calculate the needed size for(int i=0; i<header->e_phnum; i++) { elf_program_header_t *program = &programHeader[i]; if(program->p_type == PT_LOAD) { if(program->p_paddr < minAddress) minAddress = program->p_paddr; if(program->p_paddr + program->p_memsz > maxAddress) maxAddress = program->p_paddr + program->p_memsz; } } // Calculate the starting address and the number of pages we need to allocate minAddress = round4kDown(minAddress); pages = pageCount(maxAddress - minAddress); // Memory allocation uint8_t *memory = (uint8_t *)pm_alloc(pages); uint8_t *target = (uint8_t *)vm_alloc(vm_getKernelDirectory(), (uintptr_t)memory, pages, VM_FLAGS_KERNEL); uint8_t *source = begin; memset(target, 0, pages * VM_PAGE_SIZE); // Copy the data from the image for(int i=0; i<header->e_phnum; i++) { elf_program_header_t *program = &programHeader[i]; if(program->p_type == PT_LOAD) { memcpy(&target[program->p_vaddr - minAddress], &source[program->p_offset], program->p_filesz); } } vm_free(vm_getKernelDirectory(), (vm_address_t)target, pages); vm_mapPageRange(pdirectory, (uintptr_t)memory, minAddress, pages, VM_FLAGS_USERLAND_R); executable->pimage = (uintptr_t)memory; executable->vimage = (vm_address_t)minAddress; executable->imagePages = pages; } return executable; }