mirror of
https://github.com/limine-bootloader/limine
synced 2024-12-11 17:24:08 +03:00
commit
34584d97ea
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user