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)); sizeof(struct elf64_shdr));
if (!strcmp(&names[section.sh_name], name)) { 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) { if (section.sh_size > limit) {
ret = 3; ret = 3;
goto out; goto out;

View File

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

View File

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

View File

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