0%

2024春夏季开源操作系统训练营第一、二阶段总结报告-kami

一阶段 小结

这是我第二次参加了,秋冬季的时候二阶段适逢期中考试,完成的不是很好,三阶段也没有参加。这次期中考试和一阶段又撞一起了,挑了时间一口气赶进度是相当的折磨。

通过rustlings可以快速对Rust的特性进行了解,但是感觉学习的效果并不是非常的好,题目做过之后就忘的差不多了,归根到底还是一直用cpp而不习惯使用rust,在学习的时候很容易在想”这个东西就相当于cpp里的…”

最后几个算法题挺有意思的,做起来也很头疼- -

一阶段暂且告一段落,虽然笔记做了一大堆,但是实际上大部分是复制文档内容和代码样例,勉勉强强算给自己制造完成了很多工作量的错觉来给自己一点正反馈吧。

二阶段 小结

写在开头,如果没有rust-analyzer,我可能对着这一大堆东西愣半天也写不了几段正确且符合逻辑的代码。

做PA的时候总是看到强调要多RTFSC,这确实是相当的重要。所以刚开始的时候对着指导书,并结合源码,把每一个模块的实现的源码阅读了一遍,虽然并不是自己敲的,而且有的地方也不是很理解为什么要这么写,但是总体上有了大概的了解,不至于那么的无从下手。

这个学期学校课程安排开设了操作系统课程,相比于秋冬季时没有系统的学习操作系统而直接开始阅读Tutorial来说,这一次重新阅读,结合课本的相关知识,这些概念和代码实现亲切了许多。

简单说说在各个章节中的收获:

多道程序

本章学习了任务相关的知识,包括任务切换,任务调度,任务控制块TCB数据结构的设计等,相比于课本上生硬地写出TCB需要保存的内容来说,使用代码实现TCB的设计可以有了更加深刻的理解。

实践作业实现了一个新的系统调用 sys_task_info 用以获取当前正在运行的任务的信息。

地址空间

印象最深的是SV39多级页表。类似于字典树(Trie),大大节省了占用的内存空间。
还有虚拟内存的相关概念,虚拟内存和物理内存的转换。

实践作业实现了 mmap 和 munmap 匿名映射,简化了实现,仅用于申请内存。
主要是要RTFSC,在其他的系统调用中查看如何转换地址,如何查页表。

进程

进程和线程在学校课程学习中是很重要的一部分,本章介绍了进程的概念和相关系统调用,并进行进程管理和进程调度。

实践作业包括两个:

  • 实现spawn
    虽然好像 fork+execve!=spawn,但是我的实现就是把fork的代码复制下来,然后和execve的代码进行了一个缝合…
  • 实现stride调度
    发现了ci的一个bug,即实际上如果只实现了set_priority这个用于设置优先级的系统调用,并没有去实现调度的话也可以通过ci测试…

文件系统

印象非常的深刻的是Unix哲学的一切皆文件

本章的内容相当的多,因为文件系统比较复杂,读起来非常的费劲而且读完就容易忘…

只记得bitmap,inode啥的了2333,在PA中实现过read,open,seek等操作,印象也不是很深刻了,当时好像是可以将不同类型的文件用统一的接口来进行读写操作。

实践作业实现了linkat和unlinkat,关于fstat,在计算inode时遇到了一些困难…

并发

首先介绍了用户态和内核态的线程管理。
线程的并发问题是老生常谈了,用了锁,信号量,条件变量等进行线程同步互斥管理。

实践作业实现死锁检测,一开始就把这个认为是银行家算法,但是潜水看群里大佬们聊天说并不是,只是用了银行家算法的思想,再想了想课本上学习的,好像确实…

比较麻烦,一开始无从下手,因为不知道资源数量,需求资源啥的需要在哪里定义。

小结的小结

二阶段的编程小练习涵盖了操作系统设计的几个重要方面,我认为二刷甚至多刷也是有价值的-。-

三阶段 小结

项目3 Rust for Linux & 跨内核驱动框架

练习一 配环境

工欲善其事,必先利其器。

万事开头难,确实如此。在配环境上折腾了好久,一开始用WSL,但是对于图形界面的支持不够以致QEMU界面始终是黑屏- -…又改用虚拟机,但是性能很差,编译一次要花费好长时间,虽然可以显示画面了,但是到练习二的时候又出现了画面卡死动不了的问题- - …

有群友使用docker整了一个环境,也整下来试了一下,但是被mac的大小写问题给坑了一下,到最后也没配好

最后得到的最优解是在WSL启动QEMU时使用 vnc 进行连接。

算一下为了配好环境前前后后折腾了好几天,编译了不下十几次- -

练习二 实现Miscdev驱动基本读写

本学期学校开设的操作系统课程实验也使用了树莓派进行内核编程,其上烧写的是OpenEuler。于是对于内核模块的编写多少有一点亲切感。

完善了open/read/write的内容,使得杂项字符设备可以实现基本读写操作。

练习三 跨内核驱动框架下的树莓派4B GPIO点灯实现

一开始一头雾水,不知道要怎么下手,又遇上期末考试,于是就暂时搁置了。

考试周结束后又重新捡了起来,去课堂看了之前的回放才知道了如何把写的pure driver编译进内核。

在pure driver中要做的事情主要是完成树莓派的所有寄存器的抽象。(阅读树莓派的手册很重要)

然后在Adapter driver中把寄存器映射到内存地址,通过对于地址的操作,进而控制寄存器,达到GPIO口的电平和输出模式等等的目的。

1
let mapped_base = unsafe { bindings::ioremap(BCM2837_GPIO_BASE, GPIO_SIZE) };

在Arceos上的操作也类似,pure driver可以直接复用,但是要把osl相关的东西给换掉。在映射地址时多了个物理地址转为虚拟地址的操作。

1
let mut gpio_map=RpiGpioPort::new(phys_to_virt((gpio_base as usize).into()).as_mut_ptr());

文档给的点灯驱动参考非常的详细,照着做基本上就能够正常运行起来。(但是有的地方还是不理解为什么要这么操作)

总结

本次训练营的学习内容相当丰富,学到了很多新知识,以及探索了之前没有涉足过的领域。
但是由于课业等等压力,一直都算是在闲时才来跟一下训练营的进度,因此各方面感觉自己学的不够扎实,学习深度也有限,仍需要继续沉淀…
总结就是要多读源码,多看手册,不要因为嫌麻烦偷懒不看- - 问就是在这方面吃了很多的教训,有的问题想好久想不明白,这里为啥这么写?这个寄存器为啥这么操作? 最后一看手册里写的清清楚楚的…

我们旅行时不要像个信使一样,而应当像个探险家一样。我们不仅要考虑起点和终点,还得考虑起点和终点之间的距离

~

繋がる空の下
さあ自分らしく進もう
始まりの歌贈るよ
歩き出す君へ

–献给此刻迈步前行的你

Author:
kami
Xiamen University