1.2.3 加载第三部分代码—system模块(2)

来源:互联网 发布:和合期货软件下载 编辑:程序博客网 时间:2024/05/17 15:20

1.2.3 加载第三部分代码—system模块(2)

现在,bootsect程序的任务都已经完成!

下面要通过执行“jmpi 0, SETUPSEG”这行语句跳转至0x90200处,就是前面讲过的第二批程序—setup程序加载的位置。CS:IP指向setup程序的第一条指令,意味着由setup程序接着bootsect程序继续执行。图1-14形象地描述了跳转到setup程序后的起始状态,对应的代码如下:

  1. //代码路径:boot/bootsect.s  
  2. jmpi 0, SETUPSEG 
 图1-14 setup开始执行

setup程序现在开始执行。它做的第一件事请就是利用BIOS提供的中断服务程序从设备上提取内核运行所需的机器系统数据,其中包括光标位置和显示页面等数据,并分别从中断向量0x41和0x46向量值所指的内存地址处获取硬盘参数表1和硬盘参数表2,把它们存放在0x9000:0x0080和0x9000:0x0090处。

这些机器系统数据被加载到内存的0x90000~0x901FC位置,图1-15标出了其内容及准确的位置。这些数据将在以后main函数执行时发挥重要作用。

提取机器系统数据的具体代码如下:

  1. //代码路径:boot/setup.s  
  2.  
  3.     mov ax, #INITSEG        ! this is done
    in bootsect already, but...  
  4.     mov ds, ax  
  5.     mov ah, #0x03           ! read cursor pos  
  6.     xor bh, bh  
  7.     int 0x10            ! save it in known 
    place, con_init fetches  
  8.     mov [0],dx          ! it from 0x90000.  
  9.  
  10. ! Get memory size (extended mem, kB)  
  11.     mov ah, #0x88  
  12.     int 0x15  
  13.     mov [2], ax  
  14. …  
  15. …  
  16. mov cx, #0x10  
  17. mov ax, #0x00  
  18. rep  
  19. stosb 

这段代码大约70行,由于篇幅限制,我们省略了大部分代码。

 图1-15 加载机器系统数据

注意,BIOS提取的机器系统数据将覆盖bootsect程序所在的部分区域。由于这些数据是要留用的,因此在它们失去使用价值之前,一定不能被覆盖掉。

点评

机器系统数据所占的内存空间为0x90000~0x901FD,共510个字节,即原来的bootsect只有2字节未被覆盖。可见,操作系统对内存的使用是非常严谨的。在空间上,操作系统对内存严格按需使用,要加载的数据刚好占用一个扇区的位置(只差2字节),而启动扇区bootsect又恰好是一个扇区,内存的使用规划像一个账本,前后对应;在时间上,使用完毕的空间立即挪作他用,启动扇区bootsect程序刚结束其使命,执行setup时立刻就将其用数据覆盖,内存的使用率极高。虽然这与当时的硬件条件有限不无关系,但这种严谨的内存规划风格是很值得学习的。

到此为止,操作系统内核程序的加载工作已经完成。接下来的操作对Linux 0.11而言具有战略意义,系统通过已经加载到内存中的代码,将实现从实模式到保护模式的转变,使Linux 0.11真正成为“现代”操作系统。

0 0