瀏覽代碼

[Feature] DFS mount auto by kernel parameters (#8989)

DFS mount auto by kernel parameters

1.Mount the rootfs options by parameters:
- root=: root device, like vda1, sda1, sd0p1, nvme0n0p1...
- rootfstype=: root file system type, like elm, ext, crom...
- rw/ro: root is readonly or all enable, if not have 'rw' flag,
         the 'ro' flag is default.
- rootwait: always wait for root device status is OK.
- rootdelay=: mount rootfs delay amount of time (millisecond).

2.Mount the other fs options by `fstab.sh`, it will read the script
after root mount is OK, it's format is a list of mount cmds in MSH:

mount vda2 /mnt elm
mount 192.168.1.1:/ /mnt/remote nfs

Signed-off-by: GuEe-GUI <2991707448@qq.com>
GUI 11 月之前
父節點
當前提交
754c59a411
共有 2 個文件被更改,包括 175 次插入0 次删除
  1. 3 0
      components/drivers/core/SConscript
  2. 172 0
      components/drivers/core/mnt.c

+ 3 - 0
components/drivers/core/SConscript

@@ -10,6 +10,9 @@ if GetDepend(['RT_USING_DEV_BUS']) or GetDepend(['RT_USING_DM']):
 if GetDepend(['RT_USING_DM']):
     src = src + ['dm.c', 'driver.c', 'platform.c']
 
+    if GetDepend(['RT_USING_DFS']):
+        src += ['mnt.c'];
+
 if GetDepend(['RT_USING_OFW']):
     src += ['platform_ofw.c']
 

+ 172 - 0
components/drivers/core/mnt.c

@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-02-21     GuEe-GUI     first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "rtdm.mnt"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <stdlib.h>
+#include <dfs_fs.h>
+#ifdef RT_USING_FINSH
+#include <msh.h>
+#endif
+#include <ioremap.h>
+
+#ifdef RT_USING_OFW
+#define bootargs_select rt_ofw_bootargs_select
+#define memregion_request rt_fdt_commit_memregion_request
+#else
+#error Platform have not kernel parameters select interfaces!
+#endif
+
+static int rootfs_mnt_init(void)
+{
+    rt_err_t err = -RT_ERROR;
+    void *fsdata = RT_NULL;
+    const char *cromfs_type = "crom";
+    const char *dev = bootargs_select("root=", 0);
+    const char *fstype = bootargs_select("rootfstype=", 0);
+    const char *rw = bootargs_select("rw", 0);
+
+    if (!dev || !fstype)
+    {
+        const char *name = "initrd";
+        rt_size_t mem_region_nr;
+        rt_region_t *mem_region;
+        rt_uint64_t initrd_start = 0, initrd_end = 0;
+
+        if (!memregion_request(&mem_region, &mem_region_nr, RT_TRUE))
+        {
+            while (mem_region_nr-- > 0)
+            {
+                if (mem_region->name == name || !rt_strcmp(mem_region->name, name))
+                {
+                    initrd_start = mem_region->start;
+                    initrd_end = mem_region->end;
+
+                    break;
+                }
+
+                mem_region++;
+            }
+        }
+
+        if (initrd_start && initrd_end)
+        {
+            size_t initrd_size = initrd_end - initrd_start;
+
+            if ((fsdata = rt_ioremap_cached((void *)initrd_start, initrd_size)))
+            {
+                fstype = cromfs_type;
+            }
+        }
+    }
+
+    if (fstype != cromfs_type && dev)
+    {
+        rt_tick_t timeout = 0;
+        const char *rootwait, *rootdelay = RT_NULL;
+
+        rootwait = bootargs_select("rootwait", 0);
+
+        /* Maybe it is undefined or 'rootwaitABC' */
+        if (!rootwait || *rootwait)
+        {
+            rootdelay = bootargs_select("rootdelay=", 0);
+
+            if (rootdelay)
+            {
+                timeout = rt_tick_from_millisecond(atoi(rootdelay));
+            }
+
+            rootwait = RT_NULL;
+        }
+
+        /*
+         * Delays in boot flow is a terrible behavior in RTOS, but the RT-Thread
+         * SDIO framework init the devices in a task that we need to wait for
+         * SDIO devices to init complete...
+         *
+         * WHAT THE F*CK PROBLEMS WILL HAPPENED?
+         *
+         * Your main PE, applications, services that depend on the root FS and
+         * the multi cores setup, init will delay, too...
+         *
+         * So, you can try to link this function to `INIT_APP_EXPORT` even later
+         * and remove the delays if you want to optimize the boot time and mount
+         * the FS auto.
+         */
+        for (; rootdelay || rootwait; --timeout)
+        {
+            if (!rootwait && timeout == 0)
+            {
+                LOG_E("Wait for /dev/%s init time out", dev);
+
+                /*
+                 * We don't return at once because the device driver may init OK
+                 * when we break from this point, might as well give it another
+                 * try.
+                 */
+                break;
+            }
+
+            if (rt_device_find(dev))
+            {
+                break;
+            }
+
+            rt_thread_mdelay(1);
+        }
+    }
+
+    if (fstype)
+    {
+        if (!(err = dfs_mount(dev, "/", fstype, rw ? 0 : ~0, fsdata)))
+        {
+            LOG_I("Mount root %s%s type=%s %s",
+                (dev && *dev) ? "on /dev/" : "",
+                (dev && *dev) ? dev : "\b",
+                fstype, "done");
+        }
+        else
+        {
+            LOG_W("Mount root %s%s type=%s %s",
+                (dev && *dev) ? "on /dev/" : "",
+                (dev && *dev) ? dev : "\b",
+                fstype, "fail");
+
+            if (fstype == cromfs_type)
+            {
+                rt_iounmap(fsdata);
+            }
+        }
+    }
+
+    return 0;
+}
+INIT_ENV_EXPORT(rootfs_mnt_init);
+
+static int fstab_mnt_init(void)
+{
+    mkdir("/mnt", 0755);
+
+#ifdef RT_USING_FINSH
+    /* Try mount by table */
+    msh_exec_script("fstab.sh", 16);
+#endif
+
+    LOG_I("File system initialization done");
+
+    return 0;
+}
+INIT_FS_EXPORT(fstab_mnt_init);