:: commit 8c910b20e5b6db42a97347830ba799ae0b2c40fc

mintsuki <mintsuki@protonmail.com> — 2020-12-09 12:02

parents: 9c5298530d

uri: Add boot resource

diff --git a/CONFIG.md b/CONFIG.md
index 8c4aa3ec..5126ee39 100644
--- a/CONFIG.md
+++ b/CONFIG.md
@@ -99,6 +99,7 @@ resource://root/path
 The format for `root` changes depending on the resource used.
 
 A resource can be one of the following:
+* `boot` - The `root` is the 1-based decimal value representing the partition on the boot drive. If omitted, the partition containing the configuration file on the boot drive is used. For example: `boot://2/...` will use partition 2 of the boot drive and `boot:///...` will use the partition containing the config file on the boot drive.
 * `bios` - The `root` takes the form of `drive:partition`; for example: `bios://3:1/...` would use BIOS drive 3, partition 1. Partitions and BIOS drives are both 1-based. Omitting the drive is possible; for example: `bios://:2/...`. Omitting the drive makes Limine use the boot drive.
 * `guid` - The `root` takes the form of a GUID/UUID, such as `guid://736b5698-5ae1-4dff-be2c-ef8f44a61c52/...`. It is a filesystem GUID and not a partition GUID.
 * `tftp` - The `root` is the ip address of the tftp server to load the file from, if the root is left empty (`tftp:///file.elf`) the file will be loaded from the server limine booted from.
diff --git a/limine-pxe.bin b/limine-pxe.bin
index eeaba0df..87f94b13 100644
Binary files a/limine-pxe.bin and b/limine-pxe.bin differ
diff --git a/limine.bin b/limine.bin
index c10dd5de..d58729f4 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2.map b/stage2.map
index 68d4efb5..54c53bf1 100644
Binary files a/stage2.map and b/stage2.map differ
diff --git a/stage2/lib/blib.c b/stage2/lib/blib.c
index ce4596e2..b608c4fc 100644
--- a/stage2/lib/blib.c
+++ b/stage2/lib/blib.c
@@ -7,6 +7,7 @@
 #include <lib/trace.h>
 
 uint8_t boot_drive;
+int     boot_partition = -1;
 
 bool parse_resolution(int *width, int *height, int *bpp, const char *buf) {
     int res[3] = {0};
diff --git a/stage2/lib/blib.h b/stage2/lib/blib.h
index 24fdd866..5cf9ceb1 100644
--- a/stage2/lib/blib.h
+++ b/stage2/lib/blib.h
@@ -6,6 +6,7 @@
 #include <stdbool.h>
 
 extern uint8_t boot_drive;
+extern int     boot_partition;
 
 bool parse_resolution(int *width, int *height, int *bpp, const char *buf);
 
diff --git a/stage2/lib/uri.c b/stage2/lib/uri.c
index 3fe3038e..85d0a175 100644
--- a/stage2/lib/uri.c
+++ b/stage2/lib/uri.c
@@ -90,6 +90,33 @@ static bool parse_bios_partition(char *loc, uint8_t *drive, uint8_t *partition)
     return true;
 }
 
+static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path) {
+    uint8_t partition;
+
+    if (s_part[0] != '\0') {
+        uint64_t val = strtoui(s_part, NULL, 10);
+        if (val < 1 || val > 256) {
+            panic("Partition number outside range 1-256");
+        }
+        partition = val - 1;
+    } else {
+        if (boot_partition != -1) {
+            partition = boot_partition;
+        } else {
+            panic("Boot partition information is unavailable.");
+        }
+    }
+
+    struct part part;
+    if (part_get(&part, boot_drive, partition))
+        return false;
+
+    if (fopen(fd, &part, path))
+        return false;
+
+    return true;
+}
+
 static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
     uint8_t drive, partition;
 
@@ -147,8 +174,14 @@ bool uri_open(struct file_handle *fd, char *uri) {
     char *resource, *root, *path;
     uri_resolve(uri, &resource, &root, &path);
 
+    if (resource == NULL) {
+        panic("No resource specified for URI `%s`.", uri);
+    }
+
     if (!strcmp(resource, "bios")) {
         return uri_bios_dispatch(fd, root, path);
+    } else if (!strcmp(resource, "boot")) {
+        return uri_boot_dispatch(fd, root, path);
     } else if (!strcmp(resource, "guid")) {
         return uri_guid_dispatch(fd, root, path);
     } else if (!strcmp(resource, "tftp")) {
diff --git a/stage2/main.c b/stage2/main.c
index c741f7f3..992fdb5a 100644
--- a/stage2/main.c
+++ b/stage2/main.c
@@ -40,17 +40,16 @@ void entry(uint8_t _boot_drive, int pxe_boot) {
 
     if (pxe_boot) {
         pxe_init();
-        if(init_config_pxe()) {
-            panic("failed to load config file");
+        if (init_config_pxe()) {
+            panic("Failed to load config file");
         }
-        print("config loaded");
+        print("Config loaded via PXE\n");
     } else {
         print("Boot drive: %x\n", boot_drive);
         // Look for config file.
         print("Searching for config file...\n");
         for (int i = 0; ; i++) {
             struct part part;
-            print("Checking partition %d...\n", i);
             int ret = part_get(&part, boot_drive, i);
             switch (ret) {
                 case INVALID_TABLE:
@@ -58,12 +57,11 @@ void entry(uint8_t _boot_drive, int pxe_boot) {
                 case END_OF_TABLE:
                     panic("Config file not found.");
                 case NO_PARTITION:
-                    print("Partition not found.\n");
                     continue;
             }
-            print("Partition found.\n");
             if (!init_config_disk(&part)) {
                 print("Config file found and loaded.\n");
+                boot_partition = i;
                 break;
             }
         }
diff --git a/test/limine.cfg b/test/limine.cfg
index c6c3fd17..e7ac14f7 100644
--- a/test/limine.cfg
+++ b/test/limine.cfg
@@ -2,7 +2,7 @@ DEFAULT_ENTRY=2
 TIMEOUT=3
 GRAPHICS=yes
 MENU_RESOLUTION=1024x768
-MENU_FONT=bios://:1/boot/font.bin
+MENU_FONT=boot:///boot/font.bin
 E9_OUTPUT=yes
 STAGE2_MAP=bios://:1/boot/stage2.map
 
@@ -16,7 +16,7 @@ BACKGROUND_PATH=bios://:1/boot/bg.bmp
 ::Stivale Test
 
 PROTOCOL=stivale
-KERNEL_PATH=bios://:1/boot/test.elf
+KERNEL_PATH=boot://1/boot/test.elf
 KERNEL_CMDLINE=Hi! This is an example!
 
 MODULE_PATH=bios://:1/boot/test.elf
tab: 248 wrap: offon