Revert "limine: Initial support for non-ELF executables"
This reverts commit 4240256074
.
This commit is contained in:
parent
5f525a1052
commit
790a1303f8
64
PROTOCOL.md
64
PROTOCOL.md
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
31
limine.h
31
limine.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue