:: commit f0e8264e1a4cfa067192a37cdeda2cce2b15c53a

Mintsuki <mintsuki@protonmail.com> — 2026-03-23 05:00

parents: 2e2fc63628

protos/limine: Drop support for base revisions 0-3, require 4 on x86

diff --git a/common/lib/elf.c b/common/lib/elf.c
index ee686bd3..f7f3dd3b 100644
--- a/common/lib/elf.c
+++ b/common/lib/elf.c
@@ -650,73 +650,6 @@ end_of_pt_segment:
     return true;
 }
 
-bool elf64_load_section(uint8_t *elf, size_t file_size, void *buffer, const char *name, size_t limit, uint64_t slide) {
-    struct elf64_hdr *hdr = (void *)elf;
-
-    elf64_validate(hdr);
-
-    if (hdr->sh_num == 0) {
-        return false;
-    }
-
-    if (hdr->shdr_size < sizeof(struct elf64_shdr)) {
-        panic(true, "elf: shdr_size < sizeof(struct elf64_shdr)");
-    }
-
-    if (hdr->shstrndx >= hdr->sh_num) {
-        return false;
-    }
-
-    // Validate section header table is within file bounds
-    uint64_t shdr_table_end = (uint64_t)hdr->shoff + (uint64_t)hdr->sh_num * hdr->shdr_size;
-    if (shdr_table_end > file_size) {
-        return false;
-    }
-
-    struct elf64_shdr *shstrtab = (void *)elf + (hdr->shoff + hdr->shstrndx * hdr->shdr_size);
-
-    // Validate shstrtab offset and size are within file bounds
-    if (shstrtab->sh_offset >= file_size || shstrtab->sh_size > file_size - shstrtab->sh_offset) {
-        return false;
-    }
-
-    char *names = (void *)elf + shstrtab->sh_offset;
-
-    for (uint16_t i = 0; i < hdr->sh_num; i++) {
-        struct elf64_shdr *section = (void *)elf + (hdr->shoff + i * hdr->shdr_size);
-
-        // Validate sh_name is within the string table
-        if (section->sh_name >= shstrtab->sh_size) {
-            continue;
-        }
-
-        // Ensure the string is NUL-terminated within the string table
-        if (!memchr(&names[section->sh_name], '\0', shstrtab->sh_size - section->sh_name)) {
-            continue;
-        }
-
-        if (strcmp(&names[section->sh_name], name) == 0) {
-            // Validate section data is within file bounds
-            if (section->sh_offset >= file_size || section->sh_size > file_size - section->sh_offset) {
-                return false;
-            }
-
-            if (limit == 0) {
-                *(void **)buffer = ext_mem_alloc(section->sh_size);
-                buffer = *(void **)buffer;
-                limit = section->sh_size;
-            }
-            if (section->sh_size > limit) {
-                return false;
-            }
-            memcpy(buffer, elf + section->sh_offset, section->sh_size);
-            return elf64_apply_relocations(elf, hdr, buffer, section->sh_addr, section->sh_size, slide);
-        }
-    }
-
-    return false;
-}
-
 static uint64_t elf64_max_align(uint8_t *elf) {
     uint64_t ret = 0;
 
diff --git a/common/lib/elf.h b/common/lib/elf.h
index e8d5b280..f2931660 100644
--- a/common/lib/elf.h
+++ b/common/lib/elf.h
@@ -24,7 +24,6 @@ int elf_bits(uint8_t *elf);
 struct elf_section_hdr_info elf64_section_hdr_info(uint8_t *elf);
 struct elf_section_hdr_info elf32_section_hdr_info(uint8_t *elf);
 
-bool elf64_load_section(uint8_t *elf, size_t file_size, void *buffer, const char *name, size_t limit, uint64_t slide);
 bool elf64_load(uint8_t *elf, size_t file_size, uint64_t *entry_point, uint64_t *_slide, uint32_t alloc_type, bool kaslr, struct mem_range **ranges, uint64_t *ranges_count, uint64_t *physical_base, uint64_t *virtual_base, uint64_t *image_size, uint64_t *image_size_before_bss, bool *is_reloc);
 
 bool elf32_load_elsewhere(uint8_t *elf, size_t file_size, uint64_t *entry_point,
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 8cc17bdd..2e35209c 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -59,21 +59,11 @@ static enum executable_format detect_kernel_format(uint8_t *kernel, size_t kerne
 
 static int paging_mode;
 
-static uint64_t get_hhdm_span_top(int base_revision) {
-    uint64_t ret = base_revision >= 3 ? 0 : 0x100000000;
+static uint64_t get_hhdm_span_top(void) {
+    uint64_t ret = 0;
     for (size_t i = 0; i < memmap_entries; i++) {
-        if (((base_revision >= 1 && base_revision < 3) || base_revision >= 4) && (
-            memmap[i].type == MEMMAP_RESERVED
-         || memmap[i].type == MEMMAP_BAD_MEMORY)) {
-            continue;
-        }
-
-        if (base_revision == 3 && (
-            memmap[i].type != MEMMAP_USABLE
-         && memmap[i].type != MEMMAP_BOOTLOADER_RECLAIMABLE
-         && memmap[i].type != MEMMAP_KERNEL_AND_MODULES
-         && memmap[i].type != MEMMAP_FRAMEBUFFER
-         && memmap[i].type != MEMMAP_EFI_RECLAIMABLE)) {
+        if (memmap[i].type == MEMMAP_RESERVED
+         || memmap[i].type == MEMMAP_BAD_MEMORY) {
             continue;
         }
 
@@ -81,10 +71,6 @@ static uint64_t get_hhdm_span_top(int base_revision) {
         uint64_t length = memmap[i].length;
         uint64_t top = base + length;
 
-        if (base_revision < 3 && base < 0x100000000) {
-            base = 0x100000000;
-        }
-
         if (base >= top) {
             continue;
         }
@@ -158,8 +144,7 @@ static void limine_memcpy_to_64(uint64_t dst, void *src, size_t count) {
 }
 #endif
 
-static pagemap_t build_pagemap(int base_revision,
-                               bool nx, struct mem_range *ranges, size_t ranges_count,
+static pagemap_t build_pagemap(bool nx, struct mem_range *ranges, size_t ranges_count,
                                uint64_t physical_base, uint64_t virtual_base,
                                uint64_t direct_map_offset) {
     pagemap_t pagemap = new_pagemap(paging_mode);
@@ -185,16 +170,6 @@ static pagemap_t build_pagemap(int base_revision,
         map_pages(pagemap, virt, phys, pf, ranges[i].length);
     }
 
-    // Map 0x1000->4GiB range to identity if base revision == 0
-    if (base_revision == 0) {
-        map_pages(pagemap, 0x1000, 0x1000, VMM_FLAG_WRITE, 0x100000000 - 0x1000);
-    }
-
-    // Map 0->4GiB range to HHDM if base revision < 3
-    if (base_revision < 3) {
-        map_pages(pagemap, direct_map_offset, 0, VMM_FLAG_WRITE, 0x100000000);
-    }
-
     size_t _memmap_entries = memmap_entries;
     struct memmap_entry *_memmap =
         ext_mem_alloc(_memmap_entries * sizeof(struct memmap_entry));
@@ -203,18 +178,8 @@ static pagemap_t build_pagemap(int base_revision,
 
     // Map all free memory regions to the higher half direct map offset
     for (size_t i = 0; i < _memmap_entries; i++) {
-        if (((base_revision >= 1 && base_revision < 3) || base_revision >= 4) && (
-            _memmap[i].type == MEMMAP_RESERVED
-         || _memmap[i].type == MEMMAP_BAD_MEMORY)) {
-            continue;
-        }
-
-        if (base_revision == 3 && (
-            _memmap[i].type != MEMMAP_USABLE
-         && _memmap[i].type != MEMMAP_BOOTLOADER_RECLAIMABLE
-         && _memmap[i].type != MEMMAP_KERNEL_AND_MODULES
-         && _memmap[i].type != MEMMAP_FRAMEBUFFER
-         && _memmap[i].type != MEMMAP_EFI_RECLAIMABLE)) {
+        if (_memmap[i].type == MEMMAP_RESERVED
+         || _memmap[i].type == MEMMAP_BAD_MEMORY) {
             continue;
         }
 
@@ -222,10 +187,6 @@ static pagemap_t build_pagemap(int base_revision,
         uint64_t length = _memmap[i].length;
         uint64_t top    = base + length;
 
-        if (base_revision < 3 && base < 0x100000000) {
-            base = 0x100000000;
-        }
-
         if (base >= top) {
             continue;
         }
@@ -234,9 +195,6 @@ static pagemap_t build_pagemap(int base_revision,
         uint64_t aligned_top    = ALIGN_UP(top, 0x1000);
         uint64_t aligned_length = aligned_top - aligned_base;
 
-        if (base_revision == 0) {
-            map_pages(pagemap, aligned_base, aligned_base, VMM_FLAG_WRITE, aligned_length);
-        }
         map_pages(pagemap, direct_map_offset + aligned_base, aligned_base, VMM_FLAG_WRITE, aligned_length);
     }
 
@@ -254,17 +212,12 @@ static pagemap_t build_pagemap(int base_revision,
         uint64_t aligned_top    = ALIGN_UP(top, 0x1000);
         uint64_t aligned_length = aligned_top - aligned_base;
 
-        if (base_revision == 0) {
-            map_pages(pagemap, aligned_base, aligned_base, VMM_FLAG_WRITE | VMM_FLAG_FB, aligned_length);
-        }
         map_pages(pagemap, direct_map_offset + aligned_base, aligned_base, VMM_FLAG_WRITE | VMM_FLAG_FB, aligned_length);
     }
 
     // XXX we do this as a quick and dirty way to switch to the higher half
 #if defined (__x86_64__) || defined (__i386__)
-    if (base_revision >= 1) {
-        map_pages(pagemap, 0, 0, VMM_FLAG_WRITE, 0x100000000);
-    }
+    map_pages(pagemap, 0, 0, VMM_FLAG_WRITE, 0x100000000);
 #endif
 
     return pagemap;
@@ -546,12 +499,11 @@ noreturn void limine_load(char *config, char *cmdline) {
             }
             base_revision_found = true;
             base_revision = p[2];
-            if (p[2] <= SUPPORTED_BASE_REVISION) {
-                // Set to 0 to mean "supported"
-                base_rev_p2_ptr = &p[2];
-            } else {
-                base_revision = SUPPORTED_BASE_REVISION;
+            if (p[2] > SUPPORTED_BASE_REVISION) {
+                panic(true, "limine: Requested base revision %u is too new (maximum supported: %u)", (int)p[2], SUPPORTED_BASE_REVISION);
             }
+            // Set to 0 to mean "supported"
+            base_rev_p2_ptr = &p[2];
             base_rev_p1_ptr = &p[1];
         }
     }
@@ -562,62 +514,52 @@ noreturn void limine_load(char *config, char *cmdline) {
         *base_rev_p2_ptr = 0;
     }
 
-#if !defined (__x86_64__) && !defined (__i386__)
+#if defined (__x86_64__) || defined (__i386__)
+    if (base_revision < 4) {
+        panic(true, "limine: Base revision %u is no longer supported (minimum: 4)", base_revision);
+    }
+#else
     if (base_revision < 6) {
         panic(true, "limine: Base revision %u is no longer supported on this architecture (minimum: 6)", base_revision);
     }
 #endif
 
     // Load requests
-    uint64_t *limine_reqs = NULL;
     requests = ext_mem_alloc(MAX_REQUESTS * sizeof(void *));
     requests_count = 0;
-    if (base_revision == 0 && kernel_format == EXECUTABLE_FORMAT_ELF && elf64_load_section(kernel, kernel_file->size, &limine_reqs, ".limine_reqs", 0, slide)) {
-        for (size_t i = 0; ; i++) {
-            if (i >= MAX_REQUESTS) {
-                panic(true, "limine: Maximum requests exceeded");
-            }
-            if (limine_reqs[i] == 0) {
-                break;
-            }
-            requests[i] = (void *)(uintptr_t)((limine_reqs[i] - virtual_base) + physical_base);
-            requests_count++;
-        }
-    } else {
-        uint64_t common_magic[2] = { LIMINE_COMMON_MAGIC };
-        for (size_t i = 0; i < ALIGN_DOWN(image_size_before_bss, 8); i += 8) {
-            uint64_t *p = (void *)(uintptr_t)physical_base + i;
-
-            // Check if start marker hit
-            if (p[0] == limine_requests_start_marker[0] && p[1] == limine_requests_start_marker[1]
-             && p[2] == limine_requests_start_marker[2] && p[3] == limine_requests_start_marker[3]) {
-                requests_count = 0;
-                continue;
-            }
+    uint64_t common_magic[2] = { LIMINE_COMMON_MAGIC };
+    for (size_t i = 0; i < ALIGN_DOWN(image_size_before_bss, 8); i += 8) {
+        uint64_t *p = (void *)(uintptr_t)physical_base + i;
 
-            // Check if end marker hit
-            if (p[0] == limine_requests_end_marker[0] && p[1] == limine_requests_end_marker[1]) {
-                break;
-            }
+        // Check if start marker hit
+        if (p[0] == limine_requests_start_marker[0] && p[1] == limine_requests_start_marker[1]
+         && p[2] == limine_requests_start_marker[2] && p[3] == limine_requests_start_marker[3]) {
+            requests_count = 0;
+            continue;
+        }
 
-            if (p[0] != common_magic[0]) {
-                continue;
-            }
-            if (p[1] != common_magic[1]) {
-                continue;
-            }
+        // Check if end marker hit
+        if (p[0] == limine_requests_end_marker[0] && p[1] == limine_requests_end_marker[1]) {
+            break;
+        }
 
-            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 defined (__x86_64__) || defined (__i386__)
@@ -627,7 +569,7 @@ noreturn void limine_load(char *config, char *cmdline) {
     }
 #endif
 
-    uint64_t hhdm_span_top = get_hhdm_span_top(base_revision);
+    uint64_t hhdm_span_top = get_hhdm_span_top();
 
 #if defined (__x86_64__) || defined (__i386__)
     uint64_t maxphyaddr;
@@ -1041,7 +983,7 @@ FEAT_START
     struct limine_rsdp_response *rsdp_response =
         ext_mem_alloc(sizeof(struct limine_rsdp_response));
 
-    rsdp_response->address = (base_revision <= 2 || base_revision >= 4) ? reported_addr(rsdp) : (uintptr_t)rsdp;
+    rsdp_response->address = reported_addr(rsdp);
 
     rsdp_request->response = reported_addr(rsdp_response);
 FEAT_END
@@ -1063,10 +1005,10 @@ FEAT_START
         ext_mem_alloc(sizeof(struct limine_smbios_response));
 
     if (smbios_entry_32) {
-        smbios_response->entry_32 = (base_revision <= 2 || base_revision >= 5) ? reported_addr(smbios_entry_32) : (uintptr_t)smbios_entry_32;
+        smbios_response->entry_32 = (base_revision >= 5) ? reported_addr(smbios_entry_32) : (uintptr_t)smbios_entry_32;
     }
     if (smbios_entry_64) {
-        smbios_response->entry_64 = (base_revision <= 2 || base_revision >= 5) ? reported_addr(smbios_entry_64) : (uintptr_t)smbios_entry_64;
+        smbios_response->entry_64 = (base_revision >= 5) ? reported_addr(smbios_entry_64) : (uintptr_t)smbios_entry_64;
     }
 
     smbios_request->response = reported_addr(smbios_response);
@@ -1083,7 +1025,7 @@ FEAT_START
     struct limine_efi_system_table_response *est_response =
         ext_mem_alloc(sizeof(struct limine_efi_system_table_response));
 
-    est_response->address = (base_revision <= 2 || base_revision >= 5) ? reported_addr(gST) : (uintptr_t)gST;
+    est_response->address = (base_revision >= 5) ? reported_addr(gST) : (uintptr_t)gST;
 
     est_request->response = reported_addr(est_response);
 FEAT_END
@@ -1615,24 +1557,17 @@ FEAT_START
 FEAT_END
 #endif
 
-    if (base_revision < 3) {
-        pmm_sanitiser_keep_first_page = false;
-        pmm_sanitise_entries(memmap, &memmap_entries, true);
-    }
-
-    if (base_revision >= 4) {
-        acpi_map_tables();
-        if (base_revision >= 5) {
-            smbios_map_tables();
+    acpi_map_tables();
+    if (base_revision >= 5) {
+        smbios_map_tables();
 #if defined (UEFI)
-            efi_map_runtime_entries();
+        efi_map_runtime_entries();
 #endif
-        }
-        pmm_sanitise_entries(memmap, &memmap_entries, true);
     }
+    pmm_sanitise_entries(memmap, &memmap_entries, true);
 
     pagemap_t pagemap = {0};
-    pagemap = build_pagemap(base_revision, nx_available, ranges, ranges_count,
+    pagemap = build_pagemap(nx_available, ranges, ranges_count,
                             physical_base, virtual_base, direct_map_offset);
 
 #if defined (__aarch64__)
@@ -1851,13 +1786,12 @@ FEAT_END
 
     uint64_t reported_stack = reported_addr(stack);
 
-    common_spinup(limine_spinup_32, 11,
+    common_spinup(limine_spinup_32, 10,
         paging_mode, (uint32_t)(uintptr_t)pagemap.top_level,
         (uint32_t)entry_point, (uint32_t)(entry_point >> 32),
         (uint32_t)reported_stack, (uint32_t)(reported_stack >> 32),
         (uint32_t)(uintptr_t)local_gdt, nx_available,
-        (uint32_t)direct_map_offset, (uint32_t)(direct_map_offset >> 32),
-        (uint32_t)base_revision
+        (uint32_t)direct_map_offset, (uint32_t)(direct_map_offset >> 32)
     );
 #elif defined (__aarch64__)
     vmm_assert_4k_pages();
diff --git a/common/protos/limine_32.asm_x86 b/common/protos/limine_32.asm_x86
index 75819e4b..79b6b424 100644
--- a/common/protos/limine_32.asm_x86
+++ b/common/protos/limine_32.asm_x86
@@ -90,9 +90,6 @@ bits 64
     retq
   .hh:
 
-    cmp dword [rsp+44], 1
-    jb .no_unmap_lower_half
-
     ; Unmap lower half entirely
     mov rsi, cr3
     lea rdi, [rsi + rax]
@@ -101,8 +98,6 @@ bits 64
     rep stosq
     mov cr3, rsi
 
-  .no_unmap_lower_half:
-
     ; Push fake return address
     mov rsi, [rsp+20] ; stack
     sub rsi, 8
tab: 248 wrap: offon