Skip to content

Commit

Permalink
protos/limine: Require and use a requests segment for base rev 3
Browse files Browse the repository at this point in the history
  • Loading branch information
mintsuki committed Oct 26, 2024
1 parent a96daf1 commit 937ce5f
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 51 deletions.
39 changes: 0 additions & 39 deletions common/lib/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,45 +75,6 @@
#define EI_VERSION 6
#define EI_OSABI 7

struct elf32_hdr {
uint8_t ident[16];
uint16_t type;
uint16_t machine;
uint32_t version;
uint32_t entry;
uint32_t phoff;
uint32_t shoff;
uint32_t flags;
uint16_t hdr_size;
uint16_t phdr_size;
uint16_t ph_num;
uint16_t shdr_size;
uint16_t sh_num;
uint16_t shstrndx;
};

struct elf64_phdr {
uint32_t p_type;
uint32_t p_flags;
uint64_t p_offset;
uint64_t p_vaddr;
uint64_t p_paddr;
uint64_t p_filesz;
uint64_t p_memsz;
uint64_t p_align;
};

struct elf32_phdr {
uint32_t p_type;
uint32_t p_offset;
uint32_t p_vaddr;
uint32_t p_paddr;
uint32_t p_filesz;
uint32_t p_memsz;
uint32_t p_flags;
uint32_t p_align;
};

struct elf64_rela {
uint64_t r_addr;
uint32_t r_info;
Expand Down
39 changes: 39 additions & 0 deletions common/lib/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,45 @@ struct elf64_hdr {
uint16_t shstrndx;
};

struct elf32_hdr {
uint8_t ident[16];
uint16_t type;
uint16_t machine;
uint32_t version;
uint32_t entry;
uint32_t phoff;
uint32_t shoff;
uint32_t flags;
uint16_t hdr_size;
uint16_t phdr_size;
uint16_t ph_num;
uint16_t shdr_size;
uint16_t sh_num;
uint16_t shstrndx;
};

struct elf64_phdr {
uint32_t p_type;
uint32_t p_flags;
uint64_t p_offset;
uint64_t p_vaddr;
uint64_t p_paddr;
uint64_t p_filesz;
uint64_t p_memsz;
uint64_t p_align;
};

struct elf32_phdr {
uint32_t p_type;
uint32_t p_offset;
uint32_t p_vaddr;
uint32_t p_paddr;
uint32_t p_filesz;
uint32_t p_memsz;
uint32_t p_flags;
uint32_t p_align;
};

struct elf64_shdr {
uint32_t sh_name;
uint32_t sh_type;
Expand Down
53 changes: 52 additions & 1 deletion common/protos/limine.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,9 +480,59 @@ noreturn void limine_load(char *config, char *cmdline) {
}

// Load requests
uint64_t common_magic[2] = { LIMINE_COMMON_MAGIC };
uint64_t *limine_reqs = NULL;
requests = ext_mem_alloc(MAX_REQUESTS * sizeof(void *));
requests_count = 0;
if (base_revision >= 3) {
uint64_t reqs_start = 0, reqs_size = 0;

struct elf64_hdr *hdr = (void *)(uintptr_t)physical_base;

for (uint16_t i = 0; i < hdr->ph_num; i++) {
struct elf64_phdr *phdr = (void *)(uintptr_t)physical_base + (hdr->phoff + i * hdr->phdr_size);

if (phdr->p_type != 0x67e16835) {
continue;
}

reqs_start = physical_base + phdr->p_vaddr;
reqs_size = phdr->p_filesz;

printv("limine: Requests segment starts at %X and ends at %X\n", reqs_start, reqs_start + reqs_size);

break;
}

if (reqs_start == 0) {
panic(true, "limine: Base protocol revision 3 requires a requests segment");
}

for (size_t i = 0; i < ALIGN_DOWN(reqs_size, 8); i += 8) {
uint64_t *p = (void *)(uintptr_t)reqs_start + 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;
}

goto reqs_done;
}

if (base_revision == 0 && elf64_load_section(kernel, &limine_reqs, ".limine_reqs", 0, slide)) {
for (size_t i = 0; ; i++) {
if (limine_reqs[i] == 0) {
Expand All @@ -492,7 +542,6 @@ noreturn void limine_load(char *config, char *cmdline) {
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;

Expand Down Expand Up @@ -528,6 +577,8 @@ noreturn void limine_load(char *config, char *cmdline) {
}
}

reqs_done:;

#if defined (__x86_64__) || defined (__i386__)
// Check if 64 bit CPU
if (!cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx) || !(edx & (1 << 29))) {
Expand Down
6 changes: 0 additions & 6 deletions test/limine.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ static volatile LIMINE_BASE_REVISION(3);

static void limine_main(void);

__attribute__((used, section(".limine_requests_start_marker")))
static volatile LIMINE_REQUESTS_START_MARKER;

__attribute__((used, section(".limine_requests")))
static volatile struct limine_entry_point_request entry_point_request = {
.id = LIMINE_ENTRY_POINT_REQUEST,
Expand Down Expand Up @@ -152,9 +149,6 @@ static volatile struct limine_paging_mode_request _pm_request = {
.min_mode = LIMINE_PAGING_MODE_MIN
};

__attribute__((used, section(".limine_requests_end_marker")))
static volatile LIMINE_REQUESTS_END_MARKER;

static char *get_memmap_type(uint64_t type) {
switch (type) {
case LIMINE_MEMMAP_USABLE:
Expand Down
10 changes: 5 additions & 5 deletions test/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ PHDRS
text PT_LOAD FILEHDR PHDRS;
rodata PT_LOAD;
data PT_LOAD;
limine_requests 0x67e16835;
dynamic PT_DYNAMIC;
}

Expand All @@ -26,14 +27,13 @@ SECTIONS

.data : {
*(.data .data.*)

KEEP(*(.limine_requests_start_marker))
KEEP(*(.limine_requests))
KEEP(*(.limine_requests_end_marker))

*(.sdata .sdata.*)
} :data

.limine_requests : {
KEEP(*(.limine_requests))
} :data :limine_requests

.dynamic : {
*(.dynamic)
} :data :dynamic
Expand Down

0 comments on commit 937ce5f

Please sign in to comment.