Skip to content

Commit 30bfe6a

Browse files
committed
start reconstructing rtems-source-code
1 parent aa2a2ad commit 30bfe6a

File tree

1 file changed

+79
-92
lines changed

1 file changed

+79
-92
lines changed

为了工作/Linux/内核层/Rtems Source Code.md

Lines changed: 79 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ categories:
55
- 内核层
66
abbrlink: 4936fe45
77
date: 2025-05-19 12:50:00
8-
updated: 2025-06-02 17:15:00
8+
updated: 2025-06-03 12:20:00
99
---
1010

1111
<meta name="referrer" content="no-referrer"/>
@@ -26,38 +26,21 @@ RTEMS(Real‑Time Executive for Multiprocessor Systems)是一款始于 1988
2626

2727
### open()
2828

29-
open() 函数的源码如下:
30-
31-
```c
32-
int open(const char *path, int oflag, ...)
33-
{
34-
int rv = 0;
35-
va_list ap;
36-
mode_t mode = 0;
37-
rtems_libio_t *iop = NULL;
38-
39-
// 处理可变参数,获取文件创建模式(mode)。
40-
va_start(ap, oflag);
41-
mode = va_arg(ap, mode_t);
42-
43-
// 分配一个文件描述符结构。
44-
iop = rtems_libio_allocate();
45-
if (iop != NULL)
46-
{
47-
// 调用底层实现打开文件。
48-
rv = do_open(iop, path, oflag, mode);
49-
}
50-
else
51-
{
52-
// 文件描述符耗尽,设置错误码。
53-
errno = ENFILE;
54-
rv = -1;
55-
}
56-
57-
va_end(ap);
58-
59-
return rv;
60-
}
29+
open() 函数的调用流程图如下:
30+
31+
```mermaid
32+
flowchart TD
33+
A[开始 open 函数] --> B[初始化变量 rv=0, mode=0, iop=NULL]
34+
B --> C[va_start 开始处理可变参数]
35+
C --> D[获取 mode 参数]
36+
D --> E{是否成功分配 iop}
37+
E -- 是 --> F[调用 do_open 打开文件]
38+
F --> G[设置 rv 为 do_open 返回值]
39+
E -- 否 --> H[设置 errno = ENFILE]
40+
H --> I[rv = -1]
41+
G --> J[va_end 结束可变参数处理]
42+
I --> J
43+
J --> K[返回 rv]
6144
```
6245

6346
#### struct rtems_libio_t
@@ -121,23 +104,57 @@ typedef struct rtems_filesystem_location_info_tt
121104
比较重要的成员是 `const rtems_filesystem_file_handlers_r *handlers`,该结构类似于 Linux 内核中的 file_operations,定义如下:
122105

123106
```c
107+
/**
108+
* @brief File system node operations table.
109+
*/
124110
struct _rtems_filesystem_file_handlers_r
125111
{
112+
// 打开文件的处理函数指针。
126113
rtems_filesystem_open_t open_h;
114+
115+
// 关闭文件的处理函数指针。
127116
rtems_filesystem_close_t close_h;
117+
118+
// 读取文件的处理函数指针。
128119
rtems_filesystem_read_t read_h;
120+
121+
// 写入文件的处理函数指针。
129122
rtems_filesystem_write_t write_h;
123+
124+
// 控制操作(如设备控制)的处理函数指针。
130125
rtems_filesystem_ioctl_t ioctl_h;
126+
127+
// 文件位置指针移动(如 lseek)的处理函数指针。
131128
rtems_filesystem_lseek_t lseek_h;
129+
130+
// 获取文件状态信息的处理函数指针。
132131
rtems_filesystem_fstat_t fstat_h;
132+
133+
// 截断文件大小的处理函数指针。
133134
rtems_filesystem_ftruncate_t ftruncate_h;
135+
136+
// 将文件缓冲区数据同步到存储设备的处理函数指针。
134137
rtems_filesystem_fsync_t fsync_h;
138+
139+
// 同步文件数据(但不一定包括元数据)的处理函数指针。
135140
rtems_filesystem_fdatasync_t fdatasync_h;
141+
142+
// 文件控制(如修改文件描述符属性)的处理函数指针。
136143
rtems_filesystem_fcntl_t fcntl_h;
144+
145+
// 轮询文件状态(如是否可读写)的处理函数指针。
137146
rtems_filesystem_poll_t poll_h;
147+
148+
// 用于事件过滤(BSD kqueue)的处理函数指针。
138149
rtems_filesystem_kqfilter_t kqfilter_h;
150+
151+
// 读取多个缓冲区(向量读)的处理函数指针。
139152
rtems_filesystem_readv_t readv_h;
153+
154+
// 写入多个缓冲区(向量写)的处理函数指针。
140155
rtems_filesystem_writev_t writev_h;
156+
157+
// 内存映射文件的处理函数指针。
141158
rtems_filesystem_mmap_t mmap_h;
142159
};
143160
```
@@ -266,42 +283,22 @@ struct _rtems_filesystem_operations_table
266283

267284
#### rtems_libio_allocate()
268285

269-
open 函数中分配文件描述符结构使用的函数是 rtems_libio_allocate(),定义如下:
270-
271-
```c
272-
rtems_libio_t *rtems_libio_allocate(void)
273-
{
274-
rtems_libio_t *iop;
275-
276-
// 加锁,保护全局空闲链表。
277-
rtems_libio_lock();
278-
279-
// 从空闲链表头获取一个可用的文件描述符结构。
280-
iop = rtems_libio_iop_free_head;
281-
282-
if (iop != NULL)
283-
{
284-
void *next;
285-
286-
// 获取下一个空闲节点。
287-
next = iop->data1;
288-
289-
// 更新空闲链表头指针。
290-
rtems_libio_iop_free_head = next;
291-
292-
// 如果空闲链表已空,更新尾指针。
293-
if (next == NULL)
294-
{
295-
rtems_libio_iop_free_tail = &rtems_libio_iop_free_head;
296-
}
297-
}
298-
299-
// 解锁,释放对空闲链表的访问。
300-
rtems_libio_unlock();
301-
302-
// 返回分配到的文件描述符结构(可能为 NULL)。
303-
return iop;
304-
}
286+
open 函数中分配文件描述符结构使用的函数是 rtems_libio_allocate(),执行流程图如下:
287+
288+
```mermaid
289+
flowchart TD
290+
A[开始 rtems_libio_allocate 函数] --> B[加锁保护空闲链表]
291+
B --> C[从空闲链表头获取 iop]
292+
C --> D{iop 是否为 NULL?}
293+
D -- 否 --> E[获取 iop->data1 到 next]
294+
E --> F[更新空闲链表头指针为 next]
295+
F --> G{next 是否为 NULL}
296+
G -- 是 --> H[更新尾指针为 &rtems_libio_iop_free_head]
297+
G -- 否 --> I[不操作]
298+
D -- 是 --> I
299+
H --> J[解锁释放访问]
300+
I --> J
301+
J --> K[返回 iop]
305302
```
306303

307304
##### rtems_libio_iop_free_head
@@ -314,29 +311,19 @@ rtems_libio_iop_free_head 是一个全局变量,用于维护 Rtems 文件描
314311

315312
初始化阶段的函数逻辑如下:
316313

317-
```c
318-
static void rtems_libio_init(void)
319-
{
320-
uint32_t i;
321-
rtems_libio_t *iop;
322-
323-
// 如果 I/O 对象数量大于 0,才进行初始化。
324-
if (rtems_libio_number_iops > 0)
325-
{
326-
// 把空闲链表的头指针指向数组中第一个 I/O 对象。
327-
iop = rtems_libio_iop_free_head = &rtems_libio_iops[0];
328-
329-
// 把当前 I/O 对象的 data1 成员指向数组中的下一个 I/O 对象,实现链表链接。
330-
for (i = 0; (i + 1) < rtems_libio_number_iops; i++, iop++)
331-
iop->data1 = iop + 1;
332-
333-
// 最后一个 I/O 对象的 data1 设置为 NULL,表示链表末尾。
334-
iop->data1 = NULL;
335-
336-
// 记录链表尾部指针,指向最后一个 I/O 对象的 data1 成员地址。
337-
rtems_libio_iop_free_tail = &iop->data1;
338-
}
339-
}
314+
```mermaid
315+
flowchart TD
316+
A[开始 rtems_libio_init 函数] --> B{rtems_libio_number_iops > 0?}
317+
B -- 否 --> Z[结束函数]
318+
B -- 是 --> C[设置空闲链表头指针]
319+
C --> D[初始化循环变量 i = 0]
320+
D --> E{i + 1 < rtems_libio_number_iops?}
321+
E -- 是 --> F[设置 iop->data1 = iop + 1]
322+
F --> G[i++, iop++]
323+
G --> E
324+
E -- 否 --> H[设置最后一个 iop->data1 = NULL]
325+
H --> I[设置链表尾指针 rtems_libio_iop_free_tail = &iop->data1]
326+
I --> Z
340327
```
341328

342329
rtems_libio_iops 是 Rtems 预先分配的 I/O 控制块数组,配置了 CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 以后,会预先创建出这个数组。

0 commit comments

Comments
 (0)