一、二义性和无义性
我们都知道程序是接受不了二义性的,当一条语句可以有两个执行结果的时候,那么程序就会接受不了。但是我们常常忽略“无义性”,这是我取得概念,意思是这条语句的执行结果是不确定的,这种不确定不是说结果不确定,比如 C 里面局部变量刚声明的时候值也是不确定的,但是没关系,而是说执行的规则是不确定的,那么就是不可以的。
但是由于 CPP 高度的自由性,所以他希望所有的规则都是使用者来制定,但是这种自定义规则制定前,也必然是存在一定的规则的,但是这个规则需要我们自己去了解。
我认为 shell 其实可以看作由一个字符串处理的前端加一个调用其他文件的后端组成。前端将用户输入的字符串进行解析,然后将解析的结果传给后端,让后端去调用其他文件。这里的文件指的是“外部命令”。之所以叫这个名字,正是因为外部命令的功能实现并不在 shell 之内。正是因为 shell 不需要实现外部命令,所以这次大作业的难度并不高。相对应的内部命令,其功能的实现是在 shell 之内的(也就是需要在 shell 的代码中实现),幸好大作业并不要求实现内部命令。
关于一个命令是内部命令还是外部命令,可以用 type
命令查看,比如输入
type cd
Unit2 的问题以电梯作为题目背景出题,刚做题的时候很容易就把这个单元的任务当成了处理多线程,当我全部完成这些作业以后,发现仅仅将 U2 概括为多线程,是一个十分片面的直观理解。
我觉得应该这么理解,U2 要完成的东西有(当然可以不完成):
这是一次对于 MOS 内存管理的钻牛角尖梳理,在梳理过程中诞生了一些奇怪的东西。
操作系统的代码不是 C 就是汇编。所以我们从一开始就在使用虚拟空间了。但是很有意思的是,我们为什么可以?我们在一开始的时候没有内存控制块,也没有页表结构。所以我们到底是怎么完成映射的?
其实就是对于 kseg0,只要我们往里面写东西,那么内容就会直接写到高位抹零后对应的物理地址上。这种映射是第一性的,也就是说,即使我一直不建立内存控制块,一直不建立页表结构,只要我用链接器把代码放到了 kseg0,那么这种关系依然是成立的。我写的每一段代码,操作的每一个数据,都是直接写到物理内存中的,不走 MMU,不查页表。这是一切的本源。
关于 kseg1 的情况,其实应该是书里写错了,采用的映射关系其实不是抹掉高 3 位以后映射到物理地址,而是映射到了设备总线。只有这样,才可以避免 kseg0 和 kseg1 的不同的虚拟页面映射到同一个物理页框。不同的虚拟页面确实可以映射到同一个物理页框,但是这意味着这两个虚拟页面的内容应该是相同的,但是显然这两个段内容显然不是相同的,所以两个段必然不能遵守书中的规则。