正式开始看Linux的代码了,先从汇编开始。简单浏览了一下很头大,进而很高兴。这又不是什么工作,也没啥KPI,更没有工作中大跃进的要求。学习其实是一种享受,不会意味着问题很多,也就意味着我会有更多的收获。

         先看一段汇编代码的开头,具体如下:

494_linux内核学习_0x7C00地址的选择原因_ios

         这一段代码基本上是注释,前面4行,说明了一个参数。感觉上,其实是想说SYSSIZE这个参数,最初设计的时候可能是有名称变化后来跟第7行的信息不一致了。这个参数指定了linux系统的大小,单位是16字节。具体的定义其实是在第6行指明的这个文件里面定义的。

494_linux内核学习_0x7C00地址的选择原因_加载_02

         这里其实又有一个很有意思的问题,0x3000个16字节,其实是192KB而不是196KB。具体的计算参考如下:

494_linux内核学习_0x7C00地址的选择原因_ios_03

         难道是linux的“祖师爷”犯了一个错误?

         接下来,一段描述讲了bios-startup会把这段程序加载到0x7C00这个地址。其实,这个也算是说的明确了,bios-startup应该是一个跟OS不同的一段程序。但是为什么会是这个地址呢?其实这个跟Intel的处理器是没有关系的,我找了一下网络的说明,有一篇文章还是很有参考价值的,链接:​​https://www.glamenv-septzen.net/en/view/6​

         大概是一个什么来源呢?其实,这个地址来自于IBM,确切说是IBM PC 5150 BIOS开发团队。该团队最早开发了DOS 1.0的相关设计。0x7C00其实是31KB,而最初的DOS 1.0最少需要32KB的RAM。设计团队想给OS在这32KB内留下足够的空间用于OS加载,而加载程序需要512个字节。这样,团队选择了32KB中的最后1KB用来加载OS。一旦OS加载之后,这部分RAM其实是可以继续让OS使用的。

         那为什么后续到了其他的应用中依然还用这个地址呢?很简单了,肯定是为了各种兼容而存在的了。

         剩下的几个信息,其实没有这个地址具有这么多的神秘性,简单做一个梳理如下:


  1. Bios-startup把bootsect的信息加载到0x7C00;
  2. Bootsect会把自己移动到0x90000的地址,然后跳转到那里;
  3. 之后,bootsect把setup加载到自己后面,也就是0x90200的地址;
  4. Bootsect将OS加载到0x10000的地址,使用BIOS的中断;

其他的部分说明:


  1. 当前的OS最多支持512KB,linux不像minix带有缓冲buffer;
  2. 加载器简单,出现持续读取错误之后,可能死循环,需要手动重启;
  3. 如有可能,一次读取所有扇区,这样加载过程可以做得快。