From cce892e92ffbd14c463e74bfb6cbc3eaf2cd57bd Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 6 May 2018 22:03:44 -0700 Subject: [PATCH] Load ELF file by sections to get addresses right --- src/arch/x86_64/kernel.ld | 10 ++++----- src/boot/elf.h | 17 ++++++++++++++++ src/boot/loader.c | 38 +++++++++++++++++++++++++++++------ src/kernel/interrupt_isrs.inc | 34 +++++++++++++++++++++++++++++++ src/kernel/main.cpp | 7 +------ 5 files changed, 89 insertions(+), 17 deletions(-) diff --git a/src/arch/x86_64/kernel.ld b/src/arch/x86_64/kernel.ld index 4224b6c..29a9d0c 100755 --- a/src/arch/x86_64/kernel.ld +++ b/src/arch/x86_64/kernel.ld @@ -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); } diff --git a/src/boot/elf.h b/src/boot/elf.h index b0e1a3e..146fe74 100644 --- a/src/boot/elf.h +++ b/src/boot/elf.h @@ -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)); diff --git a/src/boot/loader.c b/src/boot/loader.c index c042846..b3b51c1 100644 --- a/src/boot/loader.c +++ b/src/boot/loader.c @@ -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; - status = file->Read(file, &length, addr); - CHECK_EFI_STATUS_OR_RETURN(status, L"Reading file"); + 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); diff --git a/src/kernel/interrupt_isrs.inc b/src/kernel/interrupt_isrs.inc index 5a8fb8b..ff6f1c6 100644 --- a/src/kernel/interrupt_isrs.inc +++ b/src/kernel/interrupt_isrs.inc @@ -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) diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp index 08ab216..594477f 100644 --- a/src/kernel/main.cpp +++ b/src/kernel/main.cpp @@ -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(__bss_end) - - reinterpret_cast(__bss_start)); - page_manager *pager = new (&g_page_manager) page_manager; memory_initialize_managers(