limine: Add support for .limine_reqs ELF section

This commit is contained in:
mintsuki 2022-04-14 20:34:59 +02:00
parent 15267d8522
commit dae8927078
4 changed files with 83 additions and 19 deletions

View File

@ -262,6 +262,11 @@ int elf64_load_section(uint8_t *elf, void *buffer, const char *name, size_t limi
sizeof(struct elf64_shdr));
if (!strcmp(&names[section.sh_name], name)) {
if (limit == 0) {
*(void **)buffer = ext_mem_alloc(section.sh_size);
buffer = *(void **)buffer;
limit = section.sh_size;
}
if (section.sh_size > limit) {
ret = 3;
goto out;

View File

@ -37,7 +37,7 @@
static uint64_t physical_base, virtual_base, slide, direct_map_offset;
static size_t requests_count;
static void *requests[MAX_REQUESTS];
static void **requests;
static uint64_t reported_addr(void *addr) {
return (uint64_t)(uintptr_t)addr + direct_map_offset;
@ -167,28 +167,40 @@ bool limine_load(char *config, char *cmdline) {
kaslr = is_reloc;
// Load requests
requests_count = 0;
uint64_t common_magic[2] = { LIMINE_COMMON_MAGIC };
for (size_t i = 0; i < ALIGN_DOWN(image_size, 8); i += 8) {
uint64_t *p = (void *)(uintptr_t)physical_base + i;
if (p[0] != common_magic[0]) {
continue;
}
if (p[1] != common_magic[1]) {
continue;
if (elf64_load_section(kernel, &requests, ".limine_reqs", 0, slide) == 0) {
for (size_t i = 0; ; i++) {
if (requests[i] == NULL) {
break;
}
requests[i] -= virtual_base;
requests[i] += physical_base;
requests_count++;
}
} else {
requests = ext_mem_alloc(MAX_REQUESTS * sizeof(void *));
requests_count = 0;
uint64_t common_magic[2] = { LIMINE_COMMON_MAGIC };
for (size_t i = 0; i < ALIGN_DOWN(image_size, 8); i += 8) {
uint64_t *p = (void *)(uintptr_t)physical_base + i;
if (requests_count == MAX_REQUESTS) {
panic(true, "limine: Maximum requests exceeded");
}
if (p[0] != common_magic[0]) {
continue;
}
if (p[1] != common_magic[1]) {
continue;
}
// Check for a conflict
if (_get_request(p) != NULL) {
panic(true, "limine: Conflict detected for request ID %X %X", p[2], p[3]);
}
if (requests_count == MAX_REQUESTS) {
panic(true, "limine: Maximum requests exceeded");
}
requests[requests_count++] = p;
// Check for a conflict
if (_get_request(p) != NULL) {
panic(true, "limine: Conflict detected for request ID %X %X", p[2], p[3]);
}
requests[requests_count++] = p;
}
}
if (requests_count == 0) {

View File

@ -12,71 +12,113 @@ struct limine_entry_point_request entry_point_request = {
.entry = limine_main
};
__attribute__((section(".limine_reqs")))
void *entry_point_req = &entry_point_request;
struct limine_framebuffer_request framebuffer_request = {
.id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *framebuffer_req = &framebuffer_request;
struct limine_bootloader_info_request bootloader_info_request = {
.id = LIMINE_BOOTLOADER_INFO_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *bootloader_info_req = &bootloader_info_request;
struct limine_hhdm_request hhdm_request = {
.id = LIMINE_HHDM_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *hhdm_req = &hhdm_request;
struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *memmap_req = &memmap_request;
struct limine_kernel_file_request kf_request = {
.id = LIMINE_KERNEL_FILE_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *kf_req = &kf_request;
struct limine_module_request module_request = {
.id = LIMINE_MODULE_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *module_req = &module_request;
struct limine_rsdp_request rsdp_request = {
.id = LIMINE_RSDP_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *rsdp_req = &rsdp_request;
struct limine_smbios_request smbios_request = {
.id = LIMINE_SMBIOS_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *smbios_req = &smbios_request;
struct limine_efi_system_table_request est_request = {
.id = LIMINE_EFI_SYSTEM_TABLE_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *est_req = &est_request;
struct limine_boot_time_request boot_time_request = {
.id = LIMINE_BOOT_TIME_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *boot_time_req = &boot_time_request;
struct limine_kernel_address_request kernel_address_request = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *kernel_address_req = &kernel_address_request;
struct limine_smp_request _smp_request = {
.id = LIMINE_SMP_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *smp_req = &_smp_request;
struct limine_terminal_request _terminal_request = {
.id = LIMINE_TERMINAL_REQUEST,
.revision = 0, .response = NULL
};
__attribute__((section(".limine_reqs")))
void *terminal_req = &_terminal_request;
static char *get_memmap_type(uint64_t type) {
switch (type) {
case LIMINE_MEMMAP_USABLE:

View File

@ -20,6 +20,11 @@ SECTIONS
. += 0x1000;
.limine_reqs : {
KEEP(*(.limine_reqs))
QUAD(0)
} :rodata
.stivalehdr : {
KEEP(*(.stivalehdr))
} :rodata