计算机启动过程

2019-04-13 15:12发布

目录
本文谈计算机的启动过程,分为以下几个部分:
  • 计算机执行的第一个程序是BIOS
  • BIOS做了什么工作,BIOS会加载并执行bootloader
  • bootloader是什么?又做了什么工作?
  • 引导记录如何帮BIOS找到bootloader

计算机加电后执行的第一条指令

BIOS是一个程序,它存放在主板的ROM区域。ROM是只读的、且断电后数据不丢失。主板在出厂时厂商就已经在ROM中写入了内容(包括BIOS)。
计算机加电后执行的第一个程序是BIOS。

寄存器初始值

8086 CPU在加电后对寄存器做一系列初始化,其中CS和IP被初始化为: 寄存器 位数 初始值 CS 16位 F000H IP 16位 FFF0H

第一条指令位于FFFF0H

CS和IP这两个寄存器共同决定了CPU要执行的下一条指令。加电后CS、IP的初值我们已经知道了,那么CS:IP所代表的地址就是FFFF0H(见8086分段寻址)。
因此CPU执行的第一条指令就是FFFF0H处的指令。F0000H~FFFFFH(共计64KB)是BIOS存放的区域,也就是说这64KB实际上被映射到ROM中。 很多人可能和我最开始的时候有同样的疑惑:20位的地址线可以表示1MB空间,难道这1MB空间并不是全部映射到内存中去?后来我明白了,其实地址有一部分对应到主板上的ROM、一部分映射到外设(如显示器)、剩下的才真正映射到内存。这也是为什么我以前在32位CPU上装了Windows系统后,明明插了4G的内存条,但在系统中看到只有3.8G的内存。

8086分段寻址

8086寄存器只有16位,为了能访问更大范围的内存,8086引入了分段寻址(段基址+偏移量)。
8086分段寻址的寻址空间只有20位,即1MB内存。1MB现在看来很小,但足以运行早期的DOS系统。

分段寻址的简单例子

CS和IP两个寄存器共同决定了地址,我们记CS和IP表示的地址为CS:IP。 考虑CS值为:F000H,IP值为:FFF0H。 CS左移四位得到:F0000H。那么F0000H就是段基址。 段基址+偏移量得到物理地址:F0000H + FFF0H = FFFF0H 这样就容易理解为何寻址空间是20位,因为16位的CS左移四位后可以表示的范围扩大到20位。

“回滚”机制

1MB的地址范围为:00000H ~ FFFFFH。 可能你也注意到了,CS:IP很容易超过1MB的空间产生溢出。 例如: FF00:FFFF = FF000 + FFFF = 10EFFF 8086的做法是这样的: 当CS:IP的地址超过范围时,会发生“回卷”。就是舍弃溢出的位,10EFFF变成0EFFF。 有了“回卷”机制,即使寻址大于1MB的地址时也不会发生异常。 “回卷”机制给8086带来了很大的便利,但也给未来的80286、80386带来不小的麻烦(我们之后会谈到A20)。

BIOS

既然计算机加电后能顺利进入BIOS执行,那么BIOS又做什么事呢?
大家在重装系统的时候都进过BIOS,大概也知道BIOS程序有什么功能:系统设置、开机自检等等。 但这里要讲的重点是:
BIOS最后会将磁盘中的引导扇区加载到内存中的0x7c00处,然后跳转到0x7c00处执行。 引导扇区:存放有bootloader程序。一个扇区只有512字节,所以bootloader程序要控制在512字节以内(在专门讲bootloader时会提到,其实是控制在446字节内)。 0x7c00:别问我为什么是0x7c00

Bootloader

主引导记录(MBR)

这里要解释为什么bootloader要控制在446字节内。 以后再补充

bootloader的主要工作

  • 使能A20
  • 使能保护模式、段机制
  • 加载操作系统,跳转到操作系统的入口点执行
以后再补充