0%

二阶段总结报告--c2h4moe

狂赶一周,二阶段也算是终于做完了,这里就说说实验中令我印象比较深的部分吧。

地址空间

操作系统为每个应用程序制造了一种假象,仿佛它们能够独占并随意的使用巨大的内存空间,但实际上,这是硬件分页机制和操作系统维护页表共同营造的幻觉,在加载ELF文件时,操作系统会把程序加载到物理地址中一段空闲的区间,但会让ELF文件中指定的加载地址对应的页表指向真正的物理地址。

我觉得这个实验需要注意很多细节,比如,页表切换是一条指令完成的,如何保证切换完之后依然能够按照我们所期望的执行流继续执行呢?我们开辟了一个“跳板页”,让所有地址空间的最高一页都指向一段相同的物理地址,这样就可以保证页表切换是“平滑的”。

还有,之前想了很久为什么用户态的上下文是存在用户的地址空间而非内核的,后来看实验指导书才明白页表切换和内核栈切换是两步操作,但只有一个sscratch寄存器,无法在不破坏通用寄存器的条件下切换到内核空间并在内核栈保存上下文。

这章还有很多技术上的优化技巧,比如,如果为每个应用都建立一个能够映射全部空间的页表,会占有过大的物理空间,所以,我们不再对每一个地址都映射,而是根据ELF文件的程序头一段段来映射,并且引入类似“字典树”的数据结构来建立多级页表,有效的节省了空间。

并发

实现互斥锁可以有三种方式,一种是在纯软件形式在用户态通过类Peterson算法

实现锁,还有是在硬件的支持下通过原子指令来实现,还可以通过操作系统支持(假设内核进程不被打断)。

这章给我印象比较深的部分是引入互斥锁时举了一个计数器的例子,根据例子运行的异常提供了3个分析思路:是不是编译优化造成的?是不是OS调度造成的?是不是CPU造成的?并且逐一分析,最终找到根本原因,我认为这给我了一个关于系统编程方法论的启发。并且在分析错误原因时通过状态机和合法状态来分析,也是一个很深刻的想法。

总结

除了上面说的一些底层的特性(页表,地址空间切换等等),操作系统大部分也只不过是个普通的应用程序。在看框架代码时,我也学习到了一些编程的技巧和方法,比如,通过drop trait来实现RAII,通过这个rust机制有效的减少了内存分配相关的错误。

总体来说,不管是对OS的理解,还是对rust的掌握,我都进步了很多。