Load ELF file by sections to get addresses right

This commit is contained in:
Justin C. Miller
2018-05-06 22:03:44 -07:00
parent 97fb8ef653
commit cce892e92f
5 changed files with 89 additions and 17 deletions

View File

@@ -14,7 +14,7 @@ SECTIONS
*(.text)
}
.data ALIGN(0x1000) : {
.data : {
*(.data)
*(.rodata)
}
@@ -23,15 +23,15 @@ SECTIONS
*(.isrs)
}
.note : {
*(.note.*)
}
.bss ALIGN(0x1000) : {
__bss_start = .;
*(.bss)
__bss_end = .;
}
.note ALIGN(0x1000) : {
*(.note.*)
}
kernel_end = ALIGN(4096);
}

View File

@@ -22,6 +22,9 @@
#endif
const unsigned ELF_PT_LOAD = 1;
const unsigned ELF_ST_PROGBITS = 1;
const unsigned ELF_ST_NOBITS = 8;
const unsigned long ELF_SHF_ALLOC = 0x2;
struct elf_ident
{
@@ -75,3 +78,17 @@ struct elf_program_header
uint64_t align;
} __attribute__ ((packed));
struct elf_section_header
{
uint32_t name;
uint32_t type;
uint64_t flags;
uint64_t addr;
uint64_t offset;
uint64_t size;
uint32_t link;
uint32_t info;
uint64_t align;
uint64_t entry_size;
} __attribute__ ((packed));

View File

@@ -144,9 +144,6 @@ loader_load_elf(
if (prog_header.type != ELF_PT_LOAD) continue;
status = file->SetPosition(file, prog_header.offset);
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
length = prog_header.mem_size;
void *addr = (void *)(prog_header.vaddr - KERNEL_VIRT_ADDRESS);
status = loader_alloc_pages(bootsvc, KERNEL_MEMTYPE, &length, &addr);
@@ -155,10 +152,39 @@ loader_load_elf(
if (data->kernel == 0)
data->kernel = addr;
data->kernel_length = (uint64_t)addr + length - (uint64_t)data->kernel;
}
length = prog_header.file_size;
struct elf_section_header sec_header;
for (int i = 0; i < header.sh_num; ++i) {
status = file->SetPosition(file, header.sh_offset + i * header.sh_entsize);
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
length = header.sh_entsize;
status = file->Read(file, &length, &sec_header);
CHECK_EFI_STATUS_OR_RETURN(status, L"Reading ELF section header");
if ((sec_header.flags & ELF_SHF_ALLOC) == 0) continue;
void *addr = (void *)(sec_header.addr - KERNEL_VIRT_ADDRESS);
if (sec_header.type == ELF_ST_PROGBITS) {
status = file->SetPosition(file, sec_header.offset);
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
length = sec_header.size;
status = file->Read(file, &length, addr);
CHECK_EFI_STATUS_OR_RETURN(status, L"Reading file");
con_printf(L"Loaded %lx bytes %lx - %lx\n",
sec_header.size,
addr,
sec_header.addr + sec_header.size - KERNEL_VIRT_ADDRESS);
} else if (sec_header.type == ELF_ST_NOBITS) {
bootsvc->SetMem(addr, sec_header.size, 0);
con_printf(L"Zeroed %lx bytes %lx - %lx\n",
sec_header.size,
addr,
sec_header.addr + sec_header.size - KERNEL_VIRT_ADDRESS);
}
}
status = file->Close(file);

View File

@@ -100,6 +100,40 @@ IRQ (0x5d, 0x3d, irq3D)
IRQ (0x5e, 0x3e, irq3E)
IRQ (0x5f, 0x3f, irq3F)
IRQ (0x60, 0x40, irq40)
IRQ (0x61, 0x41, irq41)
IRQ (0x62, 0x42, irq42)
IRQ (0x63, 0x43, irq43)
IRQ (0x64, 0x44, irq44)
IRQ (0x65, 0x45, irq45)
IRQ (0x66, 0x46, irq46)
IRQ (0x67, 0x47, irq47)
IRQ (0x68, 0x48, irq48)
IRQ (0x69, 0x49, irq49)
IRQ (0x6a, 0x4a, irq4A)
IRQ (0x6b, 0x4b, irq4B)
IRQ (0x6c, 0x4c, irq4C)
IRQ (0x6d, 0x4d, irq4D)
IRQ (0x6e, 0x4e, irq4E)
IRQ (0x6f, 0x4f, irq4F)
IRQ (0x70, 0x50, irq50)
IRQ (0x71, 0x51, irq51)
IRQ (0x72, 0x52, irq52)
IRQ (0x73, 0x53, irq53)
IRQ (0x74, 0x54, irq54)
IRQ (0x75, 0x55, irq55)
IRQ (0x76, 0x56, irq56)
IRQ (0x77, 0x57, irq57)
IRQ (0x78, 0x58, irq58)
IRQ (0x79, 0x59, irq59)
IRQ (0x7a, 0x5a, irq5A)
IRQ (0x7b, 0x5b, irq5B)
IRQ (0x7c, 0x5c, irq5C)
IRQ (0x7d, 0x5d, irq5D)
IRQ (0x7e, 0x5e, irq5E)
IRQ (0x7f, 0x5f, irq5F)
ISR (0xec, isrTimer)
ISR (0xed, isrLINT0)
ISR (0xee, isrLINT1)

View File

@@ -46,7 +46,7 @@ init_console(const popcorn_data *header)
cons->puts(GIT_VERSION " booting...\n");
log::init(cons);
log::enable(logs::apic, log::level::info);
log::enable(logs::apic, log::level::debug);
log::enable(logs::devices, log::level::debug);
log::enable(logs::memory, log::level::info);
}
@@ -58,11 +58,6 @@ void do_error_1() { do_error_2(); }
void
kernel_main(popcorn_data *header)
{
// First clear BSS
kutil::memset(__bss_start, 0,
reinterpret_cast<uint64_t>(__bss_end) -
reinterpret_cast<uint64_t>(__bss_start));
page_manager *pager = new (&g_page_manager) page_manager;
memory_initialize_managers(