0%

2024秋冬季开源操作系统训练营第一、二阶段总结-catme0w

来跟大伙唠会

你们好,我是清朝老兵。

我是catme0w,你可能已经在排行榜见过我的名字了。

去年这个时候,我已经来过一次了。为什么我会再来一次?马上揭晓答案。

在继续之前,你可以先看看我上一次留下的记录:https://rcore-os.cn/blog/2023/11/14/2023开源操作系统训练营第二阶段总结报告-CatMe0w/

和上次一样,我的日志里不会有太多关于技术的流水账。如果你想看一个不错的故事,那你来对地方了;如果你还在rCore中挣扎,正在寻找一些攻略,那么我也不会让你白跑一趟,接好了:

写在最前,太长不看攻略:你可能需要的建议

  1. 强烈建议关闭Copilot或Codeium等代码补全器,它们完全无法理解内核,对于系统编程几乎一无是处;它们产生出的代码会浪费你非常多的时间。
  2. 小黄鸭调试法或许会有帮助。
  3. 在你100%理解代码库之前,你是做不出题目的。相信我。
  4. 完全理解代码库之后,先构思好你准备要做的东西,否则出场即大改。
  5. 做好因方向错误而大改的准备。
  6. 小心#[repr(C)]。
  7. rustsbi-qemu可能非常不稳定,遇到灵异现象?换个QEMU版本试试;如果你在用Apple Silicon,也换台机器试试。
  8. gdb或许很低效,多插trace!()。

未讲述的往事

如果你看了上边我参加去年训练营时的记录,你应该已经了解到,当时,我在ch5就停滞下来然后退出了。我其实内心是有些后悔的,觉得自己当时并没有看起来的那么忙,是自己的懒惰造成不得不退出的结局。

纵使rCore从不是什么大事,我还是觉得“抬不起头”,之后也从未和别人再提起这个精致的小操作系统,就好像未曾发生过。

我会自己写一个操作系统吗?也许永远不会吧。就当是一场梦。我这么想。

次年夏天。

在一个非常非常偶然的机会,我了解到我的一位朋友参加了今年春季的训练营。而我们之间最大的不同,便是我自始至终都只抱着“60分万岁”一般的态度,指望着能混到晋级就是胜利,而他从一开始的目标就是榜一。

我仿佛挨了一记响亮的耳光:做不到,只是因为不想。

所幸,训练营从不禁止清朝老兵(而且现在还越来越多了!),我有机会为rCore重新补上一个完美结局。

rustlings II

我也是Rust老兵了,这100题,不是把我去年的补丁直接合过来便是?

然而从今年开始,rustlings多加了十道算法题,成了110题。清朝老兵遇到了它的第一个障碍!

我了解Rust的脾气,知道什么数据结构得开unsafe,只是我已经很长时间没有摸过算法题了,更没有用过Rust写算法题,一打开,满屏的泛型让我虎躯一震。

这需要一点时间……不过,仍然只是小插曲。让我们直面恐惧,走向rCore吧。

rCore II

实不相瞒,我去年压根没看懂rCore的教程,我的确是一路完成到了ch5,可除了ch3以外,我自己都不知道我写了什么东西,我的代码以一种连我自己都无法理解的方式运行起来,大概纯粹是碰对了测例而已。

往好处想,将功补过的机会来了;往坏处想,这相当于一点经验都没有了!

ch3

没有什么困难,凭借着清朝时期的记忆,我还记得ch3要在哪里加上什么。迅速结束战斗。

ch4

我至今都认为,ch4内存管理这一章是整个rCore难度最大的部分,至少在知识上是如此!题目本身反而是不那么难的,代码量不大,理解内存管理的情况下应该很快能找到正确的路;可如果对内存模型有哪怕一丢丢一知半解,你都会在ch4的题目上拥有一段不愉快的时光。

嗯,我承认我是后者……

ch5

ch5做的是什么来着?我又给忘了。它就是如此没有存在感,前后的ch4和ch6都是令人大叫的程度,相比之下,ch5就有些难以给人留下深刻印象了。

哦想起来了是spawn。好像还真没有太多可以说的,在经历过前两章的毒打之后,你应该能很快处理完这一章。

ch6

我抵达了我之前没能征服的地方,硬骨头来了。至此,rCore才真正展现出它的威力,BOSS进入二阶段了!

ch6在知识上稍轻松些,但题目的难度却和教材文本完全不成比例。题目的难点在于非常的绕,为了改动某个功能,你可能需要前后在许多不同的地方修改一连串代码,更不必提这个在内核之外的模块很难调试。

到这里,有件事我一定要骂:用Rust编程,有时真的很让人沮丧。

人们总是说“编译期拦住错误比事后debug更好”,可是只有自己才知道,用Arc啊,Mutex啊那些东西的时候有多令人不快:它明明就在这里,就是这么直观,但就是不让你用。

当天中午11点,我已经几乎完成了ch6的功能实现,我想着,ch6通过就去吃午饭。

你能猜到这样立flag将会如何发展。

晚上11点的我:😅

ch8

就快结束了!最开始看到ch8教程的时候,我心中窃喜:这么简单啊!就好像回到了ch3一样!

题目要求也很简单,甚至详尽地描述了要实现的每个细节。

上机开写,很快就通过了互斥锁的测例,信号量的第一个测例也很快通过了。只剩最后一个测例了,马上就可以结局了!

然后我就在这“最后一个测例上”卡了十多个小时。🌚

要么是第一个测试不过,要么是第二个,两个测例呈现出完全不可理解的结果。可是无论我怎么检查自己的代码,在能插的地方都插满了log,发现每个步骤确实都与预期中的相符,可为什么结果就是不对呢?我也没有理解错题意啊?

“我也没有理解错题意”……等等。

会不会真是我把题目弄错了?我会不会实现了一个错误的算法?

走投无路之下,我开始直接写这个算法的证明,很快发现,(按我理解的)这个算法根本无法检测任何死锁!

题目在算法的描述上,确实有些混乱和容易误导人。我意识到我该寻求外部资料了,到此时,我才终于知道这就是Dijkstra的银行家算法。

在查看了这个算法的精确描述后,我才终于弄明白我出问题的地方:need矩阵,只减不增,更绝非我最初理解的从0开始增长。

终于,所有测例都能通过了,ch8结束了,可是我却有些哭笑不得,因为这么愚蠢和缺乏技术含量的原因卡住,感觉自己有些像是被戏弄了。

rCore EnCore

感谢你还有耐心看到这里。也许你已经留意到,我在今年的排行榜上是榜一。

二阶段classroom放出之后,我使用的是补丁方式提交,因而在补丁里还留有当时的实际完成时间:9月21日。

在我完成rustlings之后,也就是今年报名刚开的那个周末,我把整个周末的全部时间都投入到速通rCore上了。

不为别的,我就想给去年的自己一个耳光。

尾声

做rCore实验的过程,前半程就是一筹莫展:你看了半天文档,感觉自己好像会了,一打开代码却发现两眼一抹黑,根本不知道在干什么。

然后你花了很长时间终于大致摸清楚代码结构了,一准备开始写,发现还是一筹莫展,都不知道要写什么东西。

过了不知道多久,终于你有了一个差不多的思路,可以开始写了,此时,你来到了后半程。

你可能用了不太长的时间就写出来,也可能很久,但一定是跑不起来的。

接下来你会用几十个小时的时间去调试,gdb或者插满trace!()。

然而即使用了gdb也没有太大帮助,因为错误往往出现在你想象不到的地方。

有的时候你会发现测试用例能过,甚至是随机性可以过,有的时候会发现QEMU直接一动不动——rustsbi-qemu并不稳定。

当你第一次发现测试能过的时候,哪怕只是概率性成功,你以为自己离胜利近了,但你很快,或者很久以后才发现,方向完全错了,你必须全部推倒重来。

这种事将会反复发生。

最后,你离最终的目标越来越近,但每次都总差那么一点,你不禁怀疑自己是否真的在接近终点,还是又一次搞错了方向。

到了最后,你可能都记不清这中间到底推翻了多少次,改了多少个细节。你不再期待一蹴而就,而是学会了享受每次解决一个小问题的成就感。

不管失败多少次,推倒多少次,你已经比一开始那个两眼一抹黑的自己强太多了。也许方向错了,代码推倒重来,但至少,你知道自己在进步,哪怕每一步都很艰难。最终你会发现,这些反复挣扎的瞬间,才是整个过程里最有价值的部分。

尾声之后

“我会自己写一个操作系统吗?”

会的。

我回想起一件事,是在我很小的时候发生过的,我已经很难分辨究竟是什么时候了。

人们在讨论《30天自制操作系统》这本书。

当时的我想,啊,这竟然是可能的吗?这本书一定很厚,很难懂……

在那时的我眼里,除开最终呈现给用户的应用程序,其余关于计算机的一切都是魔法烟雾构成的黑盒——麻瓜弄不明白。

但在这么多年之后,我终于明白,做不到,只是因为不想。

我们都可以。

训练营只是一个开始,在这之后,还有更广袤的世界等待着探索。

https://github.com/CatMe0w/attune