@@ -5,7 +5,7 @@ categories:
55 - 内核层
66abbrlink : 4936fe45
77date : 2025-05-19 12:50:00
8- updated : 2025-06-03 18:10 :00
8+ updated : 2025-06-04 12:05 :00
99---
1010
1111<meta name =" referrer " content =" no-referrer " />
@@ -562,15 +562,21 @@ rtems_filesystem_register() 的执行流程图如下:
562562
563563``` mermaid
564564flowchart TD
565- A[开始, 调用 rtems_filesystem_register, 传入 type 和挂载函数] --> B[计算 type 长度, 分配节点内存]
566- B --> C{内存分配成功吗}
567- C -- 否 --> D[设置 errno ENOMEM, 返回失败]
568- C -- 是 --> E[复制 type 字符串, 绑定挂载函数]
569- E --> F[加锁, 进入临界区]
570- F --> G{type 已经注册吗}
571- G -- 否 --> H[初始化节点, 加入链表]
572- H --> I[解锁, 退出临界区, 返回成功]
573- G -- 是 --> J[解锁, 退出临界区, 释放内存, 设置 errno EINVAL, 返回失败]
565+ A[开始 rtems_filesystem_register] --> B[计算 type_size 与 fsn_size 并 malloc 分配 fsn]
566+ B --> C{fsn 是否为 NULL?}
567+ C -- 是 --> D[设置 errno 等于 ENOMEM 并返回 -1]
568+ C -- 否 --> E[计算 type_storage 并 memcpy 复制类型字符串]
569+ E --> F[设置 fsn->entry.type 等于 type_storage]
570+ F --> G[设置 fsn->entry.mount_h 等于 mount_h]
571+ G --> H[rtems_libio_lock 进入临界区]
572+ H --> I{rtems_filesystem_get_mount_handler 判断 type 是否已注册}
573+ I -- 未注册 --> J[rtems_chain_initialize_node 初始化链表节点]
574+ J --> K[rtems_chain_append_unprotected 将 fsn 添加到全局链表]
575+ K --> L[rtems_libio_unlock 解锁]
576+ L --> M[返回 0 注册成功]
577+ I -- 已注册 --> N[rtems_libio_unlock 解锁]
578+ N --> O[free fsn 释放内存]
579+ O --> P[设置 errno 等于 EINVAL 并返回 -1]
574580```
575581
576582#### struct filesystem_node
@@ -727,6 +733,68 @@ flowchart TD
727733 K -->|注册 失败| M[调用 fsunmount, 卸载, 释放挂载表项, 返回 -1]
728734```
729735
736+ ## IMFS 文件系统
737+
738+ IMFS(In‐Memory File System)是 Rtems 提供的一个内存文件系统。它将文件和目录全部存储在 RAM 中,为嵌入式应用提供快速、轻量级的 POSIX 风格文件操作接口;其核心模块负责管理目录树结构、路径解析和文件读写逻辑,而底层的节点分配与销毁、元数据初始化等则通过回调函数(如 node_initialize、node_remove、node_destroy)由系统默认实现或用户自定义实现来完成,使得 IMFS 在不修改主体框架的情况下能够灵活适配不同内存布局或特殊需求,启动时通过 IMFS_initialize 自动注册并挂载为根文件系统,用户即可直接使用标准的 open/read/write/close 等接口访问内存中存储的文件。
739+
740+ ### rtems_filesystem_get_mount_handler()
741+
742+ 在 rtems_filesystem_register() 中,有一步是调用 rtems_filesystem_get_mount_handler 函数判断节点类型是否注册。这不仅让我们联想到,可能 Rtems 内部维护了一张全局表,专门用于记录目前已挂载的文件系统的信息。
743+
744+ rtems_filesystem_get_mount_handler() 的执行流程如下。
745+
746+ ``` mermaid
747+ flowchart TD
748+ A[开始 rtems_filesystem_get_mount_handler] --> B{type 为空?}
749+ B -- 是 --> C[返回 NULL]
750+ B -- 否 --> D[遍历表 rtems_filesystem_table]
751+ D --> E{表项匹配?}
752+ E -- 是 --> F[返回对应 mount_h]
753+ E -- 否 --> G[遍历表 filesystem_chain]
754+ G --> H{表项匹配?}
755+ H -- 是 --> I[返回对应 mount_h]
756+ H -- 否 --> J[返回 NULL]
757+ ```
758+
759+ 在 rtems_filesystem_iterate 函数中,可以发现 Rtems 定义了全局的两个表 filesystem_chain 和 rtems_filesystem_table。源码中无法直接跳转 filesystem_chain,目前无法得知他的具体状况。
760+
761+ ``` c
762+ rtems_chain_control *chain = &filesystem_chain;
763+
764+ const rtems_filesystem_table_t *table_entry = &rtems_filesystem_table[0 ];
765+ ```
766+
767+ 关于 rtems_filesystem_table,它用于表示挂载的文件系统的信息,并且猜测大概率是预挂载的文件系统的信息。定义如下:
768+
769+ ``` c
770+ const rtems_filesystem_table_t rtems_filesystem_table[] = {
771+ {"/", IMFS_initialize_support},
772+ #ifdef CONFIGURE_FILESYSTEM_DOSFS
773+ {RTEMS_FILESYSTEM_TYPE_DOSFS, rtems_dosfs_initialize},
774+ #endif
775+ #ifdef CONFIGURE_FILESYSTEM_FTPFS
776+ {RTEMS_FILESYSTEM_TYPE_FTPFS, rtems_ftpfs_initialize},
777+ #endif
778+ #ifdef CONFIGURE_FILESYSTEM_IMFS
779+ {RTEMS_FILESYSTEM_TYPE_IMFS, IMFS_initialize},
780+ #endif
781+ #ifdef CONFIGURE_FILESYSTEM_JFFS2
782+ {RTEMS_FILESYSTEM_TYPE_JFFS2, rtems_jffs2_initialize},
783+ #endif
784+ #ifdef CONFIGURE_FILESYSTEM_NFS
785+ {RTEMS_FILESYSTEM_TYPE_NFS, rtems_nfs_initialize},
786+ #endif
787+ #ifdef CONFIGURE_FILESYSTEM_RFS
788+ {RTEMS_FILESYSTEM_TYPE_RFS, rtems_rfs_rtems_initialise},
789+ #endif
790+ #ifdef CONFIGURE_FILESYSTEM_TFTPFS
791+ {RTEMS_FILESYSTEM_TYPE_TFTPFS, rtems_tftpfs_initialize},
792+ #endif
793+ {NULL, NULL}};
794+ ```
795+
796+ TODO
797+
730798# 参考文档
731799
7328001. [RTEMS Filesystem Design Guide (6.1). — RTEMS Filesystem Design Guide 6.1 (22nd January 2025) documentation](https://docs.rtems.org/docs/6.1/filesystem/index.html)
0 commit comments