bootboot: Remove uselessness and compliance fixes (see #124)
diff --git a/CONFIG.md b/CONFIG.md
index 883a0d43..7d890aed 100644
--- a/CONFIG.md
+++ b/CONFIG.md
@@ -100,12 +100,7 @@ Some keys take *URIs* as values; these are described in the next section.
modules.
* `RESOLUTION` - The resolution to be used. This setting takes the form of `<width>x<height>x<bpp>`. If the resolution is not available, Limine will pick another one automatically. Omitting `<bpp>` will default to 32.
* Bootboot protocol:
- * `KERNEL_PATH` - The URI path of the kernel.
- * `INITRD_PATH` - The URI path to the ramdisk/initrd.
- * `BOOTBOOT_ENV` - A configuration key to be passed into the kernel.
-
- Note that one can define this last variable multiple times to specify multiple
- environemnt keys.
+ * `INITRD_PATH` - The URI path to the ramdisk/initrd or kernel.
* `RESOLUTION` - The resolution to be used. This setting takes the form of `<width>x<height>x<bpp>`. If the resolution is not available, Limine will pick another one automatically. Omitting `<bpp>` will default to 32.
* stivale and stivale2 protocols:
* `KERNEL_PATH` - The URI path of the kernel.
@@ -118,7 +113,7 @@ Some keys take *URIs* as values; these are described in the next section.
to the 1st module string entry that appear, and so on.
**Note**: If `MODULE_STRING` is not specified for an entry, the `MODULE_STRING` will default to the `MODULE_PATH`.
-
+
* `RESOLUTION` - The resolution to be used should the kernel request a graphical framebuffer. This setting takes the form of `<width>x<height>x<bpp>` and *overrides* any resolution requested by the kernel, or automatic resolution requests. If the resolution is not available, Limine will pick another one automatically. Omitting `<bpp>` will default to 32.
* `KASLR` - For relocatable kernels, if set to `no`, disable kernel address space layout randomisation. KASLR is enabled by default.
* `TEXTMODE` - If set to `yes`, prefer text mode if the kernel has no video mode requirements. (Only for stivale2)
diff --git a/stage23/protos/bootboot.c b/stage23/protos/bootboot.c
index b732ad9a..87153337 100644
--- a/stage23/protos/bootboot.c
+++ b/stage23/protos/bootboot.c
@@ -46,38 +46,27 @@ void bootboot_load(char *config) {
uint64_t env_vaddr = BOOTBOOT_ENV;
uint64_t init_stack_size = (uint64_t)-1;
- /// Config ///
- char *kernel_path = config_get_value(config, 0, "KERNEL_PATH");
-
char *initrd = config_get_value(config, 0, "INITRD_PATH");
if (initrd == NULL) {
- initrd = kernel_path;
- kernel_path = NULL;
- }
-
- if (kernel_path == NULL && initrd == NULL) {
- panic("bootboot: no KERNEL_PATH or INITRD_PATH specified!");
+ panic("bootboot: no INITRD_PATH specified!");
}
/// Initrd loading ///
struct initrd_file bootboot_initrd_file;
uint64_t initrd_start = 0, initrd_size = 0;
- if (initrd) {
- struct file_handle *initrd_file;
- if ((initrd_file = uri_open(initrd)) == NULL) {
- panic("bootboot: Failed to open initrd with path `%s`. Is the path correct?", initrd);
- }
- uint8_t *initrd_data = freadall(initrd_file, MEMMAP_KERNEL_AND_MODULES);
- initrd_size = initrd_file->size;
- initrd_start = (uint64_t)(size_t)initrd_data;
- fclose(initrd_file);
- bootboot_initrd_file.size = initrd_size;
- bootboot_initrd_file.data = initrd_data;
- } else {
- panic("bootboot: logic error: no initrd, even though one MUST be present");
+ struct file_handle *initrd_file;
+ if ((initrd_file = uri_open(initrd)) == NULL) {
+ panic("bootboot: Failed to open initrd with path `%s`. Is the path correct?", initrd);
}
+ uint8_t *initrd_data = freadall(initrd_file, MEMMAP_KERNEL_AND_MODULES);
+ initrd_size = initrd_file->size;
+ initrd_start = (uint64_t)(size_t)initrd_data;
+ fclose(initrd_file);
+ bootboot_initrd_file.size = initrd_size;
+ bootboot_initrd_file.data = initrd_data;
+
/// Load bootboot config ///
uint8_t *env = ext_mem_alloc_type_aligned(4096, MEMMAP_BOOTLOADER_RECLAIMABLE, 4096);
uint64_t envoff = 0;
@@ -113,25 +102,23 @@ void bootboot_load(char *config) {
/// Kernel loading code ///
uint8_t *kernel;
- if (kernel_path) {
- print("bootboot: Loading kernel `%s`...\n", kernel_path);
- struct file_handle *kernel_file;
- if ((kernel_file = uri_open(kernel_path)) == NULL)
- panic("bootboot: Failed to open kernel with path `%s`. Is the path correct?", kernel_path);
- kernel = freadall(kernel_file, MEMMAP_KERNEL_AND_MODULES);
-
- fclose(kernel_file);
- } else {
+ if (known_initrd_format(bootboot_initrd_file)) {
const char *corefile = config_get_value((char *)env, 0, "kernel");
- if (!corefile) {
+ if (corefile == NULL) {
corefile = "sys/core";
}
struct initrd_file file = initrd_open_auto(bootboot_initrd_file, corefile);
+ if (!file.size) {
+ panic("bootboot: cannot find the kernel!");
+ }
kernel = file.data;
+ } else {
+ struct initrd_file file = bruteforce_kernel(bootboot_initrd_file);
if (!file.size) {
panic("bootboot: cannot find the kernel!");
}
+ kernel = file.data;
}
/// Memory mappings ///
@@ -208,24 +195,7 @@ void bootboot_load(char *config) {
map_page(pmap, struct_vaddr, (uintptr_t)bootboot, VMM_FLAG_PRESENT | VMM_FLAG_WRITE, false);
/// Environment ///
- {
- map_page(pmap, env_vaddr, (uintptr_t)env, VMM_FLAG_PRESENT | VMM_FLAG_WRITE, false);
- uint32_t index = 0, offset = 0;
- char *cfgent = NULL;
- do {
- cfgent = config_get_value(config, index++, "BOOTBOOT_ENV");
- if (cfgent) {
- uint32_t off = strlen(cfgent);
- if (offset + off + 1 > 4095) {
- panic("Too much config options! we only have 4k of env vars!");
- }
- memcpy(&env[offset], cfgent, off);
- offset += off;
- env[offset++] = '\n';
- }
- } while (cfgent);
- cfgent[offset] = 0;
- }
+ map_page(pmap, env_vaddr, (uintptr_t)env, VMM_FLAG_PRESENT | VMM_FLAG_WRITE, false);
/// Identity mapping ///
for (uint64_t i = 0; i < 0x400000000; i += 0x200000) {
diff --git a/stage23/protos/bootboot/initrd.c b/stage23/protos/bootboot/initrd.c
index e92f1ac7..387c7de0 100644
--- a/stage23/protos/bootboot/initrd.c
+++ b/stage23/protos/bootboot/initrd.c
@@ -1,53 +1,56 @@
#include <stdint.h>
#include <stddef.h>
+#include <stdbool.h>
#include <protos/bootboot/initrd.h>
#include <lib/print.h>
#include <lib/libc.h>
#include <lib/blib.h>
+struct initrd_file bruteforce_kernel(struct initrd_file file) {
+ for (size_t i = 0; i < file.size; i++) {
+ if (memcmp(file.data + i, "\177ELF", 4) == 0) {
+ printv("bootboot: using bruteforced kernel at initrd offset %X\n", file.data + i);
+ return (struct initrd_file){
+ .size = file.size - i,
+ .data = file.data + i
+ };
+ }
+ }
+ return (struct initrd_file){0};
+}
+
+bool known_initrd_format(struct initrd_file file) {
+ if (file.size >= 5 && file.data[4] == 0xbf) {
+ return true;
+ }
+
+ if (file.size >= 5 && memcmp("07070", file.data, 5) == 0) {
+ return true;
+ }
+
+ if (file.size >= 262 && memcmp("ustar", file.data + 257, 5) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
INITRD_HANDLER(jamesm);
INITRD_HANDLER(ustar);
INITRD_HANDLER(cpio);
INITRD_HANDLER(auto) {
if (file.size >= 5 && file.data[4] == 0xbf) {
- struct initrd_file jamesm_attempt = initrd_open_jamesm(file, path);
- if (jamesm_attempt.data) {
- printv("bootboot: jamesm matched when reading file `%s`\n", path);
- return jamesm_attempt;
- }
- panic("bootboot: cannot read file `%s`: no such file or directory", path);
+ return initrd_open_jamesm(file, path);
}
if (file.size >= 5 && memcmp("07070", file.data, 5) == 0) {
- struct initrd_file cpio_attempt = initrd_open_cpio(file, path);
- if (cpio_attempt.data) {
- printv("bootboot: cpio matched when reading file `%s`\n", path);
- return cpio_attempt;
- }
- panic("bootboot: cannot read file `%s`: no such file or directory", path);
+ return initrd_open_cpio(file, path);
}
if (file.size >= 262 && memcmp("ustar", file.data + 257, 5) == 0) {
- struct initrd_file ustar_attempt = initrd_open_ustar(file, path);
- if (ustar_attempt.data) {
- printv("bootboot: ustar matched when reading file `%s`\n", path);
- return ustar_attempt;
- }
- panic("bootboot: cannot read file `%s`: no such file or directory", path);
- }
-
- if (strcmp("sys/core", path) == 0) {
- for (size_t i = 0; i < file.size; i += 4) {
- if (memcmp(file.data + i, "\177ELF", 4) == 0) {
- printv("bootboot: using ELF as initrd to open sys/core\n");
- return (struct initrd_file){
- .size = file.size - i,
- .data = file.data + i
- };
- }
- }
+ return initrd_open_ustar(file, path);
}
- panic("bootboot: cannot read file `%s`: cannot detect initrd type (only ustar, cpio and jamesm is supported).", path);
+ return (struct initrd_file){0};
}
diff --git a/stage23/protos/bootboot/initrd.h b/stage23/protos/bootboot/initrd.h
index 752faff4..1c3d7f1d 100644
--- a/stage23/protos/bootboot/initrd.h
+++ b/stage23/protos/bootboot/initrd.h
@@ -2,12 +2,16 @@
#define __PROTOS__BOOTBOOT__INITRD_H__
#include <stdint.h>
+#include <stdbool.h>
struct initrd_file {
uint64_t size;
uint8_t *data;
};
+struct initrd_file bruteforce_kernel(struct initrd_file file);
+bool known_initrd_format(struct initrd_file file);
+
#define INITRD_HANDLER(name) struct initrd_file initrd_open_##name(struct initrd_file file, const char *path)
INITRD_HANDLER(auto);
