:: commit 42325aed4a0cb090e39650cd89392680325de0f0

mintsuki <mintsuki@protonmail.com> — 2020-01-22 06:13

parents: 48ce450aa1

Add config file parsing

diff --git a/src/lib/blib.c b/src/lib/blib.c
index 6e20c0b9..5d7635c0 100644
--- a/src/lib/blib.c
+++ b/src/lib/blib.c
@@ -5,6 +5,13 @@
 #include <drivers/vga_textmode.h>
 #include <lib/real.h>
 
+uint64_t strtoui(const char *s) {
+    uint64_t n = 0;
+    while (*s)
+        n = n * 10 + ((*(s++)) - '0');
+    return n;
+}
+
 char getchar(void) {
     struct rm_regs r = {0};
     rm_int(0x16, &r, &r);
diff --git a/src/lib/blib.h b/src/lib/blib.h
index 0cba0693..dd27a00d 100644
--- a/src/lib/blib.h
+++ b/src/lib/blib.h
@@ -6,6 +6,7 @@
 void print(const char *fmt, ...);
 char getchar(void);
 void gets(char *buf, size_t limit);
+uint64_t strtoui(const char *s);
 
 #define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b))
 
diff --git a/src/lib/config.c b/src/lib/config.c
new file mode 100644
index 00000000..5aebb806
--- /dev/null
+++ b/src/lib/config.c
@@ -0,0 +1,30 @@
+#include <stddef.h>
+#include <lib/config.h>
+#include <lib/libc.h>
+
+#define SEPARATOR '\n'
+
+char *config_get_value(char *buf, size_t limit, const char *config, const char *key) {
+    if (!limit || !buf)
+        return NULL;
+
+    size_t key_len = strlen(key);
+
+    for (size_t i = 0; config[i]; i++) {
+        if (!strncmp(&config[i], key, key_len) && config[i + key_len] == '=') {
+            if (i && config[i - 1] != SEPARATOR)
+                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;
+            return buf;
+        }
+    }
+
+    return NULL;
+}
diff --git a/src/lib/config.h b/src/lib/config.h
new file mode 100644
index 00000000..0f486a2f
--- /dev/null
+++ b/src/lib/config.h
@@ -0,0 +1,8 @@
+#ifndef __LIB__CONFIG_H__
+#define __LIB__CONFIG_H__
+
+#include <stddef.h>
+
+char *config_get_value(char *buf, size_t limit, const char *config, const char *key);
+
+#endif
diff --git a/src/main.c b/src/main.c
index 449d38c1..bb7b412a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -9,12 +9,15 @@ asm (
 #include <lib/real.h>
 #include <lib/blib.h>
 #include <lib/mbr.h>
+#include <lib/config.h>
 #include <fs/echfs.h>
 
+#define CONFIG_NAME "qloader2.cfg"
+
 extern symbol bss_begin;
 extern symbol bss_end;
 
-#define QWORD_KERNEL "qword.bin"
+static int config_loaded = 0;
 
 void main(int boot_drive) {
     // Zero out .bss section
@@ -24,30 +27,49 @@ void main(int boot_drive) {
     // Initial prompt.
     init_vga_textmode();
     print("qLoader 2\n\n");
-    print("=> Boot drive: %x\n\n", boot_drive);
+    print("=> Boot drive: %x\n", boot_drive);
 
     // Enumerate partitions.
     struct mbr_part parts[4];
     for (int i = 0; i < 4; i++) {
-        print("=> Checking for partition %d...", i);
+        print("=> Checking for partition %d...\n", i);
         int ret = mbr_get_part(&parts[i], boot_drive, i);
         if (ret) {
-            print("Not found!\n");
+            print("   Not found!\n");
         } else {
-            print("Found!\n");
+            print("   Found!\n");
+            if (!config_loaded) {
+                if (!load_echfs_file(boot_drive, i, (void *)0x100000, CONFIG_NAME)) {
+                    config_loaded = 1;
+                    print("   Config file found and loaded!\n");
+                }
+            }
         }
     }
 
-    // Load the file from the chooen partition at 1 MiB.
-    int part = 1; // TODO: The boot partition is hardcoded for now.
-    print("=> Booting %s in partition %d\n", QWORD_KERNEL, part);
-    load_echfs_file(boot_drive, part, (void *)0x100000, QWORD_KERNEL);
+    int drive, part;
+    char path[128], cmdline[128];
+
+    if (config_loaded) {
+        char buf[32];
+        config_get_value(buf, 32, (void*)0x100000, "KERNEL_DRIVE");
+        drive = (int)strtoui(buf);
+        config_get_value(buf, 32, (void*)0x100000, "KERNEL_PARTITION");
+        part = (int)strtoui(buf);
+        config_get_value(path, 128, (void*)0x100000, "KERNEL_PATH");
+        config_get_value(cmdline, 128, (void*)0x100000, "KERNEL_CMDLINE");
+    } else {
+        print("   !! NO CONFIG FILE FOUND ON BOOT DRIVE !!");
+        for (;;);
+    }
+
+    load_echfs_file(drive, part, (void *)0x100000, path);
 
     // Boot the kernel.
     asm volatile (
         "jmp 0x100000"
         :
-        : "b" ("")
+        : "b" (cmdline)
         : "memory"
     );
 }
tab: 248 wrap: offon