mit-6.828 boot/boot.S 源码阅读

- boot/boot.S

  • 该文件的目的:

    1. start CPU, switch to 32-bit protected mode(启动CPU 并且最终转到32-bit 保护模式)
    2. BIOS loads code from first sector of the hard disk into memory at physical addr 07xc00
    3. executing in real mode (%cs=0, %ip=7c00)
  • 步骤:

    1. 初始化重要的segment registers,全部初始化为0
    2. 16位指令下,屏蔽中断,初始化段寄存器
    3. 开启A20 gate,停止取模运算,将高位的空间也可访问
    4. 利用bootstrap GDT转换到protected mode
    5. 跳转到32-bit模式下的下一个指令
    6. 然后在32-bit 保护模式下,设置保护模式的寄存器
    7. 设置stack pointer 然后调用main.c执行main.c里面的bootmain函数
  • 关于开启A20 gate的代码部分解析:

11  # Enable A20:
12  #   For backwards compatibility with the earliest PCs, physical
13  #   address line 20 is tied low, so that addresses higher than
14  #   1MB wrap around to zero by default.  This code undoes this.
15 seta20.1:
16  inb     $0x64,%al               # Wait for not busy
17  testb   $0x2,%al
18  jnz     seta20.1

19  movb    $0xd1,%al               # 0xd1 -> port 0x64
20  outb    %al,$0x64

21 seta20.2:
22  inb     $0x64,%al               # Wait for not busy
23  testb   $0x2,%al
24  jnz     seta20.2

25  movb    $0xdf,%al               # 0xdf -> port 0x60
26  outb    %al,$0x60

​ 这部分指令就是在准备把CPU的工作模式从实模式转换为保护模式。我们可以看到其中的指令包括inb,outb这样的IO端口命令。所以这些指令都是在对外部设备进行操作。根据下面的链接:

   http://bochs.sourceforge.net/techspec/PORTS.LST

  我们可以查看到,0x64端口属于键盘控制器804x,名称是控制器读取状态寄存器。下面是它各个位的含义。

  img

  所以16~18号指令是在不断的检测bit1。bit1的值代表输入缓冲区是否满了,也就是说CPU传送给控制器的数据,控制器是否已经取走了,如果CPU想向控制器传送新的数据的话,必须先保证这一位为0。所以这三条指令会一直等待这一位变为0,才能继续向后运行。

  当0x64端口准备好读入数据后,现在就可以写入数据了,所以19~20这两条指令是把0xd1这条数据写入到0x64端口中。当向0x64端口写入数据时,则代表向键盘控制器804x发送指令。这个指令将会被送给0x60端口。

  img

  通过图中可见,D1指令代表下一次写入0x60端口的数据将被写入给804x控制器的输出端口。可以理解为下一个写入0x60端口的数据是一个控制指令。

  然后21~24号指令又开始再次等待,等待刚刚写入的指令D1,是否已经被读取了。

  如果指令被读取了,25~26号指令会向控制器输入新的指令,0xdf。通过查询我们看到0xDF指令的含义如下

  img

  这个指令的含义可以从图中看到,使能A20线,代表可以进入保护模式了。

注:部分资料来自网络

posted @ 2020-07-31 13:28  Cindy's  阅读(321)  评论(0编辑  收藏  举报