MIT6.828 Lab1 PC Bootstrap

环境

ubuntu 20.04 64位

正文

这部分的目的是为了让我们了解x86汇编语言和PC引导的过程,逐渐熟悉QEMU和QEMU/GDB的调试。在本次lab中不需要写任何代码,但是需要lab中的各个问题。

Getting Started with x86 assembly

如果你已经熟悉x86汇编,那么就最好了。lab页面给的那个关于x86汇编的书确实挺不错的,比国内的书感觉好点。但是这书用的是AT&T的汇编语法,和intel语法有点不同,官网提供一个网址来帮助我们了解这两种语法之间的差异。

Simulating the x86

我们所开发的系统不是用于真正的物理PC机。我们将会使用一个模拟程序来模拟真实的机器:你所写的boot 程序同样也能在真实的PC机上引导。使用模拟机器简化了debugging,比如说,我们可以在x86内部打断点,这在真实的CPU当中是很难实现的。

在6.828当中,我们使用QEMU emulator,一个现代而且相对较快的模拟器。虽然QEMU内置了很多debug的工具,但是还是用GDB来调试比较方便。

The PC's Physical Address Space
现在我们要开始了解PC启动的细节了。PC机的内存结构如下所示:

内存结构图

最早的PC机,是基于16bit的Intel 8088处理器的,能访问的地址范围只有1MB。早期的PC机因此物理地址从0x0000_0000到0x000F_FFFF而不是0xFFFF_FFFF。低位的640KB地址是Low Memory是用于早期的电脑的内存;实际上早期的电脑只能使用16KB,32KB,或者64KB的内存。

从0x000A_0000到到0x000F_FFFF这384KB内存是保留给硬件的,比如说显存和一些固件使用的的内存。这一部分区域最重要的是BIOS(Basic Input/Output System),它占据从0x000F_0000到0X000F_FFFF这部分。在早期的PC机中,BIOS是保存在ROM(read-only memory)当中,但是现在的PC机都将BIOS存放在可更新Update flash system当中。BIOS负责的是基本的系统初始比如说,激活显卡,检查有多少内存安装了。在这些初始化之后,BIOS从软盘,硬盘,光盘,或者网络中加载操作系统,然后对机器的控制权交给操作系统。

当英特尔打破了1MB内存限制之后,比如说80286和80386处理器,能够分别支持16MB和4GB的内存,然而PC架构保存了原来的低1MB内存为了保证兼容现有的计算机软件。现代PC机因此有一个hole,从0x000A_0000到0x0010_0000,将RAM划分为 low或者 conventional memory(就是最开始的640KB)以及扩展内存。另外,在内存的最上面一部分,超过物理内存的上限,被BIOS预留用于PCI设备。

最近的x86处理可以支持超过4GB的机器,所以内存可以进一步扩展到0XFFFF_FFFF之上。在这样的情况下,在内存当中就又多了一个hole。因为JOS只是用内存的最开始256MB。

The ROM Bios

在这部分lab当中,你将会使用QEMU的debugging工具来研究IA-32机器是如何引导的。打开两个terminal,一个输入make qemu-gdb。这条命令启动了QEMU,但是QEMU停在了处理器执行第一条命令之前然后等待来自GDB的debugging conncectio。再打开一个窗口,输入make gdb,就会看到如下的内容(这是我的是实验截图):

image.png

我们提供.gdbinit文件来让GDB可以再引导的时候debug代码。
接下来的这一行代码:

[f000:fff0] 0xffff0:    ljmp   $0xf000,$0xe05b

是电脑开机后执行的第一条语句的反汇编后的结果,从这个输出结果,我们可以得出以下结论:

  • IBM PCs开始执行的第一条指令再0x000f:fff0,这是在内存区域最上面为BIOS预留的64KB
  • PC机器开始执行的时候,CS=0xF000,然后IP= 0xFFF0
  • 第一条执行的语句实际上是一条jmp指令,它跳转到了cs = 0xf000 ip=0xe05b处

QEMU为什么会这样开始?这就是英特尔如何设计8088处理器,IBM在他们最初的个人电脑上使用了它。因为BIOS是hard-wired在地址0x000f_0000到0x000f_ffff处,这样的设计确保了BIOS在开机后或者重启后能获得对电脑的控制权,此时内存中没有任何可运行程序。

接下来的就是实模式下的地址,在实模式下,物理地址 = 段地址*16 + 偏移,所以当CS = 0xf000,IP= 0xfff0的时候,物理地址就是0xffff0。0xffff0就是在0x1000之前的16字节处,所以这里只能存放一条跳转指令。对于这我们就不会意外了,毕竟就16字节能放多少代码呢?

你可能感兴趣的:(MIT6.828 Lab1 PC Bootstrap)