第一阶段总结报告
事件0:报名!
因为学长的推荐,正准备自己开始做rcore lab的时候突然在rcore的官方repo里面看到news:
开源操作系统训练营报名!
wow,看到里面的正是自己想要了解学习的内容,一下子打起了12分精神,感觉很切合自己所在的嵌入式方向,并且完美的满足自己想要在更深平台上学习的想法(之前是在stm32的机器上跑过简单的ucOSII 实时操作系统)。
事件1:rust,启动!
感觉自己花在学rust的时间挺长的,主要是想更深入的学习这个语言(正巧大二上学了编译原理),在rustlings上花了不少时间,不想一个个说语法了,只是记得smart_pointers的特性很有意思狠狠的理解了,当然还有所有权(第一次见到在编译阶段去强调这个概念的语言,之前写malloc实验的时候有想过能不能在写语言的时候把内存的管理考虑好),option之类的东西和c++真的很像,前面的智能指针也是c++那一套的东西(有种写cs144的感觉)。范型的使用我就类比之前学java的时候的用法了,让我记忆深刻的还有rust对于错误处理包装成一个enum,居然是个枚举,还有它的宏,也太多了吧(学c的时候确实体会过宏的强大)。
最后10个algorithms花了小半天写完,确实算是对之前的学习合起来应用了一下。
记录的笔记我就留在个人博客上了,因为用的notion写博客,试试推送很方便,所以习惯了:
第二阶段总结报告
做实验
从做实验说起,做rcore实验的周期是起伏的,在5.1假期冲刺完成了4个lab,之前4.28号完成第一个lab。但是当时做的策略从最开始先把全部文档(tutorial3.6的)看完再做实验,变为先扫一遍guide文档,然后做lab,遇到不懂的去翻guide文档,这样才把速度提上来,因为当时也只有5.1假期是完整的时间能做rcore,后面被期末考试割得支离破碎,然后接下来每天有时间细读一下文档,再把前面跳过的问答题补上,就完成了这个整个第二阶段的要求。
对于看的每个chapter以及lab,我做了记录,集中在这里:2024春夏OS训练营
谈感受
第一反应是真的觉得学到很多,学校里面讲的内容只有概念,对于代码,涉及到的也只有linux提供的部分系统调用的使用而不是实现。而从rcore这部分的实验,特别是tutorial里面讲的内容,最开始看链接脚本的配置,bss段的清空,我之前是从来没有在完整的计算机平台写这些的,只有在stm32开发板,移植ucOSII实时操作系统的时候,写过一部分,但是单片机需要考虑的内容和完善的一个计算机应该考虑的内容还是相差较远,而且这次是拿rust进行OS开发,对我之前学的rust基础部分是很大提升。想想makefile也用的更熟练了,以前很是不喜欢命令行gdb调试,总要配配vscode的gdb(launch.json)来用用图形化,现在配合dashboard加上写.gdbinit脚本,流畅的使用gdb能够在调试中得到更多信息(不过当然还是想以后找个方法对于这种情况也能上vscode的gdb插件)。
从批处理操作系统开始,到初步的一个分时操作系统,来到ch3的部分,对系统调用的流程更加清晰,cpu硬件和os的配合(特权级别的切换,内核栈、用户栈的切换,sscratch寄存器的使用),系统调用的认识就变成了一个软中断。
感觉难起来的就是地址空间的出现,而且这个就是我特别特别想自己写代码的部分,因为自己嵌入式这边用的单片机(stm32f401re)是没有mmu的,对于课上提到的地址虚拟化这部分的认识,完全是概念上的,只会做题,算页表占用、分配。但是在rcore的实验里面,尤其是读tutorial,riscv的satp CSR用于管理MMU的配置,设置根页表所在物理号,还有我们这里采取的”双页表”地址空间设计,内核和用户程序都各自拥有地址空间,trap的时候也会伴随地址空间切换到内核的,随之而来的在切换部分实现地址平滑过渡的trampoline(跳板页)以及因为只有一个sscratch所以把内核栈设置到用户空间,这些设计细节,远远超过了平时课上的那点概念认识,也让我对原来很陌生,很迷惑的分页机制有了具体的认识。而且这里面rust的代码的书写风格也给了我很深刻的印象,利用rust的生命周期管理,不用时时刻刻都自己去写drop(因为真的很容易就搞忘或者弄混乱了),而是在设计数据结构的抽象的时候,就反映这些依赖关系,交给编译器去放置drop(大部分)。
后面就是引入了进程的完整概念(体现到数据结构),这里对于僵尸进程有一个初步的认识(不过后面加上线程过后这个僵尸进程的完整效果才展现出来),有了进程,我们顺其自然的再加上文件系统,这样从文件中加载进程执行代码,开始有了一个现代分时操作系统的雏形。文件系统虽然是给的一个easy实现(只有根目录一个目录),但是我觉得扩展出其它目录好像也并不困难(因为两者的核心内容是一样的):超级块、索引节点位图、索引节点区域、数据块位图、数据块区域。不过之前UCOSII实时操作系统里面也接触过位图(它的任务调度很依赖于位图),把自己想成计算机,想想给一个文件名,怎么找到它所在的数据块或者如何为它创建一个数据块保存在文件系统里面,就能理解每个部分的作用。
最后就是到线程的引入(前面还有进程通信,不过那部分没看的很仔细),实验实现了一个进程里面线程的死锁检测,这里让我影响最深的还不是算法实现,实现其实很简单,但是测试用例的设计反而让我记忆很深刻,我在想我有时候就需要设计一个死锁的例子,但是总是有时候马上不能想到一个比较好的例子(想出来的都是很简单的而且不一定能真死锁的(有时候执行不产生死锁)),所以分析测试用例的时候还给了我很多思路。
结语
老实说,参加这次的训练营还算是运气,正好在一阶段报名最后一天看到这个训练营,自己本来是听学长介绍,打算做rcore实验来弥补课内动手的不足,结果正好发现这里有个训练营而且会做rcore,于是在看到的第一时间就报名了,直到现在,我依然觉得这是我幸运的一点,没有这种有些紧张的氛围,以及日程安排的指导,我肯定没有这么强的动力在这么短的时间完成。也很感谢和我一起做题的室友,和他们讨论的时候让我学到了更多内容。