2024秋冬季开源操作系统训练营第一、二阶段总结-silver
第一阶段
第一个阶段是通过 Rustlings 练习 Rust 语言的基础知识,包括变量、函数、所有权等等。在这一阶段, 我更加深入地了解了 Rust 的一些基础概念,比如所有权、生命周期等等。在这一阶段的学习中, 我发现通过 debug 的方式来学习一门编程语言和熟悉其语法是非常有效的。这能够让我更深入的去思考一些语言设计的原因,而不是简单地记住一些规则。
在学习 Rust 的过程中,我发现 Rust 的所有权机制和生命周期机制是 Rust 的核心特性,也是 Rust 与其他语言最大的不同之处。这也是我认为 Rust 是一门非常有意思的语言的原因之一。所有权机制能够让我将每一个值看作绑定, 而非变量, 这种思维方式让我感觉非常新鲜, 也让我能够更多地将注意力放在程序的逻辑上, 而非内存管理上。生命周期机制则是 Rust 的一种保证, 保证了程序的安全性, 同时也能有效的避免 C/C++ 中的一些内存问题, 比如野指针、内存泄漏等等。
在后续的日常开发过程中,我应该会尝试使用 Rust 做为我的首选语言,因为我觉得 Rust 的所有权机制和生命周期机制能够让我写出更加安全、高效的代码。
第二阶段
第二个阶段是通过为 rcore 添加一些简单的 feature 来熟悉操作系统的基本概念和相关实现。在这一阶段,我更加深入地了解了操作系统的一些基本概念,比如中断、虚拟内存、系统调用、文件系统等等。在这一阶段的学习中,我发现通过实践来学习操作系统是非常有效的。这能够让我更加深入地理解操作系统的一些基本概念。对于模糊的概念,我可以直接看到它们的实现,这让我能够更加直观地理解这些概念,也能更深入的思考这些设计的原因。
在这一阶段,我的感受是操作系统是一个非常庞大的系统,其中涉及到的知识点和细节非常多,但同时操作系统对各组件的抽象也非常清晰。只要理解了这些抽象,将各组件串联起来也并不是一件非常困难的事情。
Zxx开源操作系统第二阶段总结
lab1总结
实验一相对简单。由于尚未实现页表,内核地址空间可以直接访问用户态地址空间,因此系统调用的实现只需直接返回用户态地址即可。此外,为了确保后续实验中的测试通过,建议使用高精度的 get_time_us 获取时间,避免因时间精度不足导致错误。至于统计系统调用次数,可以在 syscall 函数执行时进行更新。若需获取系统第一次调用的时间,则需修改 run_first_task 和 run_next_task。
lab2总结
与实验一不同的是,实验二中需要实现页表。因此,之前的系统调用逻辑需要重构。内核必须找到传递参数的实际物理地址,并在该地址进行读写操作。
此外,实验要求实现两个新的系统调用:mmap 和 munmap。这两个调用涉及一段连续地址,因此需要检查该地址范围是否完全未映射或已映射。mmap 负责插入页面,而 munmap 则用于删除页面。
lab3总结
在实验三中,首先需要将之前实验的代码引入本次实验。如果之前的代码有问题,本次实验的测试通常也无法通过。
本次实验的核心是实现 spawn 和 stride 调度算法。spawn 并非简单的 fork + exec,因此在实现前需充分理解其语义。可以借助 fork + exec 的部分代码来调整 TCB 数据结构至目标状态。
stride 是一种进程调度算法,由于本次实验示例较简单,按照教程步骤实现即可完成。
lab4总结
相比之前的实验,实验四的难度有所增加。首先,需要确保兼容之前的代码。一开始 spawn 的兼容性问题导致多次报错,最终通过重新实现 spawn 才解决。
此外,还需注意可能出现的死锁问题。由于某些函数(如 find 和 create)对文件系统加锁,不能直接调用它们,而是需要将其实现逻辑拷贝并进行调整。
最后是 unlink 的目录项删除操作。在找到目标目录项后,需要更新内容。采用了群里分享的方法:删除原目录项后,将内容重新拷贝过去。
lab5总结
实验五的任务是实现一个死锁检测算法,类似于银行家算法。但教程中的描述较为模糊,许多细节未明确说明。因此,需要仔细分析各个细节。sem 和 mutex 的实现思路基本相同。另外,sys_get_time 的实现必不可少,否则某些测试实例会出现死锁。
总结
总体来说,这些实验内容并不复杂,涉及的概念较为基础。但由于是第一次接触 Rust 并使用它编写操作系统,对我而言是一次新奇的体验。实验的主要难点在于 Rust 的使用上。此外,教程的部分内容并不完善,例如死锁检测算法的部分解释得较为模糊。若不是群里有人提到类似银行家算法,我很可能难以理解。因此,希望教程能进一步完善文档内容,帮助更多初学者。
Zxx开源操作系统第一阶段总结
前言
从零基础开始学习 Rust,通过 Rustlings 逐步入门。Rust 作为一门编程语言,以其优秀的内存安全和高性能设计而闻名,非常值得深入学习。
个人感悟
通过 Rustlings 学习了 Rust 的基础语法、数据结构、所有权和引用等核心概念,初步掌握了编写 Rust 程序的基本能力。在接下来的 rCore 学习中,通过实践进一步深化了对 Rust 编程的理解。这种从基础到实践的学习方式非常高效。未来还需要通过更多项目积累,不断提升 Rust 编程能力以及对操作系统的理解。
Rust 的所有权机制是学习过程中最具挑战的部分。变量所有权的转移、引用的使用,以及 Copy 和 Clone 等特性的分析,都需要反复实践和大量代码积累,才能在实际编写 Rust 代码时得心应手。
2024秋冬季开源操作系统训练营一二阶段总结报告-Nowherechan
第一阶段
是我第四次学习 Rust 编程语言,第一次看 course.rs,第二次用 rust 刷 leetcode,第三次刷 rustlings,第四次再刷了这里的 rustlings。每一次学完后总是不知道学到了什么,脑袋空空,但实际上写的时候,体验在逐渐变好。可能还是留下了些什么东西,只是没有察觉到。
不知道这次留下的东西能持续多久。
Rust 很有特点,枚举变量和模式匹配相得益彰,所有权机制比 std::move 舒服了不少,生命周期让我似懂非懂,trait 很有意思,宏看不明白,并发和异步根本没看。
Rustlings 比官网多了很多东西,例如后面的算法题。数据结构那一块,实在找不到什么优雅的方式来实现移动,应该是学的东西太少了;前几个题目对 copy trait 进行了滥用。后面的倒是简单,不涉及什么 Rust 独有的特性,如果会用其他语言写,那么这里就会写。
相关资料:course.rs,the book,rust by practice
第二阶段
rCore 是一个的小内核,长得像 xv6,基于 riscv ISA 和 RustSBI。
前面几章的内容大同小异,主要是熟悉操作系统的基本概念,例如内存分页管理。文件系统章节需要对 easyfs 有基本了解,这一点通过阅读 guide book 可以达到。
死锁检测算法很新颖,是 xv6 里面没有的内容,一直以来,只学过算法,没考虑过要怎么把这个东西切实地加进内核里面,现在又多知道了一点点,还是有不少收获。
测试用例很弱,可以轻度 hack。
2024秋冬开源操作系统训练营第二阶段总结-reganzm(阿敏)
第一阶段总结
1年前开始学习rust,初衷是了解一门操作系统级别的开发语言(深入了解,作为工作语言那种)。并为此写了系列的微信公众号文章《拥抱未来语言Rust》并在社区取得了不错的反响,感兴趣的可以微信公众号搜索“三角兽”,欢迎关注。
rust作为一门系统级语言,拥有高性能的同时还具有高安全性,基于RAII风格自动资源管理,避免了很多内存安全问题(这也是吸引我学习的主要原因)。本次比赛是我第一次参加的系统级比赛,通过比赛,夯实了对rust语言的理解,包括:所有权,作用域,生命周期,智能指针等。非常有意义,在此感谢主办方!
第二阶段总结
一直以来对OS非常感兴趣,本次通过身临其境的“代码调试”,熟悉了整个项目架构,并对OS有了进一步的深刻认识。在调试过程中不仅熟悉了OS,还对Rust语言有了更深入的认识。第二阶段的操作系统实现基于RISC-V指令集,之前没有了解过RISC-V,因此看汇编语言会有些头痛,但结合RISC-V手册加上AI的辅助,理解这些汇编代码完全没有问题。
通过第二阶段的学习,破除了一直以来对操作系统底层实现机制的迷雾,那层隔阂在应用开发人员心底的对操作系统的朦胧自此打破,世界上没有彩蛋,只有认识盲区,破除这些盲区,就是扩大自己的认知,增加自己的技术自信。后面打算写系列的博客来总结、分享操作系统,影响更多的人来学习操作系统。
下面是第二阶段各个实验的总结,重要的知识点我都画成了流程图,希望帮到需要的人。
lab1
这是第一个实验,整体难度不大,通过print打印信息调试,一天过关。
lab2
地址空间映射这一章知识密度较高,反复看了几遍才基本弄懂,调试代码陆陆续续调试了3天。(还是太菜,菜就多练!)
简单总结下本章:在开启分页SV39分页之前,OS和都是直接访问物理地址,这给系统带来很多潜在的安全隐患,例如地址空间未隔离等。开启分页模式后,OS和用户代码中就都是虚拟地址了,需要通过页表和MMU进行转换,并且页表上的属性区分出了U和S,进行了权限和空间的隔离,分别在特权级和地址空间上保证了OS内核的安全,同时也保证了用户程序之间相互隔离,彼此空间不会重叠。(虚拟空间可以重叠,但通过页表映射后通常是隔离的,有种特殊情况是通过映射到相同的物理也实现内存共享)
另外为了OS在开启分页后能平滑的访问,对于OS采用的是恒等映射(虚拟页号=物理页帧)。而对于用户程序通常采用Framed映射,通过栈式页帧分配器分配页帧并和虚拟页号建立映射关系,动态生成页表及页表项,实现物理页帧的按需分配。
另外一个比较好的抽象是地址空间MemorySet,它作为任务的一部分,管理着页表及和逻辑区。在实现采用了RAIL机制,加上rust的所有权及drop trait自动实现页表项的释放。
lab3
sys_spawn第一版实现测试通过,但是到实验4发现实现有问题,然后修改为exec+fork的方式完成。
lab4
文件系统章节是我花时间最多的一个章节,时间主要花在了对文件系统的理解上,看源码也费了些时间。将细节通过在线文档整理如下图所示:
lab5
死锁检测可以基于银行家算法实现,参考Wiki
2024秋冬开源操作系统训练营第二阶段总结-reganzm(阿敏)
总结
一直以来对OS非常感兴趣,通过本次的“代码调试”,熟悉了整个项目架构,并对OS有了进一步的深刻认识。在调试过程中不仅熟悉了OS,还对Rust语言有了更深入的认识。
本次实现的功能是打印任务信息:系统调用及调用次数,运行时间。
整体思路:在syscall入口处调用set_task_info方法。每调用一次系统调用,更新一次syscall_times和time。
踩的坑:需要注意Rust结构体与C结构体的区别,Rust编译器会对Rust中的字段进行重排序,以达到优化存储的目的。在OS中的结构体和user中的结构体字段要保持一致,否则会蛋疼:(
另外附图一张,表示我曾用心学习:)

第一题
应用分别出现:
- PageFault in application, bad addr = 0x0 bad instruction = 0x804003a4 , kernel killed it.
- IllegalInstruction in application, kernel killed it.
使用的sbi版本是:RustSBI version 0.3.0-alpha.2
第二题
1.刚进入__restore时,a0代表kernel stack pointer , restore的两种使用场景:a.trap 恢复 b.创建新任务
2.处理了sstatus sepc sscratch。sstatus用于指定返回的特权级(SPP字段);sepc用于指定返回后执行哪条指令;sscratch存储着用户栈地址,U态程序要执行必须正确找到U态的栈地址。
3.application不会使用x4;x2已经被交换到了sscratch代表着用户栈指针
4.sp指向user stack , sscratch 指向kernel stack
5.__restore总状态切换在csrw sstatus,t0这行指令,sstatus中的SPP字段记录了陷入前的特权级,csrw sstatus,t0执行后,恢复到用户特权级。最后的指令sret ,指令返回用户程序,原因是该指令会从sepc中读取指令地址,并赋予pc寄存器,而U态的栈等已恢复好,sret临门一脚,步入U世界。
6.指令之前sp -> user stack , sscratch -> kernel stack ;指令后sp -> kernel stack, sscratch -> user stack。指令进入内核运行。并且用sscratch保存着U态的栈地址,从内核态返回即可用sscratch恢复用户态栈指针。
- csrrw sp,sccratch, sp是程序从U态进入S态的关键指令,sp指向内核栈。
荣誉准则
在完成本次实验的过程(含此前学习的过程)中,我曾分别与 以下各位 就(与本次实验相关的)以下方面做过交流,还在代码中对应的位置以注释形式记录了具体的交流对象及内容:
无此外,我也参考了 以下资料 ,还在代码中对应的位置以注释形式记录了具体的参考来源及内容:
我的参考资料:rCore-Tutorial-Book-v3
我独立完成了本次实验除以上方面之外的所有工作,包括代码与文档。 我清楚地知道,从以上方面获得的信息在一定程度上降低了实验难度,可能会影响起评分。
我从未使用过他人的代码,不管是原封不动地复制,还是经过了某些等价转换。 我未曾也不会向他人(含此后各届同学)复制或公开我的实验代码,我有义务妥善保管好它们。 我提交至本实验的评测系统的代码,均无意于破坏或妨碍任何计算机系统的正常运转。 我清楚地知道,以上情况均为本课程纪律所禁止,若违反,对应的实验成绩将按“-100”分计。
2024秋冬开源操作系统训练营第二阶段总结-reganzm(阿敏)
荣誉准则
在完成本次实验的过程(含此前学习的过程)中,我曾分别与 以下各位 就(与本次实验相关的)以下方面做过交流,还在代码中对应的位置以注释形式记录了具体的交流对象及内容:
无此外,我也参考了 以下资料 ,还在代码中对应的位置以注释形式记录了具体的参考来源及内容:
我的参考资料:rCore-Tutorial-Book-v3
我独立完成了本次实验除以上方面之外的所有工作,包括代码与文档。 我清楚地知道,从以上方面获得的信息在一定程度上降低了实验难度,可能会影响起评分。
我从未使用过他人的代码,不管是原封不动地复制,还是经过了某些等价转换。 我未曾也不会向他人(含此后各届同学)复制或公开我的实验代码,我有义务妥善保管好它们。 我提交至本实验的评测系统的代码,均无意于破坏或妨碍任何计算机系统的正常运转。 我清楚地知道,以上情况均为本课程纪律所禁止,若违反,对应的实验成绩将按“-100”分计。
2024秋冬开源操作系统训练营第二阶段总结-reganzm(阿敏)
总结
地址空间映射这一章知识密度较高,反复看了几遍才基本弄懂,调试代码陆陆续续调试了3天。(还是太菜,菜就多练!)
简单总结下本章:在开启分页SV39分页之前,OS和都是直接访问物理地址,这给系统带来很多潜在的安全隐患,例如地址空间未隔离等。开启分页模式后,OS和用户代码中就都是虚拟地址了,需要通过页表和MMU进行转换,并且页表上的属性区分出了U和S,进行了权限和空间的隔离,分别在特权级和地址空间上保证了OS内核的安全,同时也保证了用户程序之间相互隔离,彼此空间不会重叠。(虚拟空间可以重叠,但通过页表映射后通常是隔离的,有种特殊情况是通过映射到相同的物理也实现内存共享)
另外为了OS在开启分页后能平滑的访问,对于OS采用的是恒等映射(虚拟页号=物理页帧)。而对于用户程序通常采用Framed映射,通过栈式页帧分配器分配页帧并和虚拟页号建立映射关系,动态生成页表及页表项,实现物理页帧的按需分配。
另外一个比较好的抽象是地址空间MemorySet,它作为任务的一部分,管理着页表及和逻辑区。在实现采用了RAIL机制,加上rust的所有权及drop trait自动实现页表项的释放。

第一题
最低的位则是标志位,它们的含义如下:
仅当 V(Valid) 位为 1 时,页表项才是合法的;
R/W/X 分别控制索引到这个页表项的对应虚拟页面是否允许读/写/取指;
U 控制索引到这个页表项的对应虚拟页面是否在 CPU 处于 U 特权级的情况下是否被允许访问;
G 全局页表项。这意味着即使是在上下文切换(例如,进程切换)之后,该页表项也不会被冲洗(flushed)或失效。简而言之,G位用于指示页表项在地址空间的多个上下文中保持有效。
A(Accessed) 记录自从页表项上的这一位被清零之后,页表项的对应虚拟页面是否被访问过;
D(Dirty) 则记录自从页表项上的这一位被清零之后,页表项的对应虚拟页表是否被修改过。
第二题
荣誉准则
在完成本次实验的过程(含此前学习的过程)中,我曾分别与 以下各位 就(与本次实验相关的)以下方面做过交流,还在代码中对应的位置以注释形式记录了具体的交流对象及内容:
无此外,我也参考了 以下资料 ,还在代码中对应的位置以注释形式记录了具体的参考来源及内容:
我的参考资料:rCore-Tutorial-Book-v3
我独立完成了本次实验除以上方面之外的所有工作,包括代码与文档。 我清楚地知道,从以上方面获得的信息在一定程度上降低了实验难度,可能会影响起评分。
我从未使用过他人的代码,不管是原封不动地复制,还是经过了某些等价转换。 我未曾也不会向他人(含此后各届同学)复制或公开我的实验代码,我有义务妥善保管好它们。 我提交至本实验的评测系统的代码,均无意于破坏或妨碍任何计算机系统的正常运转。 我清楚地知道,以上情况均为本课程纪律所禁止,若违反,对应的实验成绩将按“-100”分计。
2024秋冬开源操作系统训练营第二阶段总结-reganzm(阿敏)
实验总结
文件系统章节是我花时间最多的一个章节,时间主要花在了对文件系统的理解上,看源码也费了些时间。将细节通过在线文档整理如下图所示:
问答作业
Root Inode 的作用:
文件系统的入口点:在类 Unix 文件系统中,root inode 是文件系统层次结构的根,即 / 目录。它是访问文件系统其余部分的起始点。
存储目录信息:root inode 存储了根目录下的文件和子目录的元数据,例如它们的名称、inode 编号、文件类型(文件或目录)等。
维护文件系统结构:root inode 作为文件系统结构的起点,确保了整个文件系统的组织性和可访问性。
权限控制:root inode 还包含了访问权限信息,用于控制对根目录及其下内容的访问。
如果 Root Inode 损坏:
如果 root inode 中的内容损坏,可能会发生以下情况:
无法访问文件系统:由于 root inode 是访问文件系统的入口,如果它损坏,可能会导致整个文件系统无法挂载,用户无法访问任何文件或目录。
数据丢失:虽然文件数据可能仍然存储在磁盘上,但如果 root inode 损坏,系统可能无法定位这些数据,导致数据看似丢失。
文件系统损坏:文件系统的元数据完整性对于文件系统的健康至关重要。root inode 损坏可能导致文件系统元数据不一致,进而导致整个文件系统损坏。
恢复困难:恢复损坏的 root inode 可能非常困难,可能需要专业的数据恢复工具和专业知识。
荣誉准则
在完成本次实验的过程(含此前学习的过程)中,我曾分别与 以下各位 就(与本次实验相关的)以下方面做过交流,还在代码中对应的位置以注释形式记录了具体的交流对象及内容:
无此外,我也参考了 以下资料 ,还在代码中对应的位置以注释形式记录了具体的参考来源及内容:
我的参考资料:rCore-Tutorial-Book-v3
我独立完成了本次实验除以上方面之外的所有工作,包括代码与文档。 我清楚地知道,从以上方面获得的信息在一定程度上降低了实验难度,可能会影响起评分。
我从未使用过他人的代码,不管是原封不动地复制,还是经过了某些等价转换。 我未曾也不会向他人(含此后各届同学)复制或公开我的实验代码,我有义务妥善保管好它们。 我提交至本实验的评测系统的代码,均无意于破坏或妨碍任何计算机系统的正常运转。 我清楚地知道,以上情况均为本课程纪律所禁止,若违反,对应的实验成绩将按“-100”分计。