Use URIs instead of explicit drive and partition keys in config file
diff --git a/limine.bin b/limine.bin
index 2d442840..28833f5e 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/lib/blib.c b/stage2/lib/blib.c
index a0deb5dd..ee53ec7f 100644
--- a/stage2/lib/blib.c
+++ b/stage2/lib/blib.c
@@ -12,36 +12,55 @@
#include <lib/config.h>
#include <mm/pmm.h>
-struct kernel_loc get_kernel_loc(int boot_drive) {
- int kernel_drive; {
- char buf[32];
- if (!config_get_value(buf, 0, 32, "KERNEL_DRIVE")) {
- kernel_drive = boot_drive;
- } else {
- kernel_drive = (int)strtoui(buf);
+uint8_t boot_drive;
+
+// BIOS partitions are specified in the <BIOS drive>:<partition> form.
+// The drive may be omitted, the partition cannot.
+static bool parse_bios_partition(char *loc, uint8_t *drive, uint8_t *partition) {
+ for (size_t i = 0; ; i++) {
+ if (loc[i] == 0)
+ return false;
+
+ if (loc[i] == ':') {
+ loc[i] = 0;
+ if (*loc == 0)
+ *drive = boot_drive;
+ else
+ *drive = strtoui(loc);
+ loc += i + 1;
+ break;
}
}
- int kernel_part; {
- char buf[32];
- if (!config_get_value(buf, 0, 32, "KERNEL_PARTITION")) {
- panic("KERNEL_PARTITION not specified");
- } else {
- kernel_part = (int)strtoui(buf);
- }
- }
+ if (*loc == 0)
+ return false;
- char *kernel_path = conv_mem_alloc(128);
- if (!config_get_value(kernel_path, 0, 128, "KERNEL_PATH")) {
- panic("KERNEL_PATH not specified");
- }
+ *partition = strtoui(loc);
- struct file_handle *fd = conv_mem_alloc(sizeof(struct file_handle));
- if (fopen(fd, kernel_drive, kernel_part, kernel_path)) {
- panic("Could not open kernel file");
- }
+ return true;
+}
+
+static bool uri_bios_dispatch(struct file_handle *fd, char *loc, char *path) {
+ uint8_t drive, partition;
- return (struct kernel_loc) { kernel_drive, kernel_part, kernel_path, fd };
+ if (!parse_bios_partition(loc, &drive, &partition))
+ return false;
+
+ if (fopen(fd, drive, partition, path))
+ return false;
+
+ return true;
+}
+
+bool uri_open(struct file_handle *fd, char *uri) {
+ char *resource, *root, *path;
+ config_resolve_uri(uri, &resource, &root, &path);
+
+ if (!strcmp(resource, "bios")) {
+ return uri_bios_dispatch(fd, root, path);
+ } else {
+ panic("Resource `%s` not valid.");
+ }
}
// This integer sqrt implementation has been adapted from:
diff --git a/stage2/lib/blib.h b/stage2/lib/blib.h
index 7e657ac5..af00263e 100644
--- a/stage2/lib/blib.h
+++ b/stage2/lib/blib.h
@@ -3,16 +3,12 @@
#include <stddef.h>
#include <stdint.h>
+#include <stdbool.h>
#include <fs/file.h>
-struct kernel_loc {
- int kernel_drive;
- int kernel_part;
- char *kernel_path;
- struct file_handle *fd;
-};
+extern uint8_t boot_drive;
-struct kernel_loc get_kernel_loc(int boot_drive);
+bool uri_open(struct file_handle *fd, char *uri);
uint64_t sqrt(uint64_t a_nInput);
diff --git a/stage2/main.c b/stage2/main.c
index a43a8c72..801b055d 100644
--- a/stage2/main.c
+++ b/stage2/main.c
@@ -18,7 +18,9 @@
#include <protos/chainload.h>
#include <menu.h>
-void entry(int boot_drive) {
+void entry(uint8_t _boot_drive) {
+ boot_drive = _boot_drive;
+
mtrr_save();
term_textmode();
@@ -63,11 +65,11 @@ void entry(int boot_drive) {
}
if (!strcmp(proto, "stivale")) {
- stivale_load(cmdline, boot_drive);
+ stivale_load(cmdline);
} else if (!strcmp(proto, "stivale2")) {
- stivale2_load(cmdline, boot_drive);
+ stivale2_load(cmdline);
} else if (!strcmp(proto, "linux")) {
- linux_load(cmdline, boot_drive);
+ linux_load(cmdline);
} else if (!strcmp(proto, "chainload")) {
chainload();
} else {
diff --git a/stage2/protos/linux.c b/stage2/protos/linux.c
index 9848e95f..d525dc74 100644
--- a/stage2/protos/linux.c
+++ b/stage2/protos/linux.c
@@ -51,11 +51,18 @@ static void spinup(uint16_t real_mode_code_seg, uint16_t kernel_entry_seg) {
);
}
-void linux_load(char *cmdline, int boot_drive) {
- struct kernel_loc kernel = get_kernel_loc(boot_drive);
+void linux_load(char *cmdline) {
+ char buf[128];
+ struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
+
+ if (!config_get_value(buf, 0, 128, "KERNEL_PATH"))
+ panic("KERNEL_PATH not specified");
+
+ if (!uri_open(kernel, buf))
+ panic("Could not open kernel resource");
uint32_t signature;
- fread(kernel.fd, &signature, 0x202, sizeof(uint32_t));
+ fread(kernel, &signature, 0x202, sizeof(uint32_t));
// validate signature
if (signature != 0x53726448) {
@@ -63,7 +70,7 @@ void linux_load(char *cmdline, int boot_drive) {
}
size_t setup_code_size = 0;
- fread(kernel.fd, &setup_code_size, 0x1f1, 1);
+ fread(kernel, &setup_code_size, 0x1f1, 1);
if (setup_code_size == 0)
setup_code_size = 4;
@@ -78,7 +85,7 @@ void linux_load(char *cmdline, int boot_drive) {
void *real_mode_code = conv_mem_alloc_aligned(real_mode_code_size, 0x1000);
- fread(kernel.fd, real_mode_code, 0, real_mode_code_size);
+ fread(kernel, real_mode_code, 0, real_mode_code_size);
size_t heap_end_ptr = ((real_mode_code_size & 0x0f) + 0x10) - 0x200;
*((uint16_t *)(real_mode_code + 0x224)) = (uint16_t)heap_end_ptr;
@@ -116,8 +123,8 @@ void linux_load(char *cmdline, int boot_drive) {
// load kernel
print("Loading kernel...\n");
- memmap_alloc_range(KERNEL_LOAD_ADDR, kernel.fd->size - real_mode_code_size, 0);
- fread(kernel.fd, (void *)KERNEL_LOAD_ADDR, real_mode_code_size, kernel.fd->size - real_mode_code_size);
+ memmap_alloc_range(KERNEL_LOAD_ADDR, kernel->size - real_mode_code_size, 0);
+ fread(kernel, (void *)KERNEL_LOAD_ADDR, real_mode_code_size, kernel->size - real_mode_code_size);
char initrd_path[64];
if (!config_get_value(initrd_path, 0, 64, "INITRD_PATH"))
@@ -126,14 +133,14 @@ void linux_load(char *cmdline, int boot_drive) {
int initrd_part; {
char buf[32];
if (!config_get_value(buf, 0, 32, "INITRD_PARTITION")) {
- initrd_part = kernel.fd->partition;
+ initrd_part = kernel->partition;
} else {
initrd_part = (int)strtoui(buf);
}
}
struct file_handle initrd;
- if (fopen(&initrd, kernel.fd->disk, initrd_part, initrd_path)) {
+ if (fopen(&initrd, kernel->disk, initrd_part, initrd_path)) {
panic("Failed to open initrd");
}
diff --git a/stage2/protos/linux.h b/stage2/protos/linux.h
index bf09bf34..6ddec45d 100644
--- a/stage2/protos/linux.h
+++ b/stage2/protos/linux.h
@@ -3,6 +3,6 @@
#include <fs/file.h>
-void linux_load(char *cmdline, int boot_drive);
+void linux_load(char *cmdline);
#endif
diff --git a/stage2/protos/stivale.c b/stage2/protos/stivale.c
index 2ed45dd9..50cbeb23 100644
--- a/stage2/protos/stivale.c
+++ b/stage2/protos/stivale.c
@@ -24,14 +24,22 @@
struct stivale_struct stivale_struct = {0};
-void stivale_load(char *cmdline, int boot_drive) {
+void stivale_load(char *cmdline) {
+ char buf[128];
+
stivale_struct.flags |= (1 << 0); // set bit 0 since we are BIOS and not UEFI
- struct kernel_loc kernel = get_kernel_loc(boot_drive);
+ struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
+
+ if (!config_get_value(buf, 0, 128, "KERNEL_PATH"))
+ panic("KERNEL_PATH not specified");
+
+ if (!uri_open(kernel, buf))
+ panic("Could not open kernel resource");
struct stivale_header stivale_hdr;
- int bits = elf_bits(kernel.fd);
+ int bits = elf_bits(kernel);
int ret;
@@ -53,20 +61,20 @@ void stivale_load(char *cmdline, int boot_drive) {
level5pg = true;
}
- ret = elf64_load_section(kernel.fd, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header), slide);
+ ret = elf64_load_section(kernel, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header), slide);
if (!ret && ((stivale_hdr.flags >> 2) & 1)) {
// KASLR is enabled, set the slide
slide = rand64() & KASLR_SLIDE_BITMASK;
// Re-read the .stivalehdr with slid relocations
- ret = elf64_load_section(kernel.fd, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header), slide);
+ ret = elf64_load_section(kernel, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header), slide);
}
break;
}
case 32:
- ret = elf32_load_section(kernel.fd, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header));
+ ret = elf32_load_section(kernel, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header));
break;
default:
panic("stivale: Not 32 nor 64 bit x86 ELF file.");
@@ -92,10 +100,10 @@ void stivale_load(char *cmdline, int boot_drive) {
switch (bits) {
case 64:
- elf64_load(kernel.fd, &entry_point, &top_used_addr, slide, 10);
+ elf64_load(kernel, &entry_point, &top_used_addr, slide, 10);
break;
case 32:
- elf32_load(kernel.fd, (uint32_t *)&entry_point, (uint32_t *)&top_used_addr, 10);
+ elf32_load(kernel, (uint32_t *)&entry_point, (uint32_t *)&top_used_addr, 10);
break;
}
@@ -124,14 +132,14 @@ void stivale_load(char *cmdline, int boot_drive) {
int part; {
char buf[32];
if (!config_get_value(buf, i, 32, "MODULE_PARTITION")) {
- part = kernel.kernel_part;
+ part = kernel->partition;
} else {
part = (int)strtoui(buf);
}
}
struct file_handle f;
- if (fopen(&f, kernel.fd->disk, part, module_file)) {
+ if (fopen(&f, kernel->disk, part, module_file)) {
panic("Requested module with path \"%s\" not found!\n", module_file);
}
diff --git a/stage2/protos/stivale.h b/stage2/protos/stivale.h
index 7cf8e1a0..d46ad6da 100644
--- a/stage2/protos/stivale.h
+++ b/stage2/protos/stivale.h
@@ -6,7 +6,7 @@
#include <sys/e820.h>
#include <mm/vmm.h>
-void stivale_load(char *cmdline, int boot_drive);
+void stivale_load(char *cmdline);
pagemap_t stivale_build_pagemap(bool level5pg, struct e820_entry_t *memmap,
size_t memmap_entries);
diff --git a/stage2/protos/stivale2.c b/stage2/protos/stivale2.c
index 7856b646..6c215398 100644
--- a/stage2/protos/stivale2.c
+++ b/stage2/protos/stivale2.c
@@ -49,12 +49,20 @@ static void append_tag(struct stivale2_struct *s, struct stivale2_tag *tag) {
s->tags = (uint64_t)(size_t)tag;
}
-void stivale2_load(char *cmdline, int boot_drive) {
- struct kernel_loc kernel = get_kernel_loc(boot_drive);
+void stivale2_load(char *cmdline) {
+ char buf[128];
+
+ struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
+
+ if (!config_get_value(buf, 0, 128, "KERNEL_PATH"))
+ panic("KERNEL_PATH not specified");
+
+ if (!uri_open(kernel, buf))
+ panic("Could not open kernel resource");
struct stivale2_header stivale2_hdr;
- int bits = elf_bits(kernel.fd);
+ int bits = elf_bits(kernel);
int ret;
@@ -76,20 +84,20 @@ void stivale2_load(char *cmdline, int boot_drive) {
level5pg = true;
}
- ret = elf64_load_section(kernel.fd, &stivale2_hdr, ".stivale2hdr", sizeof(struct stivale2_header), slide);
+ ret = elf64_load_section(kernel, &stivale2_hdr, ".stivale2hdr", sizeof(struct stivale2_header), slide);
if (!ret && (stivale2_hdr.flags & 1)) {
// KASLR is enabled, set the slide
slide = rand64() & KASLR_SLIDE_BITMASK;
// Re-read the .stivale2hdr with slid relocations
- ret = elf64_load_section(kernel.fd, &stivale2_hdr, ".stivale2hdr", sizeof(struct stivale2_header), slide);
+ ret = elf64_load_section(kernel, &stivale2_hdr, ".stivale2hdr", sizeof(struct stivale2_header), slide);
}
break;
}
case 32:
- ret = elf32_load_section(kernel.fd, &stivale2_hdr, ".stivale2hdr", sizeof(struct stivale2_header));
+ ret = elf32_load_section(kernel, &stivale2_hdr, ".stivale2hdr", sizeof(struct stivale2_header));
break;
default:
panic("stivale2: Not 32 nor 64 bit x86 ELF file.");
@@ -115,10 +123,10 @@ void stivale2_load(char *cmdline, int boot_drive) {
switch (bits) {
case 64:
- elf64_load(kernel.fd, &entry_point, &top_used_addr, slide, 0x1001);
+ elf64_load(kernel, &entry_point, &top_used_addr, slide, 0x1001);
break;
case 32:
- elf32_load(kernel.fd, (uint32_t *)&entry_point, (uint32_t *)&top_used_addr, 0x1001);
+ elf32_load(kernel, (uint32_t *)&entry_point, (uint32_t *)&top_used_addr, 0x1001);
break;
}
@@ -169,14 +177,14 @@ void stivale2_load(char *cmdline, int boot_drive) {
int part; {
char buf[32];
if (!config_get_value(buf, i, 32, "MODULE_PARTITION")) {
- part = kernel.kernel_part;
+ part = kernel->partition;
} else {
part = (int)strtoui(buf);
}
}
struct file_handle f;
- if (fopen(&f, kernel.fd->disk, part, module_file)) {
+ if (fopen(&f, kernel->disk, part, module_file)) {
panic("Requested module with path \"%s\" not found!\n", module_file);
}
diff --git a/stage2/protos/stivale2.h b/stage2/protos/stivale2.h
index 307eff1f..68f66066 100644
--- a/stage2/protos/stivale2.h
+++ b/stage2/protos/stivale2.h
@@ -1,6 +1,6 @@
#ifndef __PROTOS__STIVALE2_H__
#define __PROTOS__STIVALE2_H__
-void stivale2_load(char *cmdline, int boot_drive);
+void stivale2_load(char *cmdline);
#endif
diff --git a/test/limine.cfg b/test/limine.cfg
index 380682f3..20cb5e2c 100644
--- a/test/limine.cfg
+++ b/test/limine.cfg
@@ -19,13 +19,11 @@ BACKGROUND_PATH=bg.bmp
:Stivale Test
PROTOCOL=stivale
-KERNEL_PARTITION=0
-KERNEL_PATH=boot/test.elf
+KERNEL_PATH=bios://:0/boot/test.elf
KERNEL_CMDLINE=Hi! This is an example!
:Stivale2 Test
PROTOCOL=stivale2
-KERNEL_PARTITION=0
-KERNEL_PATH=boot/test.elf
+KERNEL_PATH=bios://:0/boot/test.elf
KERNEL_CMDLINE=Woah! Another example!
