:: commit 7f63b9a10aeb24e8e88101a0d5b81a5ac6e21d07

mintsuki <mintsuki@protonmail.com> — 2021-04-20 04:45

parents: b3e4c49e57

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,
tab: 248 wrap: offon