Kernel: Pass ELF program header locations from multiboot to kernel.

Patch contributed by "pd"
This commit is contained in:
Andreas Kling 2019-05-18 03:06:34 +02:00
parent ba92c07a75
commit 14c896ec58
Notes: sideshowbarker 2024-07-19 14:02:38 +09:00
2 changed files with 31 additions and 4 deletions

View file

@ -1,7 +1,7 @@
.set MULTIBOOT_MAGIC, 0x1badb002 .set MULTIBOOT_MAGIC, 0x1badb002
.set MULTIBOOT_PAGE_ALIGN, 0x1 .set MULTIBOOT_PAGE_ALIGN, 0x1
.set MULTIBOOT_MEMORY_INFO, 0x2 .set MULTIBOOT_MEMORY_INFO, 0x2
.set MULTIBOOT_VIDEO_MODE, 0x4 .set MULTIBOOT_VIDEO_MODE, 0x0
.set multiboot_flags, MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE .set multiboot_flags, MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_VIDEO_MODE
.set multiboot_checksum, -(MULTIBOOT_MAGIC + multiboot_flags) .set multiboot_checksum, -(MULTIBOOT_MAGIC + multiboot_flags)
@ -39,6 +39,9 @@ stack_top:
.extern init .extern init
.type init, @function .type init, @function
.extern multiboot_ptr
.type multiboot_ptr, @object
start: start:
cli cli
cld cld
@ -51,6 +54,8 @@ start:
pushl %eax /* Multiboot header magic */ pushl %eax /* Multiboot header magic */
pushl %ebx /* Multiboot header pointer */ pushl %ebx /* Multiboot header pointer */
mov %ebx, multiboot_ptr
call init call init
pushl $exit_message pushl $exit_message

View file

@ -1405,11 +1405,33 @@ enum class KernelMemoryCheckResult {
AccessDenied AccessDenied
}; };
// FIXME: Nothing about this is really super...
// This structure is only present at offset 28 in the main multiboot info struct
// if bit 5 of offset 0 (flags) is set. We're just assuming that the flag is set.
//
// Also, there's almost certainly a better way to get that information here than
// a global set by boot.S
//
// Also I'm not 100% sure any of this is correct...
struct mb_elf {
uint32_t num;
uint32_t size;
uint32_t addr;
uint32_t shndx;
};
extern "C" {
void* multiboot_ptr;
}
static KernelMemoryCheckResult check_kernel_memory_access(LinearAddress laddr, bool is_write) static KernelMemoryCheckResult check_kernel_memory_access(LinearAddress laddr, bool is_write)
{ {
auto* kernel_elf_header = (Elf32_Ehdr*)0xf000; // FIXME: It would be better to have a proper structure for this...
auto* kernel_program_headers = (Elf32_Phdr*)(0xf000 + kernel_elf_header->e_phoff); auto* sections = (const mb_elf*)((const byte*)multiboot_ptr + 28);
for (unsigned i = 0; i < kernel_elf_header->e_phnum; ++i) {
auto* kernel_program_headers = (Elf32_Phdr*)(sections->addr);
for (unsigned i = 0; i < sections->num; ++i) {
auto& segment = kernel_program_headers[i]; auto& segment = kernel_program_headers[i];
if (segment.p_type != PT_LOAD || !segment.p_vaddr || !segment.p_memsz) if (segment.p_type != PT_LOAD || !segment.p_vaddr || !segment.p_memsz)
continue; continue;