:: commit 1e7ba9523046150091fc462a897c26ecdd9c7af7

mintsuki <mintsuki@protonmail.com> — 2021-02-26 00:30

parents: 60742ea6a5

config: Move config code to stage 3

diff --git a/stage23/Makefile b/stage23/Makefile
index 9f102cb0..60d4f932 100644
--- a/stage23/Makefile
+++ b/stage23/Makefile
@@ -4,6 +4,9 @@ OBJCOPY = i386-elf-objcopy
 OBJDUMP = i386-elf-objdump
 READELF = i386-elf-readelf
 
+COM_OUTPUT = false
+E9_OUTPUT = false
+
 BUILD_ID := $(shell dd if=/dev/urandom count=8 bs=1 | od -An -t x8 | sed 's/^ /0x/')
 LIMINE_VERSION := $(shell git describe --exact-match --tags `git log -n1 --pretty='%h'` || git log -n1 --pretty='%h')
 WERROR = -Werror
@@ -26,6 +29,8 @@ INTERNAL_CFLAGS = \
 	-MMD \
 	-DBUILD_ID=$(BUILD_ID) \
 	-DLIMINE_VERSION='"$(LIMINE_VERSION)"' \
+	-DCOM_OUTPUT=$(COM_OUTPUT) \
+	-DE9_OUTPUT=$(E9_OUTPUT) \
 	-I. \
 	-I..
 
diff --git a/stage23/lib/blib.c b/stage23/lib/blib.c
index 71325ec9..be43c562 100644
--- a/stage23/lib/blib.c
+++ b/stage23/lib/blib.c
@@ -22,7 +22,7 @@ extern symbol stage3_addr;
 extern symbol limine_sys_size;
 
 __attribute__((noreturn))
-void (*stage3)(void) = (void *)stage3_addr;
+void (*stage3)(int boot_from) = (void *)stage3_addr;
 
 bool stage3_init(struct volume *part) {
     struct file_handle stage3;
diff --git a/stage23/lib/blib.h b/stage23/lib/blib.h
index 54586682..f38e84de 100644
--- a/stage23/lib/blib.h
+++ b/stage23/lib/blib.h
@@ -49,7 +49,7 @@ typedef char symbol[];
 #define stage3_text __attribute__((section(".stage3_text")))
 #define stage3_data __attribute__((section(".stage3_data")))
 
-__attribute__((noreturn)) extern void (*stage3)(void);
+__attribute__((noreturn)) extern void (*stage3)(int boot_from);
 bool stage3_init(struct volume *part);
 
 #endif
diff --git a/stage23/lib/config.c b/stage23/lib/config.c
index c9c7fa9b..5c53c4db 100644
--- a/stage23/lib/config.c
+++ b/stage23/lib/config.c
@@ -16,6 +16,7 @@ bool config_ready = false;
 
 static char *config_addr;
 
+stage3_text
 int init_config_disk(struct volume *part) {
     struct file_handle f;
 
@@ -34,6 +35,7 @@ int init_config_disk(struct volume *part) {
     return init_config(config_size);
 }
 
+stage3_text
 int init_config_pxe(void) {
     struct tftp_file_handle cfg;
     if (tftp_open(&cfg, 0, 69, "limine.cfg")
@@ -52,6 +54,7 @@ int init_config_pxe(void) {
 #define DIRECT_CHILD   0
 #define INDIRECT_CHILD 1
 
+stage3_text
 static int is_child(char *buf, size_t limit,
                     size_t current_depth, size_t index) {
     if (!config_get_entry_name(buf, index, limit))
@@ -66,6 +69,7 @@ static int is_child(char *buf, size_t limit,
     return DIRECT_CHILD;
 }
 
+stage3_text
 static bool is_directory(char *buf, size_t limit,
                          size_t current_depth, size_t index) {
     switch (is_child(buf, limit, current_depth + 1, index + 1)) {
@@ -79,6 +83,7 @@ static bool is_directory(char *buf, size_t limit,
     }
 }
 
+stage3_text
 static struct menu_entry *create_menu_tree(struct menu_entry *parent,
                                            size_t current_depth, size_t index) {
     struct menu_entry *root = NULL, *prev = NULL;
@@ -126,6 +131,7 @@ static struct menu_entry *create_menu_tree(struct menu_entry *parent,
 
 struct menu_entry *menu_tree = NULL;
 
+stage3_text
 int init_config(size_t config_size) {
     // remove windows carriage returns, if any
     for (size_t i = 0; i < config_size; i++) {
@@ -143,6 +149,7 @@ int init_config(size_t config_size) {
     return 0;
 }
 
+stage3_text
 bool config_get_entry_name(char *ret, size_t index, size_t limit) {
     char *p = config_addr;
 
@@ -170,6 +177,7 @@ bool config_get_entry_name(char *ret, size_t index, size_t limit) {
     return true;
 }
 
+stage3_text
 char *config_get_entry(size_t *size, size_t index) {
     char *ret;
     char *p = config_addr;
@@ -205,6 +213,7 @@ cont:
     return ret;
 }
 
+stage3_text
 char *config_get_value(const char *config, size_t index, const char *key) {
     if (!key)
         return NULL;
diff --git a/stage23/lib/print.c b/stage23/lib/print.c
index fa6db87e..05c8cd45 100644
--- a/stage23/lib/print.c
+++ b/stage23/lib/print.c
@@ -3,14 +3,10 @@
 #include <stdint.h>
 #include <lib/print.h>
 #include <lib/blib.h>
-#include <lib/config.h>
 #include <lib/term.h>
 #include <lib/libc.h>
 #include <sys/cpu.h>
 
-static int e9_output = -1;
-static int com1_output = -1;
-
 static const char *base_digits = "0123456789abcdef";
 
 #define PRINT_BUF_MAX 512
@@ -119,26 +115,19 @@ void print(const char *fmt, ...) {
 static char print_buf[PRINT_BUF_MAX];
 
 void vprint(const char *fmt, va_list args) {
-    if (config_ready && e9_output == -1) {
-        char *e9_output_config = config_get_value(NULL, 0, "E9_OUTPUT");
-        e9_output = e9_output_config != NULL &&
-                    !strcmp(e9_output_config, "yes");
-    }
-    if (config_ready && com1_output == -1) {
-        char *com1_output_config = config_get_value(NULL, 0, "COM1_OUTPUT");
-        com1_output = com1_output_config != NULL &&
-                    !strcmp(com1_output_config, "yes");
-
-        if (com1_output == 1) {
-            // Init com1
-            outb(0x3F8 + 1, 0x00);
-            outb(0x3F8 + 3, 0x80);
-            outb(0x3F8 + 0, 0x01);
-            outb(0x3F8 + 1, 0x00);
-            outb(0x3F8 + 3, 0x03);
-            outb(0x3F8 + 2, 0xC7);
-            outb(0x3F8 + 4, 0x0B);
-        }
+    static bool com_initialised = false;
+
+    if (COM_OUTPUT && !com_initialised) {
+        // Init com1
+        outb(0x3F8 + 1, 0x00);
+        outb(0x3F8 + 3, 0x80);
+        outb(0x3F8 + 0, 0x01);
+        outb(0x3F8 + 1, 0x00);
+        outb(0x3F8 + 3, 0x03);
+        outb(0x3F8 + 2, 0xC7);
+        outb(0x3F8 + 4, 0x0B);
+
+        com_initialised = true;
     }
 
     size_t print_buf_i = 0;
@@ -198,9 +187,10 @@ out:
     term_write(print_buf, print_buf_i);
 
     for (size_t i = 0; i < print_buf_i; i++) {
-        if (e9_output == 1)
+        if (E9_OUTPUT) {
             outb(0xe9, print_buf[i]);
-        if (com1_output == 1) {
+        }
+        if (COM_OUTPUT) {
             if (print_buf[i] == '\n')
                 outb(0x3f8, '\r');
             outb(0x3f8, print_buf[i]);
diff --git a/stage23/main.c b/stage23/main.c
index 5f9c4d22..97c8ceba 100644
--- a/stage23/main.c
+++ b/stage23/main.c
@@ -48,53 +48,63 @@ void entry(uint8_t _boot_drive, int boot_from) {
     volume_create_index();
 
     switch (boot_from) {
-    case BOOT_FROM_HDD:
-    case BOOT_FROM_CD: {
-        print("Boot drive: %x\n", boot_drive);
-        struct volume boot_volume;
-        volume_get_by_coord(&boot_volume, boot_drive, -1);
-        struct volume part = boot_volume;
-        bool stage3_loaded = false, config_loaded = false;
-        for (int i = 0; ; i++) {
-            if (!stage3_loaded && stage3_init(&part)) {
-                stage3_loaded = true;
-                print("Stage 3 found and loaded.\n");
+        case BOOT_FROM_HDD:
+        case BOOT_FROM_CD: {
+            struct volume boot_volume;
+            volume_get_by_coord(&boot_volume, boot_drive, -1);
+            struct volume part = boot_volume;
+            for (int i = 0; ; i++) {
+                if (stage3_init(&part)) {
+                    print("Stage 3 found and loaded.\n");
+                    break;
+                }
+                int ret = part_get(&part, &boot_volume, i);
+                switch (ret) {
+                    case INVALID_TABLE:
+                    case END_OF_TABLE:
+                        panic("Stage 3 not found.");
+                }
             }
-            if (!config_loaded && !init_config_disk(&part)) {
-                config_loaded = true;
-                print("Config file found and loaded.\n");
-                boot_partition = i - 1;
-            }
-            int ret = part_get(&part, &boot_volume, i);
-            switch (ret) {
-                case INVALID_TABLE:
-                case END_OF_TABLE:
-                    goto break2;
-            }
-        }
-break2:
-        if (!stage3_loaded)
-            panic("Stage 3 not loaded.");
-        if (!config_loaded)
-            panic("Config file not found.");
-        break;
-    }
-
-    case BOOT_FROM_PXE:
-        pxe_init();
-        if (init_config_pxe()) {
-            panic("Failed to load config file");
+            break;
         }
-        print("Config loaded via PXE\n");
-        break;
     }
 
-    stage3();
+    stage3(boot_from);
 }
 
 __attribute__((noreturn))
 __attribute__((section(".stage3_entry")))
-void stage3_entry(void) {
+void stage3_entry(int boot_from) {
+    switch (boot_from) {
+        case BOOT_FROM_HDD:
+        case BOOT_FROM_CD: {
+            struct volume boot_volume;
+            volume_get_by_coord(&boot_volume, boot_drive, -1);
+            struct volume part = boot_volume;
+            for (int i = 0; ; i++) {
+                if (!init_config_disk(&part)) {
+                    print("Config file found and loaded.\n");
+                    boot_partition = i - 1;
+                    break;
+                }
+                int ret = part_get(&part, &boot_volume, i);
+                switch (ret) {
+                    case INVALID_TABLE:
+                    case END_OF_TABLE:
+                        panic("Config file not found.");
+                }
+            }
+            break;
+        case BOOT_FROM_PXE:
+            pxe_init();
+            if (init_config_pxe()) {
+                panic("Failed to load config file");
+            }
+            print("Config loaded via PXE\n");
+            break;
+        }
+    }
+
     char *cmdline;
     char *config = menu(&cmdline);
 
tab: 248 wrap: offon