0%

2023开源操作系统训练营第二阶段总结报告-CatMe0w

大概前阵子是和朋友聊天时,有人提到这么一个用Rust写的教学内核,产生兴趣后找来看了才发现训练营的存在。

我用Rust已经有一段时间了,但多数时候是用来写应用层面的程序,比如web服务。我对操作系统的理解几乎停留在理论,也没有做过系统开发。得知有这么一个难得的机会,那自然不可错过了。

我的文章中不会着重讲述开发的流程,但会更多地记录一些我自己遇到的比较独特的问题和经历,以及我个人的感想——我自认为我的技术实力是不如许多人的,如果你想找技术上的攻略心得,去看看别人吧。 😋

在二阶段前

不巧的是,在一阶段开始之后不久,我就遇到了一些生活上的琐事。我很快发现自己没有多少时间可以投入到rCore中了。所幸,因为已经有Rust的经验,速通rustlings也只是一晚上的功夫。

只是,可想而知之后的二阶段恐怕没这么容易了。

ch3:来自Apple的诅咒

训练营的rCore(Guide)其实已经是rCore Tutorial的再度简化版,但即便如此,第一个任务ch3还是打得我措手不及。

此前我对操作系统的理解是泛泛的,大致知道操作系统具备哪些东西,最深入的理解也只是本科课程作业中用C编写的调度算法模拟演示。对于一个真正的操作系统,该从哪里开始都不知道,比如说,在no_std的世界中,stdout从哪里来?怎么在屏幕上渲染出日志?(遗憾的是rCore并没有回答这个问题,SBI完成了这部分)

要一次性消化这么多新东西并不容易,特别是当自己以为已经把Tutorial读得足够清楚了,一打开代码库时依旧觉得无从下手,不得不再次回到Tutorial啃。在这种状况下,我僵持了差不多一个星期才弄清楚ch3究竟应该怎样完成,或者说,代码究竟该写在哪。

然而,在功能完成后,我的代码出现了一个难以理解的错误:

1
Panicked at src/bin/ch3_sleep.rs:16, assertion failed: current_time > 0

有很多人遇到了get_time_ms和get_time_us的精度问题,但我很确定我的问题不属于此类——就算我的电脑再怎么快,get_time也绝对不可能是0。

在反复重写了几个不同的实现方式之后,我开始留意到一个惊愕的事实:“get_time为0”这个错误是否发生,在时间上不均匀。

有的时候随便改动一两行代码,第一次编译可以通过测试,但第二次之后就会遇上这个错误。

在探索到深夜时,我发现在get_time加上一个println,就能把这个错误的发生概率降到零。

Commit, push, CI… Run failed.

那,把这个println删了试试吧。删除之后,在我的机器上又不能通过测试了,但出于好奇,我还是把这个commit推到了远程。

这一次,测试通过了。

这是一个只会在我的机器上出现的错误。

我使用的是QEMU 8,当然也更换了最新的pre-release RustSBI,但这……我确实没看到有其他人遇到这种问题,也无法理解。

那么只剩下一种可能了……Apple Silicon。

ch4:困难模式

虽然已经在ch3得到了教训,我还是没有在第一时间更换Linux虚拟机。我想着,时间已经不多了,同样的问题,或者更诡异的问题出现之后再换虚拟机吧,还是想贪那两秒钟的编译时间。

幸好,那来自Apple的诅咒之后再没发生过。

然而ch4的难度直线上升,尤其是对我而言——我对页表一无所知。在ch4感觉到的压力,还有那种面对代码库不知所措的感觉,比ch3还要强烈得多。

这时我已经萌生了打退堂鼓的想法,ch4无论是知识本身的难度还是任务难度都让我有点招架不住。

不过,最终还是研究明白了ch4两个函数的实现方式,以及需要为它们补上的其他函数,虽然花的时间远比预期中长。

ch5:迟来的句号

ch4完成后,二阶段原定的期限只剩下两天了,我那时还不知道通过的要求已经放宽到了ch5,在周末啃了ch5文档一天之后,我还是决定离开了。

很遗憾,没能和你们一起走下去。

……吗?

在原定的期限一周之后,我发现还有人在冲击着二阶段。

那么,来画上一个真正的句号吧。

ch5的难度倒是下降了不少,大概也是因为已经对代码库更加熟悉了。在ch5上花的时间最多的地方竟然是在cherry-pick以前的代码上,花了不少时间手动处理合并冲突,直到能通过编译和通过BASE=1。至于实现两个功能倒是比较轻松愉快,毕竟,现在已经知道代码要加在哪了。

阶梯

回过头看,在这个仓库上写的代码,好像真的不多。但是,对于一个未曾了解过操作系统本质的人,可以说是打开了新世界的大门。此刻,操作系统已经变得不再神秘,而rCore Tutorial同样也是值得反复精读的教材。

最后,也感谢老师们提供的资源以及帮助。