menu: Instead of panicking when no config file exists or it has no entries, offer the user the ability to manually type in a boot entry
diff --git a/stage23/entry.s3.c b/stage23/entry.s3.c
index 9ad6a700..a584739f 100644
--- a/stage23/entry.s3.c
+++ b/stage23/entry.s3.c
@@ -67,19 +67,14 @@ __attribute__((section(".stage3_entry")))
#endif
__attribute__((noreturn))
void stage3_common(void) {
- bool got_config = false;
volume_iterate_parts(boot_volume,
if (!init_config_disk(_PART)) {
print("Config file found and loaded.\n");
boot_volume = _PART;
- got_config = true;
break;
}
);
- if (!got_config)
- panic("Config file not found.");
-
print("Boot drive: %x\n", boot_volume->drive);
print("Boot partition: %d\n", boot_volume->partition);
diff --git a/stage23/lib/config.c b/stage23/lib/config.c
index aa1b0741..ab71d958 100644
--- a/stage23/lib/config.c
+++ b/stage23/lib/config.c
@@ -145,6 +145,9 @@ int init_config(size_t config_size) {
}
bool config_get_entry_name(char *ret, size_t index, size_t limit) {
+ if (!config_ready)
+ return false;
+
char *p = config_addr;
for (size_t i = 0; i <= index; i++) {
@@ -172,6 +175,9 @@ bool config_get_entry_name(char *ret, size_t index, size_t limit) {
}
char *config_get_entry(size_t *size, size_t index) {
+ if (!config_ready)
+ return NULL;
+
char *ret;
char *p = config_addr;
diff --git a/stage23/menu.c b/stage23/menu.c
index 653de514..6c17bb88 100644
--- a/stage23/menu.c
+++ b/stage23/menu.c
@@ -85,7 +85,9 @@ static char *config_entry_editor(const char *orig_entry) {
if (entry_size >= EDITOR_MAX_BUFFER_SIZE)
panic("Entry is too big to be edited.");
- char *buffer = ext_mem_alloc(EDITOR_MAX_BUFFER_SIZE);
+ static char *buffer = NULL;
+ if (buffer == NULL)
+ buffer = ext_mem_alloc(EDITOR_MAX_BUFFER_SIZE);
memcpy(buffer, orig_entry, entry_size);
buffer[entry_size] = 0;
@@ -327,9 +329,6 @@ char *menu(char **cmdline) {
if (menu_branding == NULL)
menu_branding = "Limine " LIMINE_VERSION;
- if (menu_tree == NULL)
- panic("Config contains no valid entries.");
-
bool skip_timeout = false;
struct menu_entry *selected_menu_entry = NULL;
@@ -386,6 +385,21 @@ refresh:
clear(true);
print("\n\n \e[36m %s \e[37m\n\n\n", menu_branding);
+ if (menu_tree == NULL) {
+ print("Config file %s.\n\n", config_ready ? "contains no valid entries" : "not found");
+ print("For information on the format of Limine config entries, consult CONFIG.md in\n");
+ print("the root of the Limine source repository.\n\n");
+ print("Press a key to enter an editor session and manually define a config entry...");
+ term_double_buffer_flush();
+ getchar();
+ char *new_body = NULL;
+ while (new_body == NULL)
+ new_body = config_entry_editor("");
+ selected_menu_entry = ext_mem_alloc(sizeof(struct menu_entry));
+ selected_menu_entry->body = new_body;
+ goto autoboot;
+ }
+
print("Select an entry:\n\n");
int max_entries = print_tree(0, 0, selected_entry, menu_tree,
