mnt.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. #include <mm_memblock.h>
  22. #ifdef RT_USING_OFW
  23. #define bootargs_select rt_ofw_bootargs_select
  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_uint64_t initrd_start = 0, initrd_end = 0;
  39. struct rt_mmblk_reg *iter = RT_NULL;
  40. rt_slist_for_each_entry(iter, &(rt_memblock_get_reserved()->reg_list), node)
  41. {
  42. if (rt_strcmp(iter->memreg.name, name) == 0)
  43. {
  44. initrd_start = iter->memreg.start;
  45. initrd_end = iter->memreg.end;
  46. break;
  47. }
  48. }
  49. if (initrd_start && initrd_end)
  50. {
  51. size_t initrd_size = initrd_end - initrd_start;
  52. if ((fsdata = rt_ioremap_cached((void *)initrd_start, initrd_size)))
  53. {
  54. fstype = cromfs_type;
  55. }
  56. }
  57. }
  58. if (fstype != cromfs_type && dev)
  59. {
  60. rt_tick_t timeout = 0;
  61. const char *rootwait, *rootdelay = RT_NULL;
  62. rootwait = bootargs_select("rootwait", 0);
  63. /* Maybe it is undefined or 'rootwaitABC' */
  64. if (!rootwait || *rootwait)
  65. {
  66. rootdelay = bootargs_select("rootdelay=", 0);
  67. if (rootdelay)
  68. {
  69. timeout = rt_tick_from_millisecond(atoi(rootdelay));
  70. }
  71. rootwait = RT_NULL;
  72. }
  73. /*
  74. * Delays in boot flow is a terrible behavior in RTOS, but the RT-Thread
  75. * SDIO framework init the devices in a task that we need to wait for
  76. * SDIO devices to init complete...
  77. *
  78. * WHAT THE F*CK PROBLEMS WILL HAPPENED?
  79. *
  80. * Your main PE, applications, services that depend on the root FS and
  81. * the multi cores setup, init will delay, too...
  82. *
  83. * So, you can try to link this function to `INIT_APP_EXPORT` even later
  84. * and remove the delays if you want to optimize the boot time and mount
  85. * the FS auto.
  86. */
  87. for (; rootdelay || rootwait; --timeout)
  88. {
  89. if (!rootwait && timeout == 0)
  90. {
  91. LOG_E("Wait for /dev/%s init time out", dev);
  92. /*
  93. * We don't return at once because the device driver may init OK
  94. * when we break from this point, might as well give it another
  95. * try.
  96. */
  97. break;
  98. }
  99. if (rt_device_find(dev))
  100. {
  101. break;
  102. }
  103. rt_thread_mdelay(1);
  104. }
  105. }
  106. if (fstype)
  107. {
  108. if (!(err = dfs_mount(dev, "/", fstype, rw ? 0 : ~0, fsdata)))
  109. {
  110. LOG_I("Mount root %s%s type=%s %s",
  111. (dev && *dev) ? "on /dev/" : "",
  112. (dev && *dev) ? dev : "\b",
  113. fstype, "done");
  114. }
  115. else
  116. {
  117. LOG_W("Mount root %s%s type=%s %s",
  118. (dev && *dev) ? "on /dev/" : "",
  119. (dev && *dev) ? dev : "\b",
  120. fstype, "fail");
  121. if (fstype == cromfs_type)
  122. {
  123. rt_iounmap(fsdata);
  124. }
  125. }
  126. }
  127. return 0;
  128. }
  129. INIT_ENV_EXPORT(rootfs_mnt_init);
  130. static int fstab_mnt_init(void)
  131. {
  132. mkdir("/mnt", 0755);
  133. #ifdef RT_USING_FINSH
  134. /* Try mount by table */
  135. msh_exec_script("fstab.sh", 16);
  136. #endif
  137. LOG_I("File system initialization done");
  138. return 0;
  139. }
  140. INIT_FS_EXPORT(fstab_mnt_init);