基于 Intel 80×86 CPU 的 IBM PC 及其兼容计算机的启动流程
前段时间我在微博上看到了阮一峰的一篇日志 《计算机是如何启动的?》 才想起来自己之前也尝试探索x86
架构计算机的启动流程来着,趁着还没遗忘就先记录下一部分结论吧。不过相对于阮一峰的这篇博文,我的侧重点在于BIOS
查找“启动顺序”(Boot Sequence)
之前,也就是从按下电源到BIOS
移交权限之间的这一段。关于之后的过程,阮一峰描述的很详细,我就不重复造轮子了。
顺便罗嗦一下,有关“扩展分区”(Extended partition)的
细节,阮一峰这里是正确的,多个扩展分区是“链式”的串起来的。网上有不少说法是错误的。倘若读者质疑,不妨用WinHex
之类的工具直接以二进制打开磁盘,一看便知。Linux
也可以用dd
命令拷贝出磁盘的内容到文件,再查看文件内容。比如dd if=/dev/sda of=/tmp/xxx bs=512 count=1
什么的。
言归正传,开始我们的探索之旅吧。不过,我们不会深入到开机电路之类的硬件问题上去,毕竟,我们还是以一个程序员的角度来看待计算机。同时,我们假定读者能完全读懂并理解上面我提到的那篇阮一峰的博文并且能理解寻址空间,实模式、保护模式、端口独立编址和端口统一编址等相关术语名词。
我们从按下电源开始。
首先,是CPU Reset
。主板加电之后在电压尚未稳定之前,北桥控制芯片会向CPU
发出重置信号Reset
,此时CPU
进行初始化。当电压稳定后,控制芯片会撤销Reset
信号,CPU
开始工作。我们要探讨的第一个问题就是CPU
执行的第一条指令的位置。
现在网上流传的资料基本上是8086 CPU
的资料,给出的说法一般是这样:
CS
寄存器初始化为0xF000
,IP
寄存器初始化为0xFFF0
,所以按照CPU
实模式地址计算法则,CPU
执行的第一条指令地址是CS*10h+IP
,即0xFFFF0
这里。
8086 CPU
确实如此,但我们的问题是,80386
及其以上的CPU
怎么处理呢?其计算地址法则还是如此吗?当然不是,否则我说这些废话做什么。如果读者之前对实模式和保护模式寻址以及地址计算的理念根深蒂固的话,那么请先暂时忘却以前的认知,因为我下文说的也许有些惊世骇俗(我指的是相对于国产的某些教材来说)。
第一点,80386
及其以上的现代CPU
(以下CPU
说的都是指80386
以上的)加电Reset
之后并不是直接进入实模式
;
第二点,CPU
在合成地址的时候并不区分实模式和保护模式。