1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-02-21 GuEe-GUI first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13
14 #define DBG_TAG "rtdm.mnt"
15 #define DBG_LVL DBG_INFO
16 #include <rtdbg.h>
17
18 #include <stdlib.h>
19 #include <dfs_fs.h>
20 #ifdef RT_USING_FINSH
21 #include <msh.h>
22 #endif
23 #include <ioremap.h>
24 #include <mm_memblock.h>
25
26 #ifdef RT_USING_OFW
27 #define bootargs_select rt_ofw_bootargs_select
28 #else
29 #error Platform have not kernel parameters select interfaces!
30 #endif
31
rootfs_mnt_init(void)32 static int rootfs_mnt_init(void)
33 {
34 rt_err_t err = -RT_ERROR;
35 void *fsdata = RT_NULL;
36 const char *cromfs_type = "crom";
37 const char *dev = bootargs_select("root=", 0);
38 const char *fstype = bootargs_select("rootfstype=", 0);
39 const char *rw = bootargs_select("rw", 0);
40
41 if (!dev || !fstype)
42 {
43 const char *name = "initrd";
44 rt_uint64_t initrd_start = 0, initrd_end = 0;
45 struct rt_mmblk_reg *iter = RT_NULL;
46
47 rt_slist_for_each_entry(iter, &(rt_memblock_get_reserved()->reg_list), node)
48 {
49 if (rt_strcmp(iter->memreg.name, name) == 0)
50 {
51 initrd_start = iter->memreg.start;
52 initrd_end = iter->memreg.end;
53 break;
54 }
55 }
56
57 if (initrd_start && initrd_end)
58 {
59 size_t initrd_size = initrd_end - initrd_start;
60
61 if ((fsdata = rt_ioremap_cached((void *)initrd_start, initrd_size)))
62 {
63 fstype = cromfs_type;
64 }
65 }
66 }
67
68 if (fstype != cromfs_type && dev)
69 {
70 rt_tick_t timeout = 0;
71 const char *rootwait, *rootdelay = RT_NULL;
72
73 rootwait = bootargs_select("rootwait", 0);
74
75 /* Maybe it is undefined or 'rootwaitABC' */
76 if (!rootwait || *rootwait)
77 {
78 rootdelay = bootargs_select("rootdelay=", 0);
79
80 if (rootdelay)
81 {
82 timeout = rt_tick_from_millisecond(atoi(rootdelay));
83 }
84
85 rootwait = RT_NULL;
86 }
87
88 /*
89 * Delays in boot flow is a terrible behavior in RTOS, but the RT-Thread
90 * SDIO framework init the devices in a task that we need to wait for
91 * SDIO devices to init complete...
92 *
93 * WHAT THE F*CK PROBLEMS WILL HAPPENED?
94 *
95 * Your main PE, applications, services that depend on the root FS and
96 * the multi cores setup, init will delay, too...
97 *
98 * So, you can try to link this function to `INIT_APP_EXPORT` even later
99 * and remove the delays if you want to optimize the boot time and mount
100 * the FS auto.
101 */
102 for (; rootdelay || rootwait; --timeout)
103 {
104 if (!rootwait && timeout == 0)
105 {
106 LOG_E("Wait for /dev/%s init time out", dev);
107
108 /*
109 * We don't return at once because the device driver may init OK
110 * when we break from this point, might as well give it another
111 * try.
112 */
113 break;
114 }
115
116 if (rt_device_find(dev))
117 {
118 break;
119 }
120
121 rt_thread_mdelay(1);
122 }
123 }
124
125 if (fstype)
126 {
127 if (!(err = dfs_mount(dev, "/", fstype, rw ? 0 : ~0, fsdata)))
128 {
129 LOG_I("Mount root %s%s type=%s %s",
130 (dev && *dev) ? "on /dev/" : "",
131 (dev && *dev) ? dev : "\b",
132 fstype, "done");
133 }
134 else
135 {
136 LOG_W("Mount root %s%s type=%s %s",
137 (dev && *dev) ? "on /dev/" : "",
138 (dev && *dev) ? dev : "\b",
139 fstype, "fail");
140
141 if (fstype == cromfs_type)
142 {
143 rt_iounmap(fsdata);
144 }
145 }
146 }
147
148 return 0;
149 }
150 INIT_ENV_EXPORT(rootfs_mnt_init);
151
fstab_mnt_init(void)152 static int fstab_mnt_init(void)
153 {
154 mkdir("/mnt", 0755);
155
156 #ifdef RT_USING_FINSH
157 /* Try mount by table */
158 msh_exec_script("fstab.sh", 16);
159 #endif
160
161 #ifdef RT_USING_DFS_PROCFS
162 mkdir("/proc", 0755);
163 dfs_mount(RT_NULL, "/proc", "procfs", 0, RT_NULL);
164 #endif
165
166 LOG_I("File system initialization done");
167
168 return 0;
169 }
170 INIT_FS_EXPORT(fstab_mnt_init);
171