:: commit ba86da93e079eb59d287e58489171f2d4375b488

mintsuki <mintsuki@protonmail.com> — 2024-05-03 04:43

parents: 54b01cd8c7

limine: Document and implement requests start marker

diff --git a/PROTOCOL.md b/PROTOCOL.md
index 9d76a29c..1844bfd6 100644
--- a/PROTOCOL.md
+++ b/PROTOCOL.md
@@ -111,20 +111,26 @@ revisions do.
 This is all there is to features. For a list of official Limine features, read
 the "Feature List" section below.
 
-## Requests Delimiter
+## Requests Delimiters
 
-The bootloader can be told to stop searching for requests (including base
-revision tags) in an executable by placing a set of 2 8-byte values called the
-"requests delimiter" on an 8-byte aligned boundary.
+The bootloader can be told to start and/or stop searching for requests (including base
+revision tags) in an executable's loaded image by placing start and/or end markers,
+on an 8-byte aligned boundary.
+
+The bootloader will only accept requests placed between the last start marker found (if
+there happen to be more than 1, which there should not, ideally) and the first end
+marker found.
 ```c
-#define LIMINE_REQUESTS_DELIMITER \
-    uint64_t limine_requests_delimiter[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 };
+#define LIMINE_REQUESTS_START_MARKER \
+    uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \
+                                                 0x785c6ed015d3e316, 0x181e920a7852b9d9 };
+
+#define LIMINE_REQUESTS_END_MARKER \
+    uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 };
 ```
 
-The requests delimiter is *a hint*. The bootloader can still search for
-requests and base revision tags past this point if it doesn't support the hint.
-When it comes to the Limine bootloader, this means versions starting from 7.1.x
-support it, while older ones do not.
+The requests delimiters are *a hint*. The bootloader can still search for
+requests and base revision tags outside the delimted area if it doesn't support the hint.
 
 ## Limine Requests Section
 
diff --git a/common/protos/limine.c b/common/protos/limine.c
index fc53bbc1..63745dbf 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -355,16 +355,26 @@ noreturn void limine_load(char *config, char *cmdline) {
 
     kaslr = kaslr && is_reloc;
 
-    LIMINE_REQUESTS_DELIMITER;
+    LIMINE_REQUESTS_START_MARKER;
+    LIMINE_REQUESTS_END_MARKER;
 
     // Determine base revision
     LIMINE_BASE_REVISION(0);
     int base_revision = 0;
+    uint64_t *base_rev_p2_ptr = NULL;
     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 delimiter hit
-        if (p[0] == limine_requests_delimiter[0] && p[1] == limine_requests_delimiter[1]) {
+        // 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]) {
+            base_revision = 0;
+            base_rev_p2_ptr = NULL;
+            continue;
+        }
+
+        // Check if end marker hit
+        if (p[0] == limine_requests_end_marker[0] && p[1] == limine_requests_end_marker[1]) {
             break;
         }
 
@@ -376,12 +386,15 @@ noreturn void limine_load(char *config, char *cmdline) {
             // We only support up to revision 1
             if (p[2] <= 1) {
                 // Set to 0 to mean "supported"
-                p[2] = 0;
+                base_rev_p2_ptr = &p[2];
             } else {
                 base_revision = 1;
             }
         }
     }
+    if (base_rev_p2_ptr != NULL) {
+        *base_rev_p2_ptr = 0;
+    }
 
     // Load requests
     uint64_t *limine_reqs = NULL;
@@ -400,8 +413,17 @@ noreturn void limine_load(char *config, char *cmdline) {
         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 delimiter hit
-            if (p[0] == limine_requests_delimiter[0] && p[1] == limine_requests_delimiter[1]) {
+            // 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]
+             && p[4] == limine_requests_start_marker[4] && p[5] == limine_requests_start_marker[5]
+             && p[6] == limine_requests_start_marker[6] && p[7] == limine_requests_start_marker[7]) {
+                requests_count = 0;
+                continue;
+            }
+
+            // Check if end marker hit
+            if (p[0] == limine_requests_end_marker[0] && p[1] == limine_requests_end_marker[1]) {
                 break;
             }
 
diff --git a/limine.h b/limine.h
index 674a90c3..04d96910 100644
--- a/limine.h
+++ b/limine.h
@@ -44,8 +44,13 @@ extern "C" {
 #  define LIMINE_DEPRECATED_IGNORE_END
 #endif
 
-#define LIMINE_REQUESTS_DELIMITER \
-    uint64_t limine_requests_delimiter[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 };
+#define LIMINE_REQUESTS_START_MARKER \
+    uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \
+                                                 0x785c6ed015d3e316, 0x181e920a7852b9d9 };
+#define LIMINE_REQUESTS_END_MARKER \
+    uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 };
+
+#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER
 
 #define LIMINE_BASE_REVISION(N) \
     uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) };
diff --git a/test/limine.c b/test/limine.c
index 3f10314b..9adaebee 100644
--- a/test/limine.c
+++ b/test/limine.c
@@ -11,8 +11,10 @@ static volatile LIMINE_BASE_REVISION(1);
 
 static void limine_main(void);
 
-__attribute__((used))
-__attribute__((section(".limine_requests")))
+__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,
     .revision = 0, .response = NULL,
@@ -138,9 +140,8 @@ static volatile struct limine_paging_mode_request _pm_request = {
     .flags = 0,
 };
 
-__attribute__((used))
-__attribute__((section(".limine_requests_delimiter")))
-static volatile LIMINE_REQUESTS_DELIMITER;
+__attribute__((used, section(".limine_requests_end_marker")))
+static volatile LIMINE_REQUESTS_END_MARKER;
 
 static char *get_memmap_type(uint64_t type) {
     switch (type) {
diff --git a/test/linker.ld b/test/linker.ld
index 6c4377d6..89593d64 100644
--- a/test/linker.ld
+++ b/test/linker.ld
@@ -1,7 +1,5 @@
 PHDRS
 {
-    limine_requests PT_LOAD FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
-
     text    PT_LOAD    FLAGS((1 << 0) | (1 << 2)) ; /* Execute + Read */
     rodata  PT_LOAD    FLAGS((1 << 2)) ;            /* Read only */
     data    PT_LOAD    FLAGS((1 << 1) | (1 << 2)) ; /* Write + Read */
@@ -13,16 +11,6 @@ SECTIONS
     . = 0xffffffff80000000;
     kernel_start = .;
 
-    .limine_requests : {
-        *(.limine_requests .limine_requests.*)
-    } :limine_requests
-
-    .limine_requests_delimiter : {
-        *(.limine_requests_delimiter .limine_requests_delimiter.*)
-    } :limine_requests
-
-    . += 0x1000;
-
     .text : {
         *(.text .text.*)
     } :text
@@ -37,6 +25,11 @@ SECTIONS
 
     .data : {
         *(.data .data.*)
+
+        *(.limine_requests_start_marker)
+        *(.limine_requests)
+        *(.limine_requests_end_marker)
+
         *(.sdata .sdata.*)
     } :data
 
tab: 248 wrap: offon