feat: dynamic boot medium probing and mounting
authorMinep <lunaixsky@qq.com>
Sun, 18 Jun 2023 20:27:23 +0000 (21:27 +0100)
committerMinep <lunaixsky@qq.com>
Sun, 18 Jun 2023 20:27:23 +0000 (21:27 +0100)
fix: null pointer exception in usr/sh
fix: parameter passing by uwrapper

lunaix-os/config/make-os
lunaix-os/includes/lunaix/fs/iso9660.h
lunaix-os/includes/lunaix/fs/probe_boot.h [new file with mode: 0644]
lunaix-os/kernel/block/block.c
lunaix-os/kernel/fs/probe_boot.c [new file with mode: 0644]
lunaix-os/kernel/loader/exec.c
lunaix-os/kernel/proc0.c
lunaix-os/makefile.ker
lunaix-os/uprog/sh.c
lunaix-os/usr/uwrap.S

index 7ea5c01c025a090f4000a093c720bac4ca41b593..5cb285cc963f7946f14c34552c83f3c8c9500b90 100644 (file)
@@ -1,6 +1,8 @@
 OS_ARCH := x86
 OS_NAME := lunaix
+OS_ID := LunaixOS
+OS_VER := dev20230618
 OS_BIN := $(OS_NAME).bin
 OS_ISO := $(OS_NAME).iso
 
-USR_LIB := liblxusrt.a
\ No newline at end of file
+USR_LIB := liblxusrt.a
index 3392af3af8014ba715b12969e19e224fd94174b9..96e73385df2afa89361066db9d70f4a7abc1ceba 100644 (file)
 #define ISO_SIGNATURE_HI 0x31
 
 // Volume Types
-#define ISO_VOLBOOT 0   // Boot Record
-#define ISO_VOLPRIM 1   // Primary
-#define ISO_VOLSUPP 2   // Supplementary
-#define ISO_VOLPART 3   // Partition
-#define ISO_VOLTERM 255 // Volume descriptor set terminator
+#define ISO_VOLBOOT 0     // Boot Record
+#define ISO_VOLPRIM 1     // Primary
+#define ISO_VOLSUPP 2     // Supplementary
+#define ISO_VOLPART 3     // Partition
+#define ISO_VOLTERM 255   // Volume descriptor set terminator
 
 #define ISO_FHIDDEN 0x1   // a hidden file
 #define ISO_FDIR 0x2      // a directory file
@@ -36,6 +36,7 @@
 
 #define ISO9660_BLKSZ 2048
 #define ISO9660_IDLEN 256
+#define ISO9660_READ_OFF (ISO9660_BLKSZ * 16)
 
 // NOTES:
 // Each Descriptor sized 1 logical block (2048 bytes in common cases)
@@ -155,8 +156,8 @@ struct iso_drecord
     iso_bbo32_t data_size;
     struct iso_datetime2 PACKED mktime; // Time the record is made, see 9.1.5
     u8_t flags;
-    u8_t fu_sz;  // size of file unit (FU)
-    u8_t gap_sz; // size of gap if FU is interleaved.
+    u8_t fu_sz;                         // size of file unit (FU)
+    u8_t gap_sz;                        // size of gap if FU is interleaved.
     iso_bbo16_t vol_seq;
     struct iso_var_mdu name;
 } PACKED;
diff --git a/lunaix-os/includes/lunaix/fs/probe_boot.h b/lunaix-os/includes/lunaix/fs/probe_boot.h
new file mode 100644 (file)
index 0000000..4eb8e06
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __LUNAIX_PROBE_BOOT_H
+#define __LUNAIX_PROBE_BOOT_H
+
+#include <lunaix/device.h>
+
+struct device*
+probe_boot_medium();
+
+#endif /* __LUNAIX_PROBE_BOOT_H */
index 1cade0c78106650c595bcea492a4c399b1132214..f699169b01423e1ce7ddbf0be5447d13cf87e57e 100644 (file)
@@ -24,6 +24,7 @@ LOG_MODULE("BLOCK")
 static struct cake_pile* lbd_pile;
 static struct block_dev** dev_registry;
 static struct twifs_node* blk_sysroot;
+static struct device* blk_parent_dev;
 
 int free_slot = 0;
 
@@ -41,6 +42,7 @@ block_init()
     dev_registry = vcalloc(sizeof(struct block_dev*), MAX_DEV);
     free_slot = 0;
     blk_sysroot = twifs_dir_node(NULL, "block");
+    blk_parent_dev = device_addcat(NULL, "block");
 }
 
 int
@@ -314,7 +316,8 @@ __block_register(struct block_dev* bdev)
         return 0;
     }
 
-    struct device* dev = device_addvol(NULL, bdev, "sd%c", 'a' + free_slot);
+    struct device* dev =
+      device_addvol(blk_parent_dev, bdev, "sd%c", 'a' + free_slot);
     dev->write = __block_write;
     dev->write_page = __block_write_page;
     dev->read = __block_read;
diff --git a/lunaix-os/kernel/fs/probe_boot.c b/lunaix-os/kernel/fs/probe_boot.c
new file mode 100644 (file)
index 0000000..69af61e
--- /dev/null
@@ -0,0 +1,50 @@
+#include <lunaix/fs/iso9660.h>
+#include <lunaix/fs/probe_boot.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/syslog.h>
+
+LOG_MODULE("PROBE")
+
+#define LUNAIX_ID 0x414e554cUL // "LUNA"
+
+struct device*
+probe_boot_medium()
+{
+    struct device* block_cat = device_getbyname(NULL, "block", 5);
+    if (!block_cat) {
+        return NULL;
+    }
+
+    struct iso_vol_primary* volp = valloc(ISO9660_BLKSZ);
+
+    struct device *pos, *n;
+    llist_for_each(pos, n, &block_cat->children, siblings)
+    {
+        int errno =
+          pos->read(pos, (void*)volp, ISO9660_READ_OFF, ISO9660_BLKSZ);
+        if (errno < 0) {
+            kprintf(KWARN "can not probe %x:%s (%d)\n",
+                    pos->dev_id,
+                    pos->name.value,
+                    errno);
+            pos = NULL;
+            goto done;
+        }
+
+        if (*(u32_t*)volp->header.std_id != ISO_SIGNATURE_LO) {
+            continue;
+        }
+
+        if (*(u32_t*)volp->sys_id == LUNAIX_ID) {
+            kprintf(KINFO "[%x:%s] %s\n",
+                    pos->dev_id,
+                    pos->name.value,
+                    (char*)volp->vol_id);
+            break;
+        }
+    }
+
+done:
+    vfree(volp);
+    return pos;
+}
\ No newline at end of file
index e5e64fe30d22e0174c918bbb3b5f6399451d02dd..6a18ffca11d91bdbeec592bd7b84689266473f11 100644 (file)
@@ -26,11 +26,11 @@ exec_str_size(const char** str_arr, size_t* length)
         sz += strlen(chr);
         len++;
 
-        chr = *(str_arr + sz);
+        chr = *(str_arr++);
     }
 
     *length = len;
-    return sz + 1;
+    return sz + sizeof(char*);
 }
 
 void
@@ -116,7 +116,7 @@ exec_load(struct ld_param* param,
             memcpy(arg_start + sz_argv, (void*)envp, sz_envp);
 
         ptr_t* ustack = (ptr_t*)USTACK_TOP;
-        struct usr_exec_param* exec_param = mapped;
+        struct usr_exec_param* exec_param = (struct usr_exec_param*)mapped;
 
         ustack[-1] = (ptr_t)mapped;
         param->info.stack_top = &ustack[-1];
index abd0ac0df4f3d925a6f7f171b2f8d9e67f4a37f7..c38ad2bc2517f340c5f55f2d8a84cd2a892a5d8f 100644 (file)
@@ -2,6 +2,7 @@
 #include <lunaix/common.h>
 #include <lunaix/foptions.h>
 #include <lunaix/fs.h>
+#include <lunaix/fs/probe_boot.h>
 #include <lunaix/fs/twifs.h>
 #include <lunaix/ld.h>
 #include <lunaix/lxconsole.h>
@@ -48,14 +49,14 @@ mount_bootmedium()
 {
     struct v_dnode* dnode;
     int errno = 0;
-    if ((errno = vfs_walk_proc("/dev/sdb", &dnode, NULL, 0))) {
+    struct device* dev = probe_boot_medium();
+    if (!dev) {
         kprintf(KERROR "fail to acquire device. (%d)", errno);
         return 0;
     }
 
-    struct device* dev = (struct device*)dnode->inode->data;
     if ((errno = vfs_mount("/mnt/lunaix-os", "iso9660", dev, 0))) {
-        kprintf(KERROR "fail to boot medium. (%d)", errno);
+        kprintf(KERROR "fail to mount boot medium. (%d)", errno);
         return 0;
     }
 
index 8411140bd62cfcfce5b42b9ba195b51129b00136..05dcc13d3a691f3190a86514a59e78d024ce44fe 100644 (file)
@@ -31,7 +31,7 @@ $(BUILD_DIR)/$(OS_ISO): $(BIN_DIR)/$(OS_BIN)
        @./config-grub.sh ${OS_NAME} $(ISO_GRUB_DIR)/grub.cfg
        @cp $(BIN_DIR)/$(OS_BIN) $(ISO_BOOT_DIR)
        @cp -r $(USR_DIR) $(ISO_DIR)
-       @grub-mkrescue -o $(BUILD_DIR)/$(OS_ISO) $(ISO_DIR)
+       @grub-mkrescue -o $(BUILD_DIR)/$(OS_ISO) $(ISO_DIR) -- -volid "$(OS_ID) $(OS_VER)" -system_id "$(OS_NAME)"
 
 all: $(BUILD_DIR)/$(OS_ISO)
 
index 4e0c6f6cb8d8571d8e8ce27256e687b18be48d23..10aed0b57ad4570f9222812bed4094291d840e60 100644 (file)
@@ -60,7 +60,11 @@ parse_cmdline(char* line, char** cmd, char** arg_part)
         l++;
     }
     *cmd = line;
-    *arg_part = strltrim_safe(line + l);
+    if (c) {
+        *arg_part = strltrim_safe(line + l);
+    } else {
+        *arg_part = NULL;
+    }
 }
 
 void
@@ -134,25 +138,34 @@ sh_loop()
     // stdout (by default, unless user did smth) is the tty we are currently at
     ioctl(stdout, TIOCSPGRP, getpgid());
 
+    char* argv[] = { 0, 0 };
+
     while (1) {
         getcwd(pwd, 512);
         printf("[\033[2m%s\033[39;49m]$ ", pwd);
         size_t sz = read(stdin, buf, 511);
+
         if (sz < 0) {
             printf("fail to read user input (%d)\n", geterrno());
             return;
         }
+
         buf[sz] = '\0';
-        parse_cmdline(buf, &cmd, &argpart);
+
+        // currently, this shell only support single argument
+        parse_cmdline(buf, &cmd, &argv[0]);
+
         if (cmd[0] == 0) {
             printf("\n");
             goto cont;
         }
+
         // cmd=="exit"
         if (*(unsigned int*)cmd == 0x74697865U) {
             break;
         }
-        sh_exec(cmd, NULL);
+
+        sh_exec(cmd, (const char**)&argv);
     cont:
         printf("\n");
     }
index 5708463653a63d0564a37ba16f3d3899dabc68b9..c9e2bbc20aa9a43ec6c512b3c9d27e59563ca11c 100644 (file)
@@ -9,13 +9,15 @@
 .section .text
     .global _u_start
     _u_start:
+        movl (%esp), %eax
+        pushl %eax
         call usr_pre_init
         jnz 1f
 
         popl %eax
 
-        pushl (%eax)    // argc
         pushl 4(%eax)   // argv
+        pushl (%eax)    // argc
         
         xorl %eax, %eax
         call main