:: commit dae892707888db36fc3768154eeb1e8c5544d6a0

mintsuki <mintsuki@protonmail.com> — 2022-04-14 18:34

parents: 15267d8522

limine: Add support for .limine_reqs ELF section

diff --git a/common/lib/elf.c b/common/lib/elf.c
index df516193..57fe63f4 100644
--- a/common/lib/elf.c
+++ b/common/lib/elf.c
@@ -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;
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 0760ce4a..39e67e48 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -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 (requests_count == MAX_REQUESTS) {
-            panic(true, "limine: Maximum requests exceeded");
+    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++;
         }
-
-        // Check for a conflict
-        if (_get_request(p) != NULL) {
-            panic(true, "limine: Conflict detected for request ID %X %X", p[2], p[3]);
+    } 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 (p[0] != common_magic[0]) {
+                continue;
+            }
+            if (p[1] != common_magic[1]) {
+                continue;
+            }
+
+            if (requests_count == MAX_REQUESTS) {
+                panic(true, "limine: Maximum requests exceeded");
+            }
+
+            // 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;
         }
-
-        requests[requests_count++] = p;
     }
 
     if (requests_count == 0) {
diff --git a/test/limine.c b/test/limine.c
index 37e0d810..839d8099 100644
--- a/test/limine.c
+++ b/test/limine.c
@@ -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:
diff --git a/test/linker.ld b/test/linker.ld
index 4ee8dc40..627a2187 100644
--- a/test/linker.ld
+++ b/test/linker.ld
@@ -20,6 +20,11 @@ SECTIONS
 
     . += 0x1000;
 
+    .limine_reqs : {
+        KEEP(*(.limine_reqs))
+        QUAD(0)
+    } :rodata
+
     .stivalehdr : {
         KEEP(*(.stivalehdr))
     } :rodata
tab: 248 wrap: offon