Revert "limine: Initial support for non-ELF executables"

This reverts commit 4240256074.
This commit is contained in:
mintsuki 2022-04-02 10:10:38 +02:00
parent 5f525a1052
commit 790a1303f8
3 changed files with 16 additions and 210 deletions

View File

@ -21,14 +21,6 @@ higher half direct map offset already added to them, unless otherwise noted.
The calling convention matches the SysV C ABI for the specific architecture. The calling convention matches the SysV C ABI for the specific architecture.
### Executable formats
The Limine protocol does not enforce any specific executable format, but
kernels using formats not supported by the bootloader, or using flat binaries,
*must* provide a Executable Layout Feature (see below).
Compliant bootloaders must support at least the ELF 64-bit executable format.
## Features ## Features
The protocol is centered around the concept of request/response - collectively The protocol is centered around the concept of request/response - collectively
@ -81,7 +73,7 @@ revisions do.
This is all there is to features. For a list of official Limine features, read This is all there is to features. For a list of official Limine features, read
the "Feature List" section below. the "Feature List" section below.
## Entry memory layout ## Executable memory layout
The protocol mandates kernels to load themselves at or above The protocol mandates kernels to load themselves at or above
`0xffffffff80000000`. Lower half kernels are *not supported*. `0xffffffff80000000`. Lower half kernels are *not supported*.
@ -218,60 +210,6 @@ struct limine_stack_size_response {
}; };
``` ```
### Executable Layout Feature
ID:
```c
#define LIMINE_EXECUTABLE_LAYOUT_REQUEST { LIMINE_COMMON_MAGIC, 0xbbd4597377e1fdbb, 0x17540007cfa435ad }
```
Request:
```c
typedef void (*limine_entry_point)(void);
struct limine_executable_layout_request {
uint64_t id[4];
uint64_t revision;
struct limine_executable_layout_response *response;
limine_entry_point entry_point;
uint64_t alignment;
uint64_t text_offset;
uint64_t text_address;
uint64_t text_size;
uint64_t data_offset;
uint64_t data_address;
uint64_t data_size;
uint64_t rodata_offset;
uint64_t rodata_address;
uint64_t rodata_size;
uint64_t bss_address;
uint64_t bss_size;
};
```
* `entry_point` - The virtual address of the entry point of the kernel. It is
equivalent to an entry point specified in an executable format, and thus it can
be overridden by the Entry Point Feature.
* `alignment` - The requested alignment for the physical base address of the
kernel. It *must* be a power of 2. An alignment of 0 means 4096.
* `{text,data,rodata}_offset` - The offset within the file where the segment
begins.
* `{text,data,rodata,bss}_address` - The virtual address to which to load the
segment to.
* `{text,data,rodata,bss}_size` - The size of the segment both in the file and
in memory, except for bss, where it is only the in-memory size.
Response:
```c
struct limine_executable_layout_response {
uint64_t revision;
};
```
Notes: This request is parsed if the bootloader does not support the executable
format of the kernel. It is otherwise ignored. If it is parsed and used for
loading the kernel, then the response will be set to a vaild pointer.
### HHDM (Higher Half Direct Map) Feature ### HHDM (Higher Half Direct Map) Feature
ID: ID:

View File

@ -137,6 +137,12 @@ bool limine_load(char *config, char *cmdline) {
int bits = elf_bits(kernel); int bits = elf_bits(kernel);
if (bits == -1 || bits == 32) {
printv("limine: Kernel in unrecognised format");
return false;
}
// ELF loading
uint64_t entry_point = 0; uint64_t entry_point = 0;
struct elf_range *ranges; struct elf_range *ranges;
uint64_t ranges_count; uint64_t ranges_count;
@ -144,99 +150,6 @@ bool limine_load(char *config, char *cmdline) {
uint64_t image_size; uint64_t image_size;
bool is_reloc; bool is_reloc;
bool flat = false;
if (bits == -1 || bits == 32) {
struct limine_executable_layout_request *exec_layout = NULL;
uint64_t exec_layout_id[4] = LIMINE_EXECUTABLE_LAYOUT_REQUEST;
for (size_t i = 0; i < ALIGN_DOWN(kernel_file->size, 8); i += 8) {
uint64_t *p = (void *)(uintptr_t)kernel + i;
if (p[0] != exec_layout_id[0]) {
continue;
}
if (p[1] != exec_layout_id[1]) {
continue;
}
if (p[2] != exec_layout_id[2]) {
continue;
}
if (p[3] != exec_layout_id[3]) {
continue;
}
exec_layout = (void *)p;
break;
}
if (exec_layout == NULL) {
printv("limine: Kernel in unrecognised format\n");
return false;
}
entry_point = exec_layout->entry_point;
if (exec_layout->text_address % 4096
|| exec_layout->data_address % 4096
|| exec_layout->rodata_address % 4096
|| exec_layout->bss_address % 4096) {
panic(true, "limine: Address of an executable segment is not page aligned");
}
ranges_count = 4;
ranges = ext_mem_alloc(sizeof(struct elf_range) * ranges_count);
ranges[0].base = exec_layout->text_address;
ranges[0].length = exec_layout->text_size;
ranges[0].permissions = ELF_PF_X | ELF_PF_R;
ranges[1].base = exec_layout->data_address;
ranges[1].length = exec_layout->data_size;
ranges[1].permissions = ELF_PF_R | ELF_PF_W;
ranges[2].base = exec_layout->rodata_address;
ranges[2].length = exec_layout->rodata_size;
ranges[2].permissions = ELF_PF_R;
ranges[3].base = exec_layout->bss_address;
ranges[3].length = exec_layout->bss_size;
ranges[3].permissions = ELF_PF_R | ELF_PF_W;
uint64_t min_addr = (uint64_t)-1;
uint64_t max_addr = 0;
for (size_t i = 0; i < ranges_count; i++) {
if (ranges[i].base < min_addr) {
min_addr = ranges[i].base;
}
if (ranges[i].base + ranges[i].length > max_addr) {
max_addr = ranges[i].base + ranges[i].length;
}
}
image_size = max_addr - min_addr;
is_reloc = false;
slide = 0;
virtual_base = min_addr;
void *image = ext_mem_alloc_type_aligned(image_size,
MEMMAP_KERNEL_AND_MODULES, exec_layout->alignment ?: 4096);
physical_base = (uintptr_t)image;
memcpy(image + (exec_layout->text_address - min_addr),
kernel + exec_layout->text_offset, exec_layout->text_size);
memcpy(image + (exec_layout->data_address - min_addr),
kernel + exec_layout->data_offset, exec_layout->data_size);
memcpy(image + (exec_layout->rodata_address - min_addr),
kernel + exec_layout->rodata_offset, exec_layout->rodata_size);
memset(image + (exec_layout->bss_address - min_addr), 0, exec_layout->bss_size);
flat = true;
} else {
// ELF loading
if (elf64_load(kernel, &entry_point, NULL, &slide, if (elf64_load(kernel, &entry_point, NULL, &slide,
MEMMAP_KERNEL_AND_MODULES, kaslr, false, MEMMAP_KERNEL_AND_MODULES, kaslr, false,
&ranges, &ranges_count, &ranges, &ranges_count,
@ -244,7 +157,6 @@ bool limine_load(char *config, char *cmdline) {
&is_reloc)) { &is_reloc)) {
return false; return false;
} }
}
kaslr = is_reloc; kaslr = is_reloc;
@ -328,7 +240,7 @@ FEAT_START
entry_point = entrypoint_request->entry; entry_point = entrypoint_request->entry;
printv("limine: Entry point at %X\n", entry_point); print("limine: Entry point at %X\n", entry_point);
struct limine_entry_point_response *entrypoint_response = struct limine_entry_point_response *entrypoint_response =
ext_mem_alloc(sizeof(struct limine_entry_point_response)); ext_mem_alloc(sizeof(struct limine_entry_point_response));
@ -336,23 +248,6 @@ FEAT_START
entrypoint_request->response = reported_addr(entrypoint_response); entrypoint_request->response = reported_addr(entrypoint_response);
FEAT_END FEAT_END
// Executable layout feature
FEAT_START
if (!flat) {
break;
}
struct limine_executable_layout_request *exec_layout_request = get_request(LIMINE_EXECUTABLE_LAYOUT_REQUEST);
if (exec_layout_request == NULL) {
panic(true, "limine: How did this even happen?");
}
struct limine_executable_layout_response *exec_layout_response =
ext_mem_alloc(sizeof(struct limine_executable_layout_response));
exec_layout_request->response = reported_addr(exec_layout_response);
FEAT_END
// Bootloader info feature // Bootloader info feature
FEAT_START FEAT_START
struct limine_bootloader_info_request *bootloader_info_request = get_request(LIMINE_BOOTLOADER_INFO_REQUEST); struct limine_bootloader_info_request *bootloader_info_request = get_request(LIMINE_BOOTLOADER_INFO_REQUEST);

View File

@ -40,8 +40,6 @@ struct limine_file {
struct limine_uuid part_uuid; struct limine_uuid part_uuid;
}; };
typedef void (*limine_entry_point)(void);
/* Boot info */ /* Boot info */
#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } #define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 }
@ -73,33 +71,6 @@ struct limine_stack_size_request {
uint64_t stack_size; uint64_t stack_size;
}; };
/* Executable layout */
#define LIMINE_EXECUTABLE_LAYOUT_REQUEST { LIMINE_COMMON_MAGIC, 0xbbd4597377e1fdbb, 0x17540007cfa435ad }
struct limine_executable_layout_response {
uint64_t revision;
};
struct limine_executable_layout_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_executable_layout_response *) response;
LIMINE_PTR(limine_entry_point) entry_point;
uint64_t alignment;
uint64_t text_offset;
uint64_t text_address;
uint64_t text_size;
uint64_t data_offset;
uint64_t data_address;
uint64_t data_size;
uint64_t rodata_offset;
uint64_t rodata_address;
uint64_t rodata_size;
uint64_t bss_address;
uint64_t bss_size;
};
/* HHDM */ /* HHDM */
#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } #define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
@ -276,6 +247,8 @@ struct limine_memmap_request {
#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } #define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a }
typedef void (*limine_entry_point)(void);
struct limine_entry_point_response { struct limine_entry_point_response {
uint64_t revision; uint64_t revision;
}; };