Merge pull request #86 from qookei/trunk

Multiboot 1 improvements
This commit is contained in:
mint 2021-06-30 21:35:53 +02:00 committed by GitHub
commit 34584d97ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -33,13 +33,14 @@ void multiboot1_load(char *config, char *cmdline) {
uint8_t *kernel = freadall(kernel_file, MEMMAP_USABLE);
struct multiboot1_header header = {0};
size_t header_offset = 0;
for (size_t i = 0; i < 8192; i += 4) {
for (header_offset = 0; header_offset < 8192; header_offset += 4) {
uint32_t v;
memcpy(&v, kernel + i, 4);
memcpy(&v, kernel + header_offset, 4);
if (v == MULTIBOOT1_HEADER_MAGIC) {
memcpy(&header, kernel + i, sizeof(header));
memcpy(&header, kernel + header_offset, sizeof(header));
break;
}
}
@ -50,28 +51,54 @@ void multiboot1_load(char *config, char *cmdline) {
if (header.magic + header.flags + header.checksum)
panic("multiboot1: Header checksum is invalid");
if (header.flags & (1 << 16))
panic("multiboot1: Aout kludge not supported");
int bits = elf_bits(kernel);
uint32_t entry_point = 0;
switch (bits) {
case 32:
if (elf32_load(kernel, &entry_point, MEMMAP_USABLE))
panic("multiboot1: ELF32 load failure");
break;
case 64: {
uint64_t e;
if (elf64_load(kernel, &e, NULL, MEMMAP_USABLE, false, true))
panic("multiboot1: ELF64 load failure");
entry_point = e;
if (header.flags & (1 << 16)) {
if (header.load_addr > header.header_addr)
panic("multiboot1: Illegal load address");
break;
size_t load_size = 0;
if (header.load_end_addr)
load_size = header.load_end_addr - header.load_addr;
else
load_size = kernel_file->size;
memmap_alloc_range(header.load_addr, load_size, MEMMAP_KERNEL_AND_MODULES, true, true, false, false);
memcpy((void *)(uintptr_t)header.load_addr, kernel + (header_offset
- (header.header_addr - header.load_addr)), load_size);
if (header.bss_end_addr) {
uintptr_t bss_addr = header.load_addr + load_size;
if (header.bss_end_addr < bss_addr)
panic("multiboot1: Illegal bss end address");
uint32_t bss_size = header.bss_end_addr - bss_addr;
memmap_alloc_range(bss_addr, bss_size, MEMMAP_KERNEL_AND_MODULES, true, true, false, false);
memset((void *)bss_addr, 0, bss_size);
}
entry_point = header.entry_addr;
} else {
int bits = elf_bits(kernel);
switch (bits) {
case 32:
if (elf32_load(kernel, &entry_point, MEMMAP_KERNEL_AND_MODULES))
panic("multiboot1: ELF32 load failure");
break;
case 64: {
uint64_t e;
if (elf64_load(kernel, &e, NULL, MEMMAP_KERNEL_AND_MODULES, false, true))
panic("multiboot1: ELF64 load failure");
entry_point = e;
break;
}
default:
panic("multiboot1: Invalid ELF file bitness");
}
default:
panic("multiboot1: Invalid ELF file bitness");
}
uint32_t n_modules;
@ -102,7 +129,7 @@ void multiboot1_load(char *config, char *cmdline) {
char *cmdline = config_get_value(config, i, "MODULE_STRING");
m->begin = (uint32_t)(size_t)freadall(&f, MEMMAP_USABLE);
m->begin = (uint32_t)(size_t)freadall(&f, MEMMAP_KERNEL_AND_MODULES);
m->end = m->begin + f.size;
m->cmdline = (uint32_t)(size_t)cmdline;
m->pad = 0;
@ -193,14 +220,22 @@ void multiboot1_load(char *config, char *cmdline) {
for (size_t i = 0; i < memmap_entries; i++ ){
mmap[i].size = sizeof(*mmap) - 4;
if (memmap[i].type == MEMMAP_BOOTLOADER_RECLAIMABLE)
if (memmap[i].type == MEMMAP_BOOTLOADER_RECLAIMABLE
|| memmap[i].type == MEMMAP_KERNEL_AND_MODULES)
memmap[i].type = MEMMAP_USABLE;
if (memmap[i].type == MEMMAP_USABLE) {
if (memmap[i].base < 0x100000)
memory_lower += memmap[i].length;
else
if (memmap[i].base < 0x100000) {
if (memmap[i].base + memmap[i].length > 0x100000) {
size_t low_len = 0x100000 - memmap[i].base;
memory_lower += low_len;
memory_upper += memmap[i].length - low_len;
} else {
memory_lower += memmap[i].length;
}
} else {
memory_upper += memmap[i].length;
}
}
}
@ -220,7 +255,6 @@ __attribute__((noreturn)) void multiboot1_spinup_32(
__attribute__((noreturn)) void multiboot1_spinup(
uint32_t entry_point, uint32_t multiboot1_info) {
pic_mask_all();
pic_flush();
#if defined (uefi)