Skip to content

Commit aa2a2ad

Browse files
committed
update rtems-source-code
1 parent 03af8b9 commit aa2a2ad

File tree

1 file changed

+71
-38
lines changed

1 file changed

+71
-38
lines changed

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

Lines changed: 71 additions & 38 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-05-26 11:05:00
8+
updated: 2025-06-02 17:15:00
99
---
1010

1111
<meta name="referrer" content="no-referrer"/>
@@ -16,6 +16,8 @@ RTEMS(Real‑Time Executive for Multiprocessor Systems)是一款始于 1988
1616

1717
本文章用于记录阅读 Rtems 内核源码的笔记,尝试理解其中的逻辑。Rtems 内核的版本是 6.1,在线代码网站见 [https://rtems.davidingplus.cn/lxr/source/](https://rtems.davidingplus.cn/lxr/source/)
1818

19+
本文章中涉及到的源码摘抄见项目 [DavidingPlus/rtems-source-code: Rtems 源码阅读。](https://github.com/DavidingPlus/rtems-source-code)
20+
1921
<!-- more -->
2022

2123
# 文件系统
@@ -343,7 +345,10 @@ rtems_libio_iops 是 Rtems 预先分配的 I/O 控制块数组,配置了 CONFI
343345

344346
```c
345347
#if CONFIGURE_MAXIMUM_FILE_DESCRIPTORS > 0
346-
rtems_libio_t rtems_libio_iops[ CONFIGURE_MAXIMUM_FILE_DESCRIPTORS ];
348+
rtems_libio_t rtems_libio_iops[CONFIGURE_MAXIMUM_FILE_DESCRIPTORS];
349+
350+
const uint32_t rtems_libio_number_iops = RTEMS_ARRAY_SIZE(rtems_libio_iops);
351+
#endif
347352
```
348353

349354
#### do_open()
@@ -634,19 +639,25 @@ close() 函数的源码如下。在前面更改完状态标志位后,还是会
634639
```c
635640
int close(int fd)
636641
{
637-
rtems_libio_t *iop; // 指向文件描述符对应的 I/O 对象。
638-
unsigned int flags; // 当前 I/O 对象的状态标志位。
639-
int rc; // 用于保存最终返回值。
642+
// 指向文件描述符对应的 I/O 对象。
643+
rtems_libio_t *iop;
644+
645+
// 当前 I/O 对象的状态标志位。
646+
unsigned int flags;
647+
648+
// 用于保存最终返回值。
649+
int rc;
640650

641651
// 检查文件描述符是否越界。
642652
if ((uint32_t)fd >= rtems_libio_number_iops)
643653
{
644-
rtems_set_errno_and_return_minus_one(EBADF); // 错误:Bad file descriptor。
654+
// 错误:Bad file descriptor。
655+
rtems_set_errno_and_return_minus_one(EBADF);
645656
}
646657

647-
// 根据 fd 获取对应的 I/O 对象。
648-
/**
649-
* 这个实现如我所料。
658+
/*
659+
* 根据 fd 获取对应的 I/O 对象。
660+
* 实现类似于:
650661
* static inline rtems_libio_t *rtems_libio_iop(int fd)
651662
* {
652663
* return &rtems_libio_iops[fd];
@@ -657,11 +668,18 @@ int close(int fd)
657668
// 读取该对象当前的标志。
658669
flags = rtems_libio_iop_flags(iop);
659670

660-
// 这段循环代码的作用是:在线程安全的前提下,把 I/O 对象的 “打开” 标志(LIBIO_FLAGS_OPEN)给清除掉,并且检测有没有正在并发操作导致的冲突。
671+
/*
672+
* 这段循环代码的作用是:在线程安全的前提下,
673+
* 把 I/O 对象的 “打开” 标志(LIBIO_FLAGS_OPEN)清除掉,
674+
* 并且检测有没有正在并发操作导致的冲突。
675+
*/
661676
while (true)
662677
{
663-
unsigned int desired; // 期望写入的新标志。
664-
bool success; // CAS 成功与否。
678+
// 期望写入的新标志。
679+
unsigned int desired;
680+
681+
// CAS 成功与否。
682+
bool success;
665683

666684
// 如果文件未被标记为已打开,返回 EBADF。
667685
if ((flags & LIBIO_FLAGS_OPEN) == 0)
@@ -678,16 +696,16 @@ int close(int fd)
678696

679697
// 使用原子操作尝试替换标志,确保线程安全。
680698
success = _Atomic_Compare_exchange_uint(
681-
&iop->flags, // 要更新的目标变量。
682-
&flags, // 当前预期值,会被更新为实际值(若失败)。
683-
desired, // 想要写入的新值。
684-
ATOMIC_ORDER_ACQ_REL, // 成功时的内存顺序。
685-
ATOMIC_ORDER_RELAXED // 失败时的内存顺序。
699+
&iop->flags, // 要更新的目标变量。
700+
&flags, // 当前预期值,会被更新为实际值(若失败)。
701+
desired, // 想要写入的新值。
702+
ATOMIC_ORDER_ACQ_REL, // 成功时的内存顺序。
703+
ATOMIC_ORDER_RELAXED // 失败时的内存顺序。
686704
);
687705

706+
// 成功清除 OPEN 标志,跳出循环。
688707
if (success)
689708
{
690-
// 成功清除 OPEN 标志,跳出循环。
691709
break;
692710
}
693711

@@ -699,11 +717,14 @@ int close(int fd)
699717
}
700718

701719
// 调用具体文件系统提供的 close 方法。
702-
rc = (*iop->pathinfo.handlers->close_h)(iop); // 关闭文件,通常会执行文件系统特定的清理工作。
720+
// 关闭文件,通常会执行文件系统特定的清理工作。
721+
rc = (*iop->pathinfo.handlers->close_h)(iop);
703722

704-
rtems_libio_free(iop); // 释放 I/O 对象资源,回收到 I/O 对象池中以供复用。
723+
// 释放 I/O 对象资源,回收到 I/O 对象池中以供复用。
724+
rtems_libio_free(iop);
705725

706-
return rc; // 返回关闭操作的结果,通常为 0 表示成功,-1 表示失败(并设置 errno)。
726+
// 返回关闭操作的结果,通常为 0 表示成功,-1 表示失败(并设置 errno)。
727+
return rc;
707728
}
708729
```
709730
@@ -718,17 +739,22 @@ ssize_t read(
718739
size_t count // 期望读取的字节数。
719740
)
720741
{
721-
rtems_libio_t *iop; // 指向文件描述符对应的 I/O 对象结构体。
722-
ssize_t n; // 实际读取的字节数或错误代码。
742+
// 指向文件描述符对应的 I/O 对象结构体。
743+
rtems_libio_t *iop;
744+
745+
// 实际读取的字节数或错误代码。
746+
ssize_t n;
723747
724748
// 检查 buffer 是否为 NULL,防止非法内存访问。
725749
rtems_libio_check_buffer(buffer);
726750
727751
// 检查读取字节数是否为 0 或超出合理范围。
728752
rtems_libio_check_count(count);
729753
730-
// 获取对应的 I/O 对象,并检查是否具有可读权限。
731-
// 若无效或不可读,则自动设置 errno = EBADF 并返回 -1。
754+
/*
755+
* 获取对应的 I/O 对象,并检查是否具有可读权限。
756+
* 若无效或不可读,则自动设置 errno = EBADF 并返回 -1。
757+
*/
732758
LIBIO_GET_IOP_WITH_ACCESS(fd, iop, LIBIO_FLAGS_READ, EBADF);
733759
734760
/*
@@ -741,7 +767,8 @@ ssize_t read(
741767
// 读取完成后释放 I/O 对象(减少引用计数等)。
742768
rtems_libio_iop_drop(iop);
743769
744-
return n; // 返回实际读取的字节数,若出错则为负值并设置 errno。
770+
// 返回实际读取的字节数,若出错则为负值并设置 errno。
771+
return n;
745772
}
746773
```
747774

@@ -756,17 +783,22 @@ ssize_t write(
756783
size_t count // 要写入的字节数。
757784
)
758785
{
759-
rtems_libio_t *iop; // 指向文件描述符关联的 I/O 对象。
760-
ssize_t n; // 实际写入的字节数或错误码。
786+
// 指向文件描述符关联的 I/O 对象。
787+
rtems_libio_t *iop;
788+
789+
// 实际写入的字节数或错误码。
790+
ssize_t n;
761791

762792
// 检查 buffer 是否为 NULL,防止非法内存访问。
763793
rtems_libio_check_buffer(buffer);
764794

765795
// 检查写入的字节数是否合理(非零、未超限)。
766796
rtems_libio_check_count(count);
767797

768-
// 获取 I/O 对象,并检查是否具有写权限。
769-
// 若非法或不可写,则设置 errno = EBADF,并返回 -1。
798+
/*
799+
* 获取 I/O 对象,并检查是否具有写权限。
800+
* 若非法或不可写,则设置 errno = EBADF,并返回 -1。
801+
*/
770802
LIBIO_GET_IOP_WITH_ACCESS(fd, iop, LIBIO_FLAGS_WRITE, EBADF);
771803

772804
/*
@@ -778,7 +810,8 @@ ssize_t write(
778810
// 操作完成后释放 I/O 对象(例如减少引用计数)。
779811
rtems_libio_iop_drop(iop);
780812

781-
return n; // 返回写入的字节数,失败时为负值并设置 errno。
813+
// 返回写入的字节数,失败时为负值并设置 errno。
814+
return n;
782815
}
783816
```
784817

@@ -875,7 +908,7 @@ rtems_filesystem_register() 用于在 Rtems 操作系统中注册一个新的文
875908

876909
```c
877910
int rtems_filesystem_register(
878-
// 文件系统类型字符串,例如 "imfs"、"dosfs" 等。
911+
// 文件系统类型字符串,例如 "imfs"、"dosfs" 等。
879912
const char *type,
880913
// 挂载处理函数指针,用于挂载该类型的文件系统。
881914
rtems_filesystem_fsmount_me_t mount_h)
@@ -886,24 +919,24 @@ int rtems_filesystem_register(
886919
// 计算文件系统类型字符串长度(包含字符串结束符)。
887920
size_t type_size = strlen(type) + 1;
888921

889-
// 计算要分配的内存大小:filesystem_node结构体大小 + 文件系统类型字符串大小。
922+
// 计算要分配的内存大小:filesystem_node 结构体大小 + 文件系统类型字符串大小。
890923
size_t fsn_size = sizeof(filesystem_node) + type_size;
891924

892925
// 动态分配内存用于存储新文件系统节点和类型字符串。
893926
filesystem_node *fsn = malloc(fsn_size);
894927

895-
// 指向分配内存中,存储类型字符串的位置(紧接在filesystem_node结构体之后)。
928+
// 指向分配内存中,存储类型字符串的位置(紧接在 filesystem_node 结构体之后)。
896929
char *type_storage = (char *)fsn + sizeof(*fsn);
897930

898931
// 如果内存分配失败。
899932
if (fsn == NULL)
900-
// 设置错误码为“内存不足”,返回-1。
933+
// 设置错误码为“内存不足”,返回 -1。
901934
rtems_set_errno_and_return_minus_one(ENOMEM);
902935

903936
// 将传入的文件系统类型字符串拷贝到刚分配的内存中。
904937
memcpy(type_storage, type, type_size);
905938

906-
// 设置节点中的type指针指向存储的类型字符串
939+
// 设置节点中的 type 指针指向存储的类型字符串
907940
fsn->entry.type = type_storage;
908941

909942
// 设置节点中的挂载处理函数指针。
@@ -929,14 +962,14 @@ int rtems_filesystem_register(
929962
// 释放刚分配的内存。
930963
free(fsn);
931964

932-
// 设置错误码为“无效参数”(文件系统类型重复),返回-1。
965+
// 设置错误码为“无效参数”(文件系统类型重复),返回 -1。
933966
rtems_set_errno_and_return_minus_one(EINVAL);
934967
}
935968

936969
// 解锁。
937970
rtems_libio_unlock();
938971

939-
// 成功返回0
972+
// 成功返回 0
940973
return 0;
941974
}
942975
```

0 commit comments

Comments
 (0)