2025春夏季开源操作系统训练营学习总结
2025春夏季我参加了开源操作系统训练营,前三阶段主要是学习了rust语言,并在其两个项目rCore和arceOS中进行实践,下面是我的学习总结。
作为二战选手,上次秋冬训练营止步于第四阶段,之后痛定思痛恶补了一下CSAPP还有RUST圣经,操作系统等这种基础课,还猛猛的参加了Rust训练营,今年磨拳擦掌卷土重来⸜( •ᴗ• )⸝
第一阶段属于是轻车熟路了,通过链表的编写更深刻的理解了Rust的裸指针和智能指针,感慨学无止境,同时也在读张汉东老师的Rust编程之道,后面死灵书等一系列内容都在排队等着学习,对语言的探索多深都不为过。
上一届对于汇编ld文件makefile文件这种东西稀里糊涂,经过过年前后的闭关,把这些知识都补起来了,为了更了解RISCV都汇编指令,通关了傲来训练营的一二三阶段,又自己学习了RISC-V体系结构编程与实践,现在ld文件也看得懂了,makefile也能自己改了,汇编和高级语言之间的调用也知道咋回事了,剩下的就是确定范围和补全逻辑了,有了上一次的经验,这回对从批处理,到进程再到线程的进化有了更深的体会。
第三阶段,上一届前进到写完hashmap因为别的事情就没有继续了,这回有时间慢慢来,一层一层弄清楚调用关系,感受何为模块化操作系统。不过仅是对功能的修改觉得不够尽兴,我也自己拉了一个repo写一个自己的操作系统玩一玩。
这一阶段是rustlings刷题,主要是对rust的学习,我接触Rust有一段时间了,Rustlings之前刷过两遍,对我来说还是比较轻松的。
这一阶段是rcore的练习,涉及到很多计算机底层软硬件的知识,收获很多。
第四章是我花了最多时间的一章,以前对操作系统的内存管理仅仅停留在课本的知识,这一章让我对操作系统的内存管理有了更加深入的了解。
第五章是进程管理的章节,主要是学习了进程管理的相关知识,包括进程的创建,退出,等待,以及进程的调度,对进程的概念比较熟悉。
第六章是文件系统的章节,主要是学习了文件系统的相关知识,包括文件系统的概念,文件系统的实现,以及文件系统的接口。
学习了进程rCore的并发机制,包括信号量,锁,条件变量等概念,以及如何在rCore中实现这些机制。对银行家算法中的资源有了更加深入的了解。
第三阶段是对arceos的学习,对组件化OS的设计有了宏观的认识,从unikernel到宏内核再到Hypervisor。相比于rCore,arceos的项目组织更加清晰,代码更加模块化,也更加易于理解。
让我印象最为深刻的是Hypervisor的实现,我之前对Hypervisor的理解是模拟计算机硬件,然后客户机在这些虚拟硬件中执行,对于硬件虚拟化的认识是比较浅的。
这次操作系统训练营是一次非常有收获的经历。
本人是大三的计科专业学生,上学期学习了操作系统,颇有兴趣,这学期听说了 opencamp os 训练营,就来深入学习一下。本文是我在完成前三阶段任务后的阶段性总结,主要回顾这一个月的学习历程,并对知识进行整理与查漏补缺。
见 2025spring-rust-based-os-comp-stage2-report-loichyan.
在前文中,构思了一种单内核栈的思路.但如果需要实现抢占式内核任务,仅凭单个内核栈是无法做到的——当某个内核任务被打断,需要保存完整的上下文,包括整个执行栈.因此,需要在单内核栈的基础上,增加动态分配的内核栈^1.具体而言,
这样便能按需使用多内核栈,以最大化利用单核栈带来的优势.
在 Rust 的异步模型中,编译器将每个异步函数转换为一个状态机^2,从而避免了任务挂起时对执行栈的保存(虽然加重了编译器的负担).因此,Rust 无栈协程模型天然地适用于单内核栈的系统:
await I/O 操作时,只需将当前任务加入 Executor 的等待队列即可.在多核环境中,为了保证数据一致性,原子数据结构(如 Arc、Atomic* 等)和同步锁(如 Mutex、RwLock 等)是必不可少的.但除了文件系统读写等任务必须加锁以外,大部分任务都是在单核上处理的,此时对原子计数和同步原语的频繁读写就成了额外的负担.并且,主流异步运行时(如 Tokio、async-std 等)默认要求 Future 多线程安全,这使得编写异步函数没那么“愉快”,也是 Rust 异步体验被广为诟病的一点^4.Thread-per-core 模型^5便因此有了不少拥趸,例如 Glommio^6 是一个适用于 Linux 的 Thread-per-core 框架,它是以 io_uring^7 为基础构建的.
之所以 Tokio 等运行时要求 Future 多线程安全,是因为它们使用了工作窃取的调度算法^8,即在线程 A 创建的任务可能被线程 B “偷走”来减少线程空闲.Linux 的任务调度算法也使用了工作窃取^9.Thread-per-core 和工作窃取模型各有优劣^5:
此外,从 Glommio 的介绍^6中不难看出,它很大程度上依赖于各任务之间的相互协作,即理想情况下,任务需要周期地归还执行权,来使得权重更高的任务优先执行.并且,在 Thread-per-core 模型中,为了充分利用各核心的执行资源,需要将 CPU 密集型和 I/O 密集型任务细致地划分给不同的核心,这无疑给开发维护带来了额外的心智负担.从这个角度来看,Thread-per-core 和工作窃取又分别类似于内核的协作式任务调度^10和抢占式任务调度^11.前两者和后两者的不同之处在于:
不过,综合考量各方面因素,还是工作窃取更适用,也更容易实现 :)
以上便是第三阶段的主要收获,接下来需要进一步研究 IRQ 机制与 Rust 异步的集成,以及 io_uring 模型的实现和应用,最终达成对 ArceOS 内核的异步化改造.
第一阶段主要是学习 Rust 语言。Rust 拥有完善的官方文档和丰富的社区资源。
我通过完成 rustlings 练习来熟悉语法和常用特性,遇到不懂的地方就查阅官方手册和社区博客。
这一阶段让我对 Rust 的所有权、借用、生命周期等核心概念有了更深入的理解。
第二阶段聚焦于 rCore 操作系统的学习。rCore 项目内容丰富,涵盖了操作系统的各个核心模块。
我花了大约两周时间,逐章阅读并动手实践,过程中遇到不少挑战,但也极大提升了我的系统编程能力。
通过查阅 RISC-V 参考手册和相关资料,逐步理清了内核启动、进程管理、内存管理等知识点。
第三阶段主要是阅读 ArceOS 的源码并尝试参与部分模块的开发。
与 rCore 相比,ArceOS 的架构更加模块化和易于扩展。
虽然刚开始阅读时有些吃力,但通过不断调试和查阅文档,逐渐理解了其设计思路和实现细节。
这一阶段锻炼了我的代码阅读能力和团队协作能力。
通过本次训练营,我不仅系统学习了 Rust 语言和操作系统原理,还提升了独立解决问题和查阅资料的能力。
同时也暴露了自己在算法和底层实现方面的不足,后续会继续加强相关训练。
感谢 rcore-os 社区和各位导师的指导!
第一阶段是 Rust 编程,让我印象深刻的是 rustling 中链表的习题,那一刻我深深地怀疑为什么要使用 Rust,在之后的阶段中也多次因为对 Rust 语法的不熟悉而头脑混乱,所以在基础阶段确实要好好利用时间认真地学习 Rust 基础,我现在都还在在过 Rust 圣经…
这一阶段就开始对 OS 部分进行学习,二阶段我觉得整个文档都写得非常清晰,整个学习中虽然实验是从第三章开始的,但是或许是因为我之前只是看了操作系统导论,实际上我在第一章节和第二章节的学习上花费了更多的时间,我觉得这个视角就开始切换了,从一开始写应用程序我们进行系统调用和到开发内核的视角,链接脚本,汇编语言,SBI 等等,我觉得理解内核的执行环境也是一个很重要的点
第三章 是对应特权级切换的,学习特权级切换的硬件控制机制,初始化 Trap 处理点 __alltraps() , trap_handler() 实现 Trap 的分发和处理,到 __restroe() 对 Trap 上下文切换的恢复,很有意思的一章
第四章 是对应地址空间,这里我觉得主要讲解了
在分页机制下,为什么要将 Trap 上下文保存在应用地址空间而不是将其直接放在应用的内核栈,对应理解跳板
然后就是对 __alltraps 和 __restore 下是如何保存和恢复 Tarp 上下文时切换地址地址空间的代码部分的修改
然后就是系统调用后,用户传的地址不要直接解用户地址访问,那是用户空间的虚拟地址
第五章 是进程相关的,内核栈,进程控制块,任务管理器,处理器,进程的调度机制
第六章 文件系统
第八章 内核态操作系统方法实现锁
在这里我比较印象深刻是文件系统这一部分的实现,一开始我执行 shell 是觉得这部分测试是可以的,在最后提交的时候才发现原来我竟然是使用的标准库的而没有使用 axstd,然后之后再去实现 armf 中的 rename 方法,在同一个文件夹下 rename 的逻辑,而没有 move 的实现逻辑,但是测试的时候依然报错,而且利用输出给我的感觉是整个代码 都没有运行到我的 axfs_ramfs中,实在想不出原因在角落群中才看见 ”rename实现为了启用本地的 axfs_ramfs要在根目录下的 patch 添加本地的 ramfs“,感谢,,,以及被自己蠢哭。。。不过在这个过程中也是算是对整个文件结构有了一定的了解,是一种组件化的感觉
1 | rceos |
恩,其实诚实地说虽然做了实验,但是现在其实还是有一种脑袋空空的感觉,当然我觉得肯定是对这个有更直观的理解了,然后在知识上我觉得自己没有什么要说的,我觉得整个文档写得很好第三阶段石磊老师的课讲得也非常好,而且因为其实本身可能自己的吸收还是没有很系统,确实能力有限,就给一些我自己学习过程的建议吧
首先实验的完成部分很多都是借鉴相关的部分,我觉得在实验上就是要多看相关的代码,然后不断借鉴,也不要怕错,就只有胆大心细
然后就是在看文档知识的时候我比较推荐就是把它拆出来的感觉,然后放在一个类似 excalidraw 或者 draw.io 的看板上,也可以自己写一些批注,我也尝试就是写博客那种但是一整块流下来的感觉怎么说我自己就是看着很累,但是使用化肥然后拆出来我个人感觉是比较顺畅的,也经常在遇见问题之后没有想法的时候,就到处翻翻,或许就能找到答案,而且画图的这种给的笔记压力也比较小一些,但是不得不说在后面内容多之后确实会有点乱,这种情况下我觉得就是需要再梳理的,可能以另外一个形式或者是什么的,但是我觉得这样拆出来之后就算是复习我个人感觉会比较流畅,不会有太大的压力

这是我尝试的两种方法对比,左边是那种拆出来的,右边就是纯文字的博客,我个人是看左边更觉得看得下去一点…

然后这是我的一个粗略的笔记截图,我就是在这个图上找来找去看一下可能有关联的点…
这种方法是我自己学习下来觉得对我帮助比较大的,然后在之后的复习中没有给我太大压力的感觉,当然我认为每个人适合的方式是不同的,这也只是我自己的感受而已,反正客观地看吧

有了第二阶段的基础,第三阶段相对更好理解了,有些第二阶段有点模糊的在第三阶段也更清晰了,第三阶段作业相比第二阶段更简单。
为什么来这个训练营
官方通过要求:
主要参考资料:
学习过程
感想
官方通过要求
参考资料
学习过程
感想
async/await 异步模型的执行机制和运行时结构lazy_static、OnceCell 等标准库机制,加深了对线程安全延迟初始化(全局单例)设计模式的理解reqwest + tokio 构建异步爬虫,显著感受到异步模型对 I/O 密集型任务的性能提升poll、Future 等底层机制,结合项目实践理解 async 底层原理dev 上尝试更接近 std 的接口模型,目前仍在调试阶段design-patterns-rust: 系统收集和实现 Rust 中常见设计模式learn-rust: 构建学习路径、记录 Rust 编程与系统知识