config: Dynamically allocate buffer for config values when requested
diff --git a/limine-pxe.bin b/limine-pxe.bin
index 30c86eab..cfd63bc5 100644
Binary files a/limine-pxe.bin and b/limine-pxe.bin differ
diff --git a/limine.bin b/limine.bin
index 7c19f54e..f2e53300 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2.map b/stage2.map
index 266ffc58..fcd22902 100644
Binary files a/stage2.map and b/stage2.map differ
diff --git a/stage2/drivers/vbe.c b/stage2/drivers/vbe.c
index 602ae5c5..24514caf 100644
--- a/stage2/drivers/vbe.c
+++ b/stage2/drivers/vbe.c
@@ -351,12 +351,11 @@ void vbe_putchar(char c) {
}
bool vbe_tty_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, int _margin_gradient, struct image *_background) {
- char buf[32];
-
int req_width = 0, req_height = 0, req_bpp = 0;
- if (config_get_value(NULL, buf, 0, 32, "MENU_RESOLUTION"))
- parse_resolution(&req_width, &req_height, &req_bpp, buf);
+ char *menu_resolution = config_get_value(NULL, 0, "MENU_RESOLUTION");
+ if (menu_resolution == NULL)
+ parse_resolution(&req_width, &req_height, &req_bpp, menu_resolution);
// We force bpp to 32
req_bpp = 32;
diff --git a/stage2/lib/config.c b/stage2/lib/config.c
index 4fc70c92..6f35fa31 100644
--- a/stage2/lib/config.c
+++ b/stage2/lib/config.c
@@ -200,9 +200,8 @@ cont:
return ret;
}
-char *config_get_value(const char *config,
- char *buf, size_t index, size_t limit, const char *key) {
- if (!limit || !buf || !key)
+char *config_get_value(const char *config, size_t index, const char *key) {
+ if (!key)
return NULL;
if (config == NULL)
@@ -217,13 +216,12 @@ char *config_get_value(const char *config,
if (index--)
continue;
i += key_len + 1;
- size_t j;
- for (j = 0; config[i + j] != SEPARATOR && config[i + j]; j++) {
- if (j == limit - 1)
- break;
- buf[j] = config[i + j];
- }
- buf[j] = 0;
+ size_t value_len;
+ for (value_len = 0;
+ config[i + value_len] != SEPARATOR && config[i + value_len];
+ value_len++);
+ char *buf = ext_mem_alloc(value_len + 1);
+ memcpy(buf, config + i, value_len);
return buf;
}
}
diff --git a/stage2/lib/config.h b/stage2/lib/config.h
index 49eb2036..005ed91c 100644
--- a/stage2/lib/config.h
+++ b/stage2/lib/config.h
@@ -23,7 +23,6 @@ int init_config_pxe(void);
int init_config(size_t config_size);
bool config_get_entry_name(char *ret, size_t index, size_t limit);
char *config_get_entry(size_t *size, size_t index);
-char *config_get_value(const char *config,
- char *buf, size_t index, size_t limit, const char *key);
+char *config_get_value(const char *config, size_t index, const char *key);
#endif
diff --git a/stage2/lib/print.c b/stage2/lib/print.c
index 0c4bf844..57b70699 100644
--- a/stage2/lib/print.c
+++ b/stage2/lib/print.c
@@ -119,8 +119,9 @@ static char print_buf[PRINT_BUF_MAX];
void vprint(const char *fmt, va_list args) {
if (config_ready && e9_output == -1) {
- e9_output = config_get_value(NULL, print_buf, 0, PRINT_BUF_MAX, "E9_OUTPUT") &&
- !strcmp(print_buf, "yes");
+ char *e9_output_config = config_get_value(NULL, 0, "E9_OUTPUT");
+ e9_output = e9_output_config != NULL &&
+ !strcmp(e9_output_config, "yes");
}
size_t print_buf_i = 0;
diff --git a/stage2/lib/trace.c b/stage2/lib/trace.c
index 5bd88a15..362379ed 100644
--- a/stage2/lib/trace.c
+++ b/stage2/lib/trace.c
@@ -11,8 +11,8 @@
static char *stage2_map = NULL;
void trace_init(void) {
- char map_filename[80];
- if (!config_get_value(NULL, map_filename, 0, 80, "STAGE2_MAP"))
+ char *map_filename = config_get_value(NULL, 0, "STAGE2_MAP");
+ if (map_filename == NULL)
return;
struct file_handle stage2_map_file;
diff --git a/stage2/main.c b/stage2/main.c
index c2757af2..25d0ebe1 100644
--- a/stage2/main.c
+++ b/stage2/main.c
@@ -73,8 +73,8 @@ void entry(uint8_t _boot_drive, int pxe_boot) {
char *cmdline;
char *config = menu(&cmdline);
- char proto[32];
- if (!config_get_value(config, proto, 0, 32, "PROTOCOL")) {
+ char *proto = config_get_value(config, 0, "PROTOCOL");
+ if (proto == NULL) {
panic("PROTOCOL not specified");
}
diff --git a/stage2/menu.c b/stage2/menu.c
index b88d028d..586936b8 100644
--- a/stage2/menu.c
+++ b/stage2/menu.c
@@ -244,25 +244,26 @@ static int print_tree(int level, int base_index, int selected_entry,
char *menu(char **cmdline_ret) {
cmdline = conv_mem_alloc(CMDLINE_MAX);
- char *buf = conv_mem_alloc(256);
-
struct menu_entry *selected_menu_entry;
int selected_entry = 0;
- if (config_get_value(NULL, buf, 0, 16, "DEFAULT_ENTRY")) {
- selected_entry = (int)strtoui(buf, NULL, 10);
+ char *default_entry = config_get_value(NULL, 0, "DEFAULT_ENTRY");
+ if (default_entry != NULL) {
+ selected_entry = strtoui(default_entry, NULL, 10);
}
int timeout = 5;
- if (config_get_value(NULL, buf, 0, 16, "TIMEOUT")) {
- timeout = (int)strtoui(buf, NULL, 10);
+ char *timeout_config = config_get_value(NULL, 0, "TIMEOUT");
+ if (timeout_config != NULL) {
+ timeout = strtoui(timeout_config, NULL, 10);
}
if (!timeout)
goto autoboot;
// If there is GRAPHICS config key and the value is "yes", enable graphics
- if (config_get_value(NULL, buf, 0, 16, "GRAPHICS") && !strcmp(buf, "yes")) {
+ char *graphics = config_get_value(NULL, 0, "GRAPHICS");
+ if (graphics != NULL && !strcmp(graphics, "yes")) {
// default scheme
int margin = 64;
int margin_gradient = 20;
@@ -277,9 +278,11 @@ char *menu(char **cmdline_ret) {
0x00aaaaaa // grey
};
- if (config_get_value(NULL, buf, 0, 256, "THEME_COLOURS")
- || config_get_value(NULL, buf, 0, 256, "THEME_COLORS")) {
- const char *first = buf;
+ char *colours = config_get_value(NULL, 0, "THEME_COLOURS");
+ if (colours == NULL)
+ colours = config_get_value(NULL, 0, "THEME_COLORS");
+ if (colours != NULL) {
+ const char *first = colours;
for (int i = 0; i < 8; i++) {
const char *last;
uint32_t col = strtoui(first, &last, 16);
@@ -292,32 +295,32 @@ char *menu(char **cmdline_ret) {
}
}
- if (config_get_value(NULL, buf, 0, 16, "THEME_MARGIN")) {
- margin = (int)strtoui(buf, NULL, 10);
+ char *theme_margin = config_get_value(NULL, 0, "THEME_MARGIN");
+ if (theme_margin != NULL) {
+ margin = strtoui(theme_margin, NULL, 10);
}
- if (config_get_value(NULL, buf, 0, 16, "THEME_MARGIN_GRADIENT")) {
- margin_gradient = (int)strtoui(buf, NULL, 10);
+ char *theme_margin_gradient = config_get_value(NULL, 0, "THEME_MARGIN_GRADIENT");
+ if (theme_margin_gradient != NULL) {
+ margin_gradient = strtoui(theme_margin_gradient, NULL, 10);
}
- if (!config_get_value(NULL, cmdline, 0, CMDLINE_MAX, "BACKGROUND_PATH"))
- goto nobg;
+ struct image *bg = NULL;
- struct file_handle *bg_file = conv_mem_alloc(sizeof(struct file_handle));
- if (!uri_open(bg_file, cmdline))
+ char *background_path = config_get_value(NULL, 0, "BACKGROUND_PATH");
+ if (background_path == NULL)
goto nobg;
- struct image *bg = conv_mem_alloc(sizeof(struct image));
- if (open_image(bg, bg_file))
+ struct file_handle *bg_file = ext_mem_alloc(sizeof(struct file_handle));
+ if (!uri_open(bg_file, background_path))
goto nobg;
- term_vbe(colourscheme, margin, margin_gradient, bg);
- goto yesbg;
+ bg = ext_mem_alloc(sizeof(struct image));
+ if (open_image(bg, bg_file))
+ bg = NULL;
nobg:
- term_vbe(colourscheme, margin, margin_gradient, NULL);
-
- yesbg:;
+ term_vbe(colourscheme, margin, margin_gradient, bg);
}
disable_cursor();
@@ -377,10 +380,12 @@ timeout_aborted:
goto refresh;
}
enable_cursor();
- if (!config_get_value(selected_menu_entry->body, cmdline, 0, CMDLINE_MAX, "KERNEL_CMDLINE")) {
- if (!config_get_value(selected_menu_entry->body, cmdline, 0, CMDLINE_MAX, "CMDLINE")) {
- cmdline[0] = '\0';
- }
+ cmdline = config_get_value(selected_menu_entry->body, 0, "KERNEL_CMDLINE");
+ if (!cmdline) {
+ cmdline = config_get_value(selected_menu_entry->body, 0, "CMDLINE");
+ }
+ if (!cmdline) {
+ cmdline[0] = '\0';
}
clear(true);
*cmdline_ret = cmdline;
diff --git a/stage2/protos/chainload.c b/stage2/protos/chainload.c
index a97a0580..8048e100 100644
--- a/stage2/protos/chainload.c
+++ b/stage2/protos/chainload.c
@@ -50,11 +50,11 @@ void chainload(char *config) {
uint64_t val;
int part; {
- char buf[32];
- if (!config_get_value(config, buf, 0, 32, "PARTITION")) {
+ char *part_config = config_get_value(config, 0, "PARTITION");
+ if (part_config == NULL) {
part = -1;
} else {
- val = strtoui(buf, NULL, 10);
+ val = strtoui(part_config, NULL, 10);
if (val < 1 || val > 256) {
panic("BIOS partition number outside range 1-256");
}
@@ -62,11 +62,11 @@ void chainload(char *config) {
}
}
int drive; {
- char buf[32];
- if (!config_get_value(config, buf, 0, 32, "DRIVE")) {
+ char *drive_config = config_get_value(config, 0, "DRIVE");
+ if (drive_config == NULL) {
panic("DRIVE not specified");
}
- val = strtoui(buf, NULL, 10);
+ val = strtoui(drive_config, NULL, 10);
if (val < 1 || val > 16) {
panic("BIOS drive number outside range 1-16");
}
diff --git a/stage2/protos/linux.c b/stage2/protos/linux.c
index c3386277..5e1c420e 100644
--- a/stage2/protos/linux.c
+++ b/stage2/protos/linux.c
@@ -53,13 +53,13 @@ static void spinup(uint16_t real_mode_code_seg, uint16_t kernel_entry_seg) {
}
void linux_load(char *config, char *cmdline) {
- char buf[128];
struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
- if (!config_get_value(config, buf, 0, 128, "KERNEL_PATH"))
+ char *kernel_path = config_get_value(config, 0, "KERNEL_PATH");
+ if (kernel_path == NULL)
panic("KERNEL_PATH not specified");
- if (!uri_open(kernel, buf))
+ if (!uri_open(kernel, kernel_path))
panic("Could not open kernel resource");
uint32_t signature;
@@ -129,14 +129,15 @@ void linux_load(char *config, char *cmdline) {
size_t modules_mem_base = INITRD_LOAD_ADDR;
for (size_t i = 0; ; i++) {
- if (!config_get_value(config, buf, i, 128, "MODULE_PATH"))
+ char *module_path = config_get_value(config, i, "MODULE_PATH");
+ if (module_path == NULL)
break;
struct file_handle module;
- if (!uri_open(&module, buf))
- panic("Could not open `%s`", buf);
+ if (!uri_open(&module, module_path))
+ panic("Could not open `%s`", module_path);
- print("Loading module `%s`...\n", buf);
+ print("Loading module `%s`...\n", module_path);
memmap_alloc_range(modules_mem_base, module.size, 0);
fread(&module, (void *)modules_mem_base, 0, module.size);
diff --git a/stage2/protos/stivale.c b/stage2/protos/stivale.c
index 8dabb812..146264d4 100644
--- a/stage2/protos/stivale.c
+++ b/stage2/protos/stivale.c
@@ -2,6 +2,7 @@
#include <stddef.h>
#include <stdbool.h>
#include <protos/stivale.h>
+#include <lib/libc.h>
#include <lib/elf.h>
#include <lib/blib.h>
#include <lib/acpi.h>
@@ -26,16 +27,15 @@
struct stivale_struct stivale_struct = {0};
void stivale_load(char *config, char *cmdline) {
- char buf[128];
-
stivale_struct.flags |= (1 << 0); // set bit 0 since we are BIOS and not UEFI
struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
- if (!config_get_value(config, buf, 0, 128, "KERNEL_PATH"))
+ char *kernel_path = config_get_value(config, 0, "KERNEL_PATH");
+ if (kernel_path == NULL)
panic("KERNEL_PATH not specified");
- if (!uri_open(kernel, buf))
+ if (!uri_open(kernel, kernel_path))
panic("Could not open kernel resource");
struct stivale_header stivale_hdr;
@@ -116,26 +116,34 @@ void stivale_load(char *config, char *cmdline) {
stivale_struct.module_count = 0;
uint64_t *prev_mod_ptr = &stivale_struct.modules;
for (int i = 0; ; i++) {
- if (!config_get_value(config, buf, i, 128, "MODULE_PATH"))
+ char *module_path = config_get_value(config, i, "MODULE_PATH");
+ if (module_path == NULL)
break;
stivale_struct.module_count++;
struct stivale_module *m = conv_mem_alloc(sizeof(struct stivale_module));
- if (!config_get_value(config, m->string, i, 128, "MODULE_STRING")) {
+ char *module_string = config_get_value(config, i, "MODULE_STRING");
+ if (module_string == NULL) {
m->string[0] = '\0';
+ } else {
+ // TODO perhaps change this to be a pointer
+ size_t str_len = strlen(module_string);
+ if (str_len > 127)
+ str_len = 127;
+ memcpy(m->string, module_string, str_len);
}
struct file_handle f;
- if (!uri_open(&f, buf))
- panic("Requested module with path \"%s\" not found!", buf);
+ if (!uri_open(&f, module_path))
+ panic("Requested module with path \"%s\" not found!", module_path);
void *module_addr = (void *)(((uint32_t)top_used_addr & 0xfff) ?
((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
(uint32_t)top_used_addr);
- print("stivale: Loading module `%s`...\n", buf);
+ print("stivale: Loading module `%s`...\n", module_path);
memmap_alloc_range((size_t)module_addr, f.size, 10);
fread(&f, module_addr, 0, f.size);
@@ -150,7 +158,7 @@ void stivale_load(char *config, char *cmdline) {
prev_mod_ptr = &m->next;
print("stivale: Requested module %u:\n", i);
- print(" Path: %s\n", buf);
+ print(" Path: %s\n", module_path);
print(" String: %s\n", m->string);
print(" Begin: %X\n", m->begin);
print(" End: %X\n", m->end);
@@ -170,8 +178,9 @@ void stivale_load(char *config, char *cmdline) {
int req_height = stivale_hdr.framebuffer_height;
int req_bpp = stivale_hdr.framebuffer_bpp;
- if (config_get_value(config, buf, 0, 128, "RESOLUTION"))
- parse_resolution(&req_width, &req_height, &req_bpp, buf);
+ char *resolution = config_get_value(config, 0, "RESOLUTION");
+ if (resolution != NULL)
+ parse_resolution(&req_width, &req_height, &req_bpp, resolution);
struct vbe_framebuffer_info fbinfo;
init_vbe(&fbinfo, req_width, req_height, req_bpp);
diff --git a/stage2/protos/stivale2.c b/stage2/protos/stivale2.c
index 81917230..e1580486 100644
--- a/stage2/protos/stivale2.c
+++ b/stage2/protos/stivale2.c
@@ -51,14 +51,13 @@ static void append_tag(struct stivale2_struct *s, struct stivale2_tag *tag) {
}
void stivale2_load(char *config, char *cmdline) {
- char buf[128];
-
struct file_handle *kernel = conv_mem_alloc(sizeof(struct file_handle));
- if (!config_get_value(config, buf, 0, 128, "KERNEL_PATH"))
+ char *kernel_path = config_get_value(config, 0, "KERNEL_PATH");
+ if (kernel_path == NULL)
panic("KERNEL_PATH not specified");
- if (!uri_open(kernel, buf))
+ if (!uri_open(kernel, kernel_path))
panic("Could not open kernel resource");
struct stivale2_header stivale2_hdr;
@@ -157,8 +156,8 @@ void stivale2_load(char *config, char *cmdline) {
{
size_t module_count;
for (module_count = 0; ; module_count++) {
- char module_file[64];
- if (!config_get_value(config, module_file, module_count, 64, "MODULE_PATH"))
+ char *module_file = config_get_value(config, module_count, "MODULE_PATH");
+ if (module_file == NULL)
break;
}
@@ -169,25 +168,31 @@ void stivale2_load(char *config, char *cmdline) {
tag->tag.identifier = STIVALE2_STRUCT_TAG_MODULES_ID;
tag->module_count = module_count;
- for (int i = 0; ; i++) {
- if (!config_get_value(config, buf, i, 128, "MODULE_PATH"))
- break;
+ for (size_t i = 0; i < module_count; i++) {
+ char *module_path = config_get_value(config, i, "MODULE_PATH");
struct stivale2_module *m = &tag->modules[i];
- if (!config_get_value(config, m->string, i, 128, "MODULE_STRING")) {
+ char *module_string = config_get_value(config, i, "MODULE_STRING");
+ if (module_string == NULL) {
m->string[0] = '\0';
+ } else {
+ // TODO perhaps change this to be a pointer
+ size_t str_len = strlen(module_string);
+ if (str_len > 127)
+ str_len = 127;
+ memcpy(m->string, module_string, str_len);
}
struct file_handle f;
- if (!uri_open(&f, buf))
- panic("Requested module with path \"%s\" not found!", buf);
+ if (!uri_open(&f, module_path))
+ panic("Requested module with path \"%s\" not found!", module_path);
void *module_addr = (void *)(((uint32_t)top_used_addr & 0xfff) ?
((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
(uint32_t)top_used_addr);
- print("stivale2: Loading module `%s`...\n", buf);
+ print("stivale2: Loading module `%s`...\n", module_path);
memmap_alloc_range((size_t)module_addr, f.size, 0x1001);
fread(&f, module_addr, 0, f.size);
@@ -198,7 +203,7 @@ void stivale2_load(char *config, char *cmdline) {
top_used_addr = (uint64_t)(size_t)m->end;
print("stivale2: Requested module %u:\n", i);
- print(" Path: %s\n", buf);
+ print(" Path: %s\n", module_path);
print(" String: %s\n", m->string);
print(" Begin: %X\n", m->begin);
print(" End: %X\n", m->end);
@@ -257,8 +262,9 @@ void stivale2_load(char *config, char *cmdline) {
int req_height = hdrtag->framebuffer_height;
int req_bpp = hdrtag->framebuffer_bpp;
- if (config_get_value(config, buf, 0, 128, "RESOLUTION"))
- parse_resolution(&req_width, &req_height, &req_bpp, buf);
+ char *resolution = config_get_value(config, 0, "RESOLUTION");
+ if (resolution != NULL)
+ parse_resolution(&req_width, &req_height, &req_bpp, resolution);
struct vbe_framebuffer_info fbinfo;
if (init_vbe(&fbinfo, req_width, req_height, req_bpp)) {
