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
