mirror of
https://github.com/limine-bootloader/limine
synced 2025-01-19 11:09:26 +03:00
commit
34584d97ea
@ -33,13 +33,14 @@ void multiboot1_load(char *config, char *cmdline) {
|
|||||||
uint8_t *kernel = freadall(kernel_file, MEMMAP_USABLE);
|
uint8_t *kernel = freadall(kernel_file, MEMMAP_USABLE);
|
||||||
|
|
||||||
struct multiboot1_header header = {0};
|
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;
|
uint32_t v;
|
||||||
memcpy(&v, kernel + i, 4);
|
memcpy(&v, kernel + header_offset, 4);
|
||||||
|
|
||||||
if (v == MULTIBOOT1_HEADER_MAGIC) {
|
if (v == MULTIBOOT1_HEADER_MAGIC) {
|
||||||
memcpy(&header, kernel + i, sizeof(header));
|
memcpy(&header, kernel + header_offset, sizeof(header));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,28 +51,54 @@ void multiboot1_load(char *config, char *cmdline) {
|
|||||||
if (header.magic + header.flags + header.checksum)
|
if (header.magic + header.flags + header.checksum)
|
||||||
panic("multiboot1: Header checksum is invalid");
|
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;
|
uint32_t entry_point = 0;
|
||||||
|
|
||||||
switch (bits) {
|
if (header.flags & (1 << 16)) {
|
||||||
case 32:
|
if (header.load_addr > header.header_addr)
|
||||||
if (elf32_load(kernel, &entry_point, MEMMAP_USABLE))
|
panic("multiboot1: Illegal load address");
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
uint32_t n_modules;
|
||||||
@ -102,7 +129,7 @@ void multiboot1_load(char *config, char *cmdline) {
|
|||||||
|
|
||||||
char *cmdline = config_get_value(config, i, "MODULE_STRING");
|
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->end = m->begin + f.size;
|
||||||
m->cmdline = (uint32_t)(size_t)cmdline;
|
m->cmdline = (uint32_t)(size_t)cmdline;
|
||||||
m->pad = 0;
|
m->pad = 0;
|
||||||
@ -193,14 +220,22 @@ void multiboot1_load(char *config, char *cmdline) {
|
|||||||
for (size_t i = 0; i < memmap_entries; i++ ){
|
for (size_t i = 0; i < memmap_entries; i++ ){
|
||||||
mmap[i].size = sizeof(*mmap) - 4;
|
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;
|
memmap[i].type = MEMMAP_USABLE;
|
||||||
|
|
||||||
if (memmap[i].type == MEMMAP_USABLE) {
|
if (memmap[i].type == MEMMAP_USABLE) {
|
||||||
if (memmap[i].base < 0x100000)
|
if (memmap[i].base < 0x100000) {
|
||||||
memory_lower += memmap[i].length;
|
if (memmap[i].base + memmap[i].length > 0x100000) {
|
||||||
else
|
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;
|
memory_upper += memmap[i].length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +255,6 @@ __attribute__((noreturn)) void multiboot1_spinup_32(
|
|||||||
|
|
||||||
__attribute__((noreturn)) void multiboot1_spinup(
|
__attribute__((noreturn)) void multiboot1_spinup(
|
||||||
uint32_t entry_point, uint32_t multiboot1_info) {
|
uint32_t entry_point, uint32_t multiboot1_info) {
|
||||||
pic_mask_all();
|
|
||||||
pic_flush();
|
pic_flush();
|
||||||
|
|
||||||
#if defined (uefi)
|
#if defined (uefi)
|
||||||
|
Loading…
Reference in New Issue
Block a user