From da43c70a2d0c25af41bdd60e14e80c100a16fda7 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Thu, 5 Dec 2024 09:31:59 +0100 Subject: [PATCH] protos: Reduce or remove mentions of 'kernel' where unnecessary This also introduces limine.h API revision 2 --- CONFIG.md | 12 ++-- PROTOCOL.md | 141 +++++++++++++++++++------------------ common/common.mk | 2 +- common/menu.c | 1 + common/protos/limine.c | 54 +++++++------- common/protos/multiboot1.c | 14 ++-- common/protos/multiboot2.c | 16 +++-- limine.h | 52 ++++++++++++-- test/limine.c | 44 ++++++------ test/limine.conf | 4 +- test/linker.ld | 2 +- test/test.mk | 2 +- 12 files changed, 204 insertions(+), 140 deletions(-) diff --git a/CONFIG.md b/CONFIG.md index a8fa2721..64db789b 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -113,7 +113,7 @@ Editor control options: *Locally assignable (non protocol specific) options* are: * `comment` - An optional comment string that will be displayed by the bootloader on the menu when an entry is selected. -* `protocol` - The boot protocol that will be used to boot the kernel. Valid protocols are: `linux`, `limine`, `multiboot` (or `multiboot1`), `multiboot2`, `efi_chainload`, `bios_chainload`, and `chainload_next`. +* `protocol` - The boot protocol that will be used to boot the kernel/executable. Valid protocols are: `linux`, `limine`, `multiboot` (or `multiboot1`), `multiboot2`, `efi_chainload`, `bios_chainload`, and `chainload_next`. * `cmdline` - The command line string to be passed to the kernel/executable. Can be omitted. * `kernel_cmdline` - Alias of `cmdline`. @@ -127,11 +127,12 @@ Editor control options: * `dtb_path` - A device tree blob to pass instead of the one provided by the firmware. * Limine protocol: - * `kernel_path` - The path of the kernel. + * `path` - The path of the executable. + * `kernel_path` - Alias of `path`. * `module_path` - The path to a module. This option can be specified multiple times to specify multiple modules. * `module_cmdline` - A command line to be passed to a module. This option can also be specified multiple times. It applies to the module described by the last module option specified. * `resolution` - The resolution to be used. This setting takes the form of `xx`. If the resolution is not available, Limine will pick another one automatically. Omitting `` will default to 32. - * `kaslr` - For relocatable kernels, if set to `no`, disable kernel address space layout randomisation. KASLR is enabled by default. + * `kaslr` - For relocatable executables, if set to `no`, disable kernel address space layout randomisation. KASLR is enabled by default. * `randomise_hhdm_base` - If set to `yes`, randomise the base address of the higher half direct map. If set to `no`, do not. By default it is `yes` if KASLR is supported and enabled, else it is `no`. * `randomize_hhdm_base` - Alias of `randomise_hhdm_base`. * `max_paging_mode`, `min_paging_mode` - Limit the maximum and minimum paging modes to one of the following: @@ -142,10 +143,11 @@ Editor control options: * `dtb_path` - A device tree blob to pass instead of the one provided by the firmware. * multiboot1 and multiboot2 protocols: - * `kernel_path` - The path of the kernel. + * `path` - The path of the executable. + * `kernel_path` - Alias of `path`. * `module_path` - The path to a module. This option can be specified multiple times to specify multiple modules. * `module_string` - A string to be passed to a module. This option can also be specified multiple times. It applies to the module described by the last module option specified. - * `resolution` - The resolution to be used should the kernel request a graphical framebuffer. This setting takes the form of `xx` and *overrides* any resolution requested by the kernel. If the resolution is not available, Limine will pick another one automatically. Omitting `` will default to 32. + * `resolution` - The resolution to be used should the executable request a graphical framebuffer. This setting takes the form of `xx` and *overrides* any resolution requested by the executable. If the resolution is not available, Limine will pick another one automatically. Omitting `` will default to 32. * `textmode` - If set to `yes`, prefer text mode. (BIOS only) * EFI Chainload protocol: diff --git a/PROTOCOL.md b/PROTOCOL.md index b3d50e04..bed3b7ac 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -14,6 +14,9 @@ languages. ## General Notes +The "executable" is the kernel or otherwise the freestanding application being loaded +by the Limine boot protocol. + All pointers are 64-bit wide. All non-NULL pointers point to the object with the higher half direct map offset already added to them, unless otherwise noted. @@ -33,10 +36,10 @@ outside any specific feature. The specifics are going to be described as needed throughout this specification. Base revision 0 through 2 are considered deprecated. Base revision 0 is the default base revision -a kernel is assumed to be requesting and complying to if no base revision tag -is provided by the kernel, for backwards compatibility. +an executable is assumed to be requesting and complying to if no base revision tag +is provided by the executable, for backwards compatibility. -A base revision tag is a set of 3 64-bit values placed somewhere in the loaded kernel +A base revision tag is a set of 3 64-bit values placed somewhere in the loaded executable image on an 8-byte aligned boundary; the first 2 values are a magic number for the bootloader to be able to identify the tag, and the last value is the requested base revision number. Lack of base revision tag implies revision 0. @@ -47,29 +50,29 @@ requested base revision number. Lack of base revision tag implies revision 0. ``` If a bootloader drops support for an older base revision, the bootloader must -fail to boot a kernel requesting such base revision. If a bootloader does not yet +fail to boot an executable requesting such base revision. If a bootloader does not yet support a requested base revision (i.e. if the requested base revision is higher -than the maximum base revision supported), it must boot the kernel using any -arbitrary revision it supports, and communicate failure to comply to the kernel by +than the maximum base revision supported), it must boot the executable using any +arbitrary revision it supports, and communicate failure to comply to the executable by *leaving the 3rd component of the base revision tag unchanged*. -On the other hand, if the kernel's requested base revision is supported, +On the other hand, if the executable's requested base revision is supported, *the 3rd component of the base revision tag must be set to 0 by the bootloader*. Note: this means that unlike when the bootloader drops support for an older base -revision and *it* is responsible for failing to boot the kernel, in case the -bootloader does not yet support the kernel's requested base revision, -it is up to the kernel itself to fail (or handle the condition otherwise). +revision and *it* is responsible for failing to boot the executable, in case the +bootloader does not yet support the executable's requested base revision, +it is up to the executable itself to fail (or handle the condition otherwise). For any Limine-compliant bootloader supporting base revision 3, it is *mandatory* -to load kernels requesting higher unsupported base revisions with at least +to load executables requesting higher unsupported base revisions with at least base revision 3, and it is mandatory for it to always set the 2nd component of -the base revision tag to the base revision actually used to load the kernel, +the base revision tag to the base revision actually used to load the executable, regardless of whether it was the requested one or not. ## Features The protocol is centered around the concept of request/response - collectively -named "features" - where the kernel requests some action or information from +named "features" - where the executable requests some action or information from the bootloader, and the bootloader responds accordingly, if it is capable of doing so. @@ -91,7 +94,7 @@ aligned. There may only be 1 of the same request. The bootloader will refuse to boot an executable with multiple of the same request IDs. Alternatively, it is possible to provide a list of requests explicitly via an executable file section. See "Limine Requests Section". (Note: this is deprecated and removed in base revision 1) -* `revision` - The revision of the request that the kernel provides. This starts at 0 and is +* `revision` - The revision of the request that the executable provides. This starts at 0 and is bumped whenever new members or functionality are added to the request structure. Bootloaders process requests in a backwards compatible manner, *always*. This means that if the bootloader does not support the revision of the request, @@ -149,28 +152,28 @@ rather than them just being a hint. Note: *This behaviour is deprecated and removed as of base protocol revision 1* -For kernels requesting deprecated base revision 0, -if the executable kernel file contains a `.limine_reqs` section, the bootloader +For executables requesting deprecated base revision 0, +if the executable executable file contains a `.limine_reqs` section, the bootloader will, instead of scanning the executable for requests, fetch the requests from a NULL-terminated array of pointers to the provided requests, contained inside said section. ## Entry memory layout -The protocol mandates kernels to load themselves at or above -`0xffffffff80000000`. Lower half kernels are *not supported*. For relocatable kernels +The protocol mandates executables to load themselves at or above +`0xffffffff80000000`. Lower half executables are *not supported*. For relocatable executables asking to be loaded at address 0, a minimum slide of `0xffffffff80000000` is applied. -At handoff, the kernel will be properly loaded and mapped with appropriate +At handoff, the executable will be properly loaded and mapped with appropriate MMU permissions, as supervisor, at the requested virtual memory address (provided it is at or above `0xffffffff80000000`). -No specific physical memory placement is guaranteed, except that the loaded kernel image +No specific physical memory placement is guaranteed, except that the loaded executable image is guaranteed to be physically contiguous. In order to determine -where the kernel is loaded in physical memory, see the Kernel Address feature +where the executable is loaded in physical memory, see the Executable Address feature below. -Alongside the loaded kernel, the bootloader will set up memory mappings as such: +Alongside the loaded executable, the bootloader will set up memory mappings as such: ``` Base Physical Address | | Base Virtual Address @@ -197,7 +200,7 @@ of types: For base revision 3, the only memory map regions mapped to the HHDM are: - Usable - Bootloader reclaimable - - Kernel and modules + - Executable and modules - Framebuffer For base revision 3, the unconditional direct map of the first 4GiB is dropped, and @@ -207,7 +210,7 @@ The bootloader page tables are in bootloader-reclaimable memory (see Memory Map feature below), and their specific layout is undefined as long as they provide the above memory mappings. -If the kernel is a position independent executable, the bootloader is free to +If the executable is a position independent executable, the bootloader is free to relocate it as it sees fit, potentially performing KASLR (as specified by the config). @@ -215,7 +218,7 @@ config). ### x86-64 -The kernel executable, loaded at or above `0xffffffff80000000`, sees all of its +The executable, loaded at or above `0xffffffff80000000`, sees all of its segments mapped using write-back (WB) caching at the page tables level. All HHDM and identity map memory regions are mapped using write-back (WB) caching at the page @@ -238,7 +241,7 @@ The MTRRs are left as the firmware set them up. ### aarch64 -The kernel executable, loaded at or above `0xffffffff80000000`, sees all of its +The executable, loaded at or above `0xffffffff80000000`, sees all of its segments mapped using Normal Write-Back RW-Allocate non-transient caching mode. All HHDM and identity map memory regions are mapped using the Normal Write-Back RW-Allocate @@ -249,13 +252,13 @@ framebuffer on the platform. The `MAIR_EL1` register will at least contain entries for the above-mentioned caching modes, in an unspecified order. -In order to access MMIO regions, the kernel must ensure the correct caching mode +In order to access MMIO regions, the executable must ensure the correct caching mode is used on its own. ### riscv64 If the `Svpbmt` extension is available, all framebuffer memory regions are mapped -with `PBMT=NC` to enable write-combining optimizations. The kernel executable, +with `PBMT=NC` to enable write-combining optimizations. The executable, loaded at or above `0xffffffff80000000`, and all HHDM and identity map memory regions are mapped with the default `PBMT=PMA`. @@ -264,7 +267,7 @@ everything is mapped with `PBMT=PMA`). ### loongarch64 -The kernel executable, loaded at or above `0xffffffff80000000`, sees all of its +The executable, loaded at or above `0xffffffff80000000`, sees all of its segments mapped using the Coherent Cached (CC) memory access type (MAT). All HHDM and identity map memory regions are mapped using the Coherent Cached (CC) @@ -293,7 +296,7 @@ with at least the following entries, starting at offset 0: - 64-bit code descriptor. Base and limit irrelevant. Readable. - 64-bit data descriptor. Base and limit irrelevant. Writable. -The IDT is in an undefined state. Kernel must load its own. +The IDT is in an undefined state. Executable must load its own. IF flag, VM flag, and direction flag are cleared on entry. Other flags undefined. @@ -313,7 +316,7 @@ If booted by EFI/UEFI, boot services are exited. `rsp` is set to point to a stack, in bootloader-reclaimable memory, which is at least 64KiB (65536 bytes) in size, or the size specified in the Stack Size Request (see below). An invalid return address of 0 is pushed -to the stack before jumping to the kernel. +to the stack before jumping to the executable. All other general purpose registers are set to 0. @@ -323,14 +326,14 @@ All other general purpose registers are set to 0. unless the Entry Point feature is requested (see below), in which case, the value of `PC` is going to be taken from there. -The contents of the `VBAR_EL1` register are undefined, and the kernel must load +The contents of the `VBAR_EL1` register are undefined, and the executable must load its own. The `MAIR_EL1` register contents are described above, in the caching section. All interrupts are masked (`PSTATE.{D, A, I, F}` are set to 1). -The kernel is entered in little-endian AArch64 EL1t (EL1 with `PSTATE.SP` set to +The executable is entered in little-endian AArch64 EL1t (EL1 with `PSTATE.SP` set to 0, `PSTATE.E` set to 0, and `PSTATE.nRW` set to 0). Other fields of `PSTATE` are undefined. @@ -353,7 +356,7 @@ paging. Additionally, for 5-level paging, `TCR_EL1.DS` is set to 1. `TTBR1_EL1` points to the bootloader-provided higher half page tables. For base revision 0, `TTBR0_EL1` points to the bootloader-provided identity mapping page tables, and is unspecified for all other base revisions and can -thus be freely used by the kernel. +thus be freely used by the executable. If booted by EFI/UEFI, boot services are exited. @@ -372,13 +375,13 @@ At entry the machine is executing in Supervisor mode. unless the Entry Point feature is requested (see below), in which case, the value of `pc` is going to be taken from there. -`x1`(`ra`) is set to 0, the kernel must not return from the entry point. +`x1`(`ra`) is set to 0, the executable must not return from the entry point. `x2`(`sp`) is set to point to a stack, in bootloader-reclaimable memory, which is at least 64KiB (65536 bytes) in size, or the size specified in the Stack Size Request (see below). -`x3`(`gp`) is set to 0, kernel must load its own global pointer if needed. +`x3`(`gp`) is set to 0, executable must load its own global pointer if needed. All other general purpose registers, with the exception of `x5`(`t0`), are set to 0. @@ -400,7 +403,7 @@ At entry the machine is executing in PLV0. unless the Entry Point feature is requested (see below), in which case, the value of `$pc` is going to be taken from there. -`$r1`(`$ra`) is set to 0, the kernel must not return from the entry point. +`$r1`(`$ra`) is set to 0, the executable must not return from the entry point. `$r3`(`$sp`) is set to point to a stack, in bootloader-reclaimable memory, which is at least 64KiB (65536 bytes) in size, or the size specified in the Stack @@ -616,7 +619,7 @@ struct limine_video_mode { ### Paging Mode Feature -The Paging Mode feature allows the kernel to control which paging mode is enabled +The Paging Mode feature allows the executable to control which paging mode is enabled before control is passed to it. ID: @@ -669,7 +672,7 @@ struct limine_paging_mode_response { ``` The response indicates which paging mode was actually enabled by the bootloader. -Kernels must be prepared to handle cases where the provided paging mode is +Executables must be prepared to handle cases where the provided paging mode is not supported. #### x86-64 @@ -946,7 +949,7 @@ struct limine_memmap_response { #define LIMINE_MEMMAP_ACPI_NVS 3 #define LIMINE_MEMMAP_BAD_MEMORY 4 #define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 -#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#define LIMINE_MEMMAP_EXECUTABLE_AND_MODULES 6 #define LIMINE_MEMMAP_FRAMEBUFFER 7 struct limine_memmap_entry { @@ -956,19 +959,23 @@ struct limine_memmap_entry { }; ``` -Note: All these memory entry types, besides usable and bootloader reclaimable, +All these memory entry types, besides usable and bootloader reclaimable, are meant to have an illustrative purpose only, and are not authoritative sources -to be used as a means to find the addresses of kernel, modules, framebuffer, ACPI, +to be used as a means to find the addresses of the executable, modules, framebuffer, ACPI, or otherwise. Use the specific Limine features to do that, if available, or other discovery means. -Note: For base revisions <= 2, memory between 0 and 0x1000 is never marked as usable memory. -The kernel and modules loaded are not marked as usable memory. -They are marked as Kernel/Modules. The entries are guaranteed to be sorted by -base address, lowest to highest. Usable and bootloader reclaimable entries -are guaranteed to be 4096 byte aligned for both base and length. Usable and -bootloader reclaimable entries are guaranteed not to overlap with any other -entry. To the contrary, all non-usable entries (including kernel/modules) are +For base revisions <= 2, memory between 0 and 0x1000 is never marked as usable memory. + +The executable and modules loaded are not marked as usable memory, but as Executable/Modules. + +The entries are guaranteed to be sorted by base address, lowest to highest. + +Usable and bootloader reclaimable entries are guaranteed to be 4096 byte aligned for +both base and length. + +Usable and bootloader reclaimable entries are guaranteed not to overlap with any other +entry. To the contrary, all non-usable entries (including executable/modules) are not guaranteed any alignment, nor is it guaranteed that they do not overlap other entries. @@ -1000,32 +1007,32 @@ struct limine_entry_point_response { }; ``` -### Kernel File Feature +### Executable File Feature ID: ```c -#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } +#define LIMINE_EXECUTABLE_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } ``` Request: ```c -struct limine_kernel_file_request { +struct limine_executable_file_request { uint64_t id[4]; uint64_t revision; - struct limine_kernel_file_response *response; + struct limine_executable_file_response *response; }; ``` Response: ```c -struct limine_kernel_file_response { +struct limine_executable_file_response { uint64_t revision; - struct limine_file *kernel_file; + struct limine_file *executable_file; }; ``` -* `kernel_file` - Pointer to the `struct limine_file` structure (see below) -for the kernel file. +* `executable_file` - Pointer to the `struct limine_file` structure (see below) +for the executable file. ### Module Feature @@ -1056,7 +1063,7 @@ struct limine_module_request { }; ``` -* `internal_module_count` - How many internal modules are passed by the kernel. +* `internal_module_count` - How many internal modules are passed by the executable. * `internal_modules` - Pointer to an array of `internal_module_count` pointers to `struct limine_internal_module` structures. @@ -1065,7 +1072,7 @@ Note: Internal modules are honoured if the module response has revision >= 1. As part of `struct limine_internal_module`: * `path` - Path to the module to load. This path is *relative* to the location of -the kernel. +the executable. * `cmdline` - Command line for the given module. * `flags` - Flags changing module loading behaviour: - `LIMINE_INTERNAL_MODULE_REQUIRED`: Fail if the requested module is not found. @@ -1281,33 +1288,33 @@ struct limine_boot_time_response { * `boot_time` - The UNIX time on boot, in seconds, taken from the system RTC. -### Kernel Address Feature +### Executable Address Feature ID: ```c -#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } +#define LIMINE_EXECUTABLE_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } ``` Request: ```c -struct limine_kernel_address_request { +struct limine_executable_address_request { uint64_t id[4]; uint64_t revision; - struct limine_kernel_address_response *response; + struct limine_executable_address_response *response; }; ``` Response: ```c -struct limine_kernel_address_response { +struct limine_executable_address_response { uint64_t revision; uint64_t physical_base; uint64_t virtual_base; }; ``` -* `physical_base` - The physical base address of the kernel. -* `virtual_base` - The virtual base address of the kernel. +* `physical_base` - The physical base address of the executable. +* `virtual_base` - The virtual base address of the executable. ### Device Tree Blob Feature @@ -1341,4 +1348,4 @@ Note: Information contained in the `/chosen` node may not reflect the informatio given by bootloader tags, and as such the `/chosen` node properties should be ignored. Note: If the DTB contained `memory@...` nodes, they will get removed. -Kernels may not rely on these nodes and should use the Memory Map feature instead. +Executables may not rely on these nodes and should use the Memory Map feature instead. diff --git a/common/common.mk b/common/common.mk index e0185c94..d6ad5f32 100644 --- a/common/common.mk +++ b/common/common.mk @@ -51,7 +51,7 @@ override CPPFLAGS_FOR_TARGET := \ $(CPPFLAGS_FOR_TARGET) \ -DCOM_OUTPUT=$(COM_OUTPUT) \ -DE9_OUTPUT=$(E9_OUTPUT) \ - -DLIMINE_API_REVISION=1 \ + -DLIMINE_API_REVISION=2 \ -MMD \ -MP diff --git a/common/menu.c b/common/menu.c index 8890040b..cce5a91d 100644 --- a/common/menu.c +++ b/common/menu.c @@ -97,6 +97,7 @@ static const char *VALID_KEYS[] = { "COMMENT", "PROTOCOL", "CMDLINE", + "PATH", "KERNEL_CMDLINE", "KERNEL_PATH", "INITRD_PATH", diff --git a/common/protos/limine.c b/common/protos/limine.c index 242e31a6..68c7b1d6 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -409,15 +409,19 @@ noreturn void limine_load(char *config, char *cmdline) { uint32_t eax, ebx, ecx, edx; #endif - char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); - if (kernel_path == NULL) - panic(true, "limine: KERNEL_PATH not specified"); + char *kernel_path = config_get_value(config, 0, "PATH"); + if (kernel_path == NULL) { + kernel_path = config_get_value(config, 0, "KERNEL_PATH"); + } + if (kernel_path == NULL) { + panic(true, "limine: Executable path not specified"); + } - print("limine: Loading kernel `%#`...\n", kernel_path); + print("limine: Loading executable `%#`...\n", kernel_path); struct file_handle *kernel_file; if ((kernel_file = uri_open(kernel_path)) == NULL) - panic(true, "limine: Failed to open kernel with path `%#`. Is the path correct?", kernel_path); + panic(true, "limine: Failed to open executable with path `%#`. Is the path correct?", kernel_path); char *k_path_copy = ext_mem_alloc(strlen(kernel_path) + 1); strcpy(k_path_copy, kernel_path); @@ -787,18 +791,18 @@ FEAT_START } if (kern_max_mode < kern_min_mode) { - panic(true, "limine: Kernel's paging max_mode lower than min_mode"); + panic(true, "limine: Executable's paging max_mode lower than min_mode"); } if (paging_mode > kern_max_mode) { if (kern_max_mode < min_supported_paging_mode) { - panic(true, "limine: Kernel's maximum supported paging mode lower than minimum allowable paging mode"); + panic(true, "limine: Executable's maximum supported paging mode lower than minimum allowable paging mode"); } paging_mode = kern_max_mode; } if (paging_mode < kern_min_mode) { if (kern_min_mode > max_supported_paging_mode) { - panic(true, "limine: Kernel's minimum supported paging mode higher than maximum allowable paging mode"); + panic(true, "limine: Executable's minimum supported paging mode higher than maximum allowable paging mode"); } paging_mode = kern_min_mode; } @@ -898,20 +902,20 @@ FEAT_START firmware_type_request->response = reported_addr(firmware_type_response); FEAT_END - // Kernel address feature + // Executable address feature FEAT_START - struct limine_kernel_address_request *kernel_address_request = get_request(LIMINE_KERNEL_ADDRESS_REQUEST); - if (kernel_address_request == NULL) { + struct limine_executable_address_request *executable_address_request = get_request(LIMINE_EXECUTABLE_ADDRESS_REQUEST); + if (executable_address_request == NULL) { break; // next feature } - struct limine_kernel_address_response *kernel_address_response = - ext_mem_alloc(sizeof(struct limine_kernel_address_response)); + struct limine_executable_address_response *executable_address_response = + ext_mem_alloc(sizeof(struct limine_executable_address_response)); - kernel_address_response->physical_base = physical_base; - kernel_address_response->virtual_base = virtual_base; + executable_address_response->physical_base = physical_base; + executable_address_response->virtual_base = virtual_base; - kernel_address_request->response = reported_addr(kernel_address_response); + executable_address_request->response = reported_addr(executable_address_response); FEAT_END // HHDM feature @@ -1019,7 +1023,7 @@ FEAT_START if (dtb) { // Delete all /memory@... nodes. - // The kernel must use the given UEFI memory map instead. + // The executable must use the given UEFI memory map instead. while (true) { int offset = fdt_subnode_offset_namelen(dtb, 0, "memory@", 7); @@ -1063,19 +1067,19 @@ FEAT_START stack_size_request->response = reported_addr(stack_size_response); FEAT_END - // Kernel file + // Executable file FEAT_START - struct limine_kernel_file_request *kernel_file_request = get_request(LIMINE_KERNEL_FILE_REQUEST); - if (kernel_file_request == NULL) { + struct limine_executable_file_request *executable_file_request = get_request(LIMINE_EXECUTABLE_FILE_REQUEST); + if (executable_file_request == NULL) { break; // next feature } - struct limine_kernel_file_response *kernel_file_response = - ext_mem_alloc(sizeof(struct limine_kernel_file_response)); + struct limine_executable_file_response *executable_file_response = + ext_mem_alloc(sizeof(struct limine_executable_file_response)); - kernel_file_response->kernel_file = reported_addr(kf); + executable_file_response->executable_file = reported_addr(kf); - kernel_file_request->response = reported_addr(kernel_file_response); + executable_file_request->response = reported_addr(executable_file_response); FEAT_END // Modules @@ -1533,7 +1537,7 @@ FEAT_START _memmap[i].type = LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE; break; case MEMMAP_KERNEL_AND_MODULES: - _memmap[i].type = LIMINE_MEMMAP_KERNEL_AND_MODULES; + _memmap[i].type = LIMINE_MEMMAP_EXECUTABLE_AND_MODULES; break; case MEMMAP_FRAMEBUFFER: _memmap[i].type = LIMINE_MEMMAP_FRAMEBUFFER; diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c index 36a276d2..69a5b628 100644 --- a/common/protos/multiboot1.c +++ b/common/protos/multiboot1.c @@ -51,14 +51,18 @@ static void *mb1_info_alloc(void **mb1_info_raw, size_t size) { noreturn void multiboot1_load(char *config, char *cmdline) { struct file_handle *kernel_file; - char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); - if (kernel_path == NULL) - panic(true, "multiboot1: KERNEL_PATH not specified"); + char *kernel_path = config_get_value(config, 0, "PATH"); + if (kernel_path == NULL) { + kernel_path = config_get_value(config, 0, "KERNEL_PATH"); + } + if (kernel_path == NULL) { + panic(true, "multiboot1: Executable path not specified"); + } - print("multiboot1: Loading kernel `%#`...\n", kernel_path); + print("multiboot1: Loading executable `%#`...\n", kernel_path); if ((kernel_file = uri_open(kernel_path)) == NULL) - panic(true, "multiboot1: Failed to open kernel with path `%#`. Is the path correct?", kernel_path); + panic(true, "multiboot1: Failed to open executable with path `%#`. Is the path correct?", kernel_path); uint8_t *kernel = freadall(kernel_file, MEMMAP_KERNEL_AND_MODULES); diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c index 0c0afe82..5f291878 100644 --- a/common/protos/multiboot2.c +++ b/common/protos/multiboot2.c @@ -71,14 +71,18 @@ static size_t get_multiboot2_info_size( noreturn void multiboot2_load(char *config, char* cmdline) { struct file_handle *kernel_file; - char *kernel_path = config_get_value(config, 0, "KERNEL_PATH"); - if (kernel_path == NULL) - panic(true, "multiboot2: KERNEL_PATH not specified"); + char *kernel_path = config_get_value(config, 0, "PATH"); + if (kernel_path == NULL) { + kernel_path = config_get_value(config, 0, "KERNEL_PATH"); + } + if (kernel_path == NULL) { + panic(true, "multiboot2: Executable path not specified"); + } - print("multiboot2: Loading kernel `%#`...\n", kernel_path); + print("multiboot2: Loading executable `%#`...\n", kernel_path); if ((kernel_file = uri_open(kernel_path)) == NULL) - panic(true, "multiboot2: Failed to open kernel with path `%#`. Is the path correct?", kernel_path); + panic(true, "multiboot2: Failed to open executable with path `%#`. Is the path correct?", kernel_path); uint8_t *kernel = freadall(kernel_file, MEMMAP_KERNEL_AND_MODULES); @@ -365,7 +369,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) { if (!check_usable_memory(ranges->target, ranges->target + ranges->length)) { reloc_fail: - panic(true, "multiboot2: Could not find viable load address for kernel"); + panic(true, "multiboot2: Could not find viable load address for executable"); } // Get the load base address (AKA the lowest target in the ranges) diff --git a/limine.h b/limine.h index 76ea3c43..a24777d7 100644 --- a/limine.h +++ b/limine.h @@ -35,7 +35,7 @@ extern "C" { # define LIMINE_API_REVISION 0 #endif -#if LIMINE_API_REVISION > 1 +#if LIMINE_API_REVISION > 2 # error "limine.h API revision unsupported" #endif @@ -444,7 +444,11 @@ struct LIMINE_MP(request) { #define LIMINE_MEMMAP_ACPI_NVS 3 #define LIMINE_MEMMAP_BAD_MEMORY 4 #define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 -#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#if LIMINE_API_REVISION >= 2 +# define LIMINE_MEMMAP_EXECUTABLE_AND_MODULES 6 +#else +# define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#endif #define LIMINE_MEMMAP_FRAMEBUFFER 7 struct limine_memmap_entry { @@ -482,19 +486,39 @@ struct limine_entry_point_request { LIMINE_PTR(limine_entry_point) entry; }; -/* Kernel File */ +/* Executable File */ -#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } +#if LIMINE_API_REVISION >= 2 +# define LIMINE_EXECUTABLE_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } +#else +# define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } +#endif +#if LIMINE_API_REVISION >= 2 +struct limine_executable_file_response { +#else struct limine_kernel_file_response { +#endif uint64_t revision; +#if LIMINE_API_REVISION >= 2 + LIMINE_PTR(struct limine_file *) executable_file; +#else LIMINE_PTR(struct limine_file *) kernel_file; +#endif }; +#if LIMINE_API_REVISION >= 2 +struct limine_executable_file_request { +#else struct limine_kernel_file_request { +#endif uint64_t id[4]; uint64_t revision; +#if LIMINE_API_REVISION >= 2 + LIMINE_PTR(struct limine_executable_file_response *) response; +#else LIMINE_PTR(struct limine_kernel_file_response *) response; +#endif }; /* Module */ @@ -618,20 +642,36 @@ struct limine_boot_time_request { LIMINE_PTR(struct limine_boot_time_response *) response; }; -/* Kernel address */ +/* Executable address */ -#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } +#if LIMINE_API_REVISION >= 2 +# define LIMINE_EXECUTABLE_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } +#else +# define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } +#endif +#if LIMINE_API_REVISION >= 2 +struct limine_executable_address_response { +#else struct limine_kernel_address_response { +#endif uint64_t revision; uint64_t physical_base; uint64_t virtual_base; }; +#if LIMINE_API_REVISION >= 2 +struct limine_executable_address_request { +#else struct limine_kernel_address_request { +#endif uint64_t id[4]; uint64_t revision; +#if LIMINE_API_REVISION >= 2 + LIMINE_PTR(struct limine_executable_address_response *) response; +#else LIMINE_PTR(struct limine_kernel_address_response *) response; +#endif }; /* Device Tree Blob */ diff --git a/test/limine.c b/test/limine.c index f4276203..362f2cf6 100644 --- a/test/limine.c +++ b/test/limine.c @@ -53,8 +53,8 @@ static volatile struct limine_memmap_request memmap_request = { }; __attribute__((section(".limine_requests"))) -static volatile struct limine_kernel_file_request kf_request = { - .id = LIMINE_KERNEL_FILE_REQUEST, +static volatile struct limine_executable_file_request exec_file_request = { + .id = LIMINE_EXECUTABLE_FILE_REQUEST, .revision = 0, .response = NULL }; @@ -119,8 +119,8 @@ static volatile struct limine_boot_time_request boot_time_request = { }; __attribute__((section(".limine_requests"))) -static volatile struct limine_kernel_address_request kernel_address_request = { - .id = LIMINE_KERNEL_ADDRESS_REQUEST, +static volatile struct limine_executable_address_request executable_address_request = { + .id = LIMINE_EXECUTABLE_ADDRESS_REQUEST, .revision = 0, .response = NULL }; @@ -177,8 +177,8 @@ static char *get_memmap_type(uint64_t type) { return "Bad memory"; case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE: return "Bootloader reclaimable"; - case LIMINE_MEMMAP_KERNEL_AND_MODULES: - return "Kernel and modules"; + case LIMINE_MEMMAP_EXECUTABLE_AND_MODULES: + return "Executable and modules"; case LIMINE_MEMMAP_FRAMEBUFFER: return "Framebuffer"; default: @@ -254,7 +254,7 @@ void ap_entry(struct limine_mp_info *info) { #define FEAT_START do { #define FEAT_END } while (0); -extern char kernel_start[]; +extern char executable_start[]; struct flanterm_context *ft_ctx = NULL; @@ -290,10 +290,10 @@ static void limine_main(void) { 0 ); - uint64_t kernel_slide = (uint64_t)kernel_start - 0xffffffff80000000; + uint64_t executable_slide = (uint64_t)executable_start - 0xffffffff80000000; - e9_printf("Kernel start: %x", kernel_start); - e9_printf("Kernel slide: %x", kernel_slide); + e9_printf("Executable start: %x", executable_start); + e9_printf("Executable slide: %x", executable_slide); FEAT_START e9_printf(""); @@ -320,14 +320,14 @@ FEAT_END FEAT_START e9_printf(""); - if (kernel_address_request.response == NULL) { - e9_printf("Kernel address not passed"); + if (executable_address_request.response == NULL) { + e9_printf("Executable address not passed"); break; } - struct limine_kernel_address_response *ka_response = kernel_address_request.response; - e9_printf("Kernel address feature, revision %d", ka_response->revision); - e9_printf("Physical base: %x", ka_response->physical_base); - e9_printf("Virtual base: %x", ka_response->virtual_base); + struct limine_executable_address_response *exec_addr_response = executable_address_request.response; + e9_printf("Executable address feature, revision %d", exec_addr_response->revision); + e9_printf("Physical base: %x", exec_addr_response->physical_base); + e9_printf("Virtual base: %x", exec_addr_response->virtual_base); FEAT_END FEAT_START @@ -390,13 +390,13 @@ FEAT_END FEAT_START e9_printf(""); - if (kf_request.response == NULL) { - e9_printf("Kernel file not passed"); + if (exec_file_request.response == NULL) { + e9_printf("Executable file not passed"); break; } - struct limine_kernel_file_response *kf_response = kf_request.response; - e9_printf("Kernel file feature, revision %d", kf_response->revision); - print_file(kf_response->kernel_file); + struct limine_executable_file_response *exec_file_response = exec_file_request.response; + e9_printf("Executable file feature, revision %d", exec_file_response->revision); + print_file(exec_file_response->executable_file); FEAT_END FEAT_START @@ -547,6 +547,7 @@ FEAT_START e9_printf(" mode: %d", pm_response->mode); FEAT_END +#if defined (__riscv) FEAT_START e9_printf(""); struct limine_riscv_bsp_hartid_response *bsp_response = _bsp_request.response; @@ -556,6 +557,7 @@ FEAT_START } e9_printf("RISC-V BSP Hart ID: %x", bsp_response->bsp_hartid); FEAT_END +#endif for (;;); } diff --git a/test/limine.conf b/test/limine.conf index 78d7d767..b73558f0 100644 --- a/test/limine.conf +++ b/test/limine.conf @@ -14,8 +14,8 @@ backdrop: 008080 protocol: limine kaslr: no - kernel_path: ${TEST_KERNEL} - kernel_cmdline: This is an example kernel command line. + path: ${TEST_KERNEL} + cmdline: This is an example command line. module_path: ${WALLPAPER_PATH} module_cmdline: This is the first module. diff --git a/test/linker.ld b/test/linker.ld index c75a9962..ac99b8de 100644 --- a/test/linker.ld +++ b/test/linker.ld @@ -10,7 +10,7 @@ PHDRS SECTIONS { . = SIZEOF_HEADERS; - kernel_start = . - SIZEOF_HEADERS; + executable_start = . - SIZEOF_HEADERS; .text : { *(.text .text.*) diff --git a/test/test.mk b/test/test.mk index 5e3a950f..87b2dfdc 100644 --- a/test/test.mk +++ b/test/test.mk @@ -61,7 +61,7 @@ override CFLAGS += \ -I../freestnd-c-hdrs-0bsd \ -I. \ -D_LIMINE_PROTO \ - -DLIMINE_API_REVISION=1 + -DLIMINE_API_REVISION=2 ifneq ($(findstring x86_64,$(shell $(CC_FOR_TARGET) -dumpmachine)),) override CFLAGS += \