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
