mnt.c 4.3 KB

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