【我所認知的BIOS】-->第一条指令

2019-04-13 20:48发布

【我所認知的BIOS-->第一条指令

By LightSeed 2009-10-26   其实早就想写这样一篇文章了,今天才着手写了下。说来也惭愧关于CPU的第一条指令的问题,在一开始study的时候我自己并没有求甚解,所以当时理解的也比较肤浅,今天我们来详细探讨一下关于reset(从没电到上电)后CPU执行第一条指令的一些东西。(说明一下:这篇文章是讨论的IA32架构上的处理器。)

1、准备知识

如果您还对Flat mode的原理还不太了解的话,那么我想你可以再回头参考一下关于Flat mode的原理。见 http://blog.csdn.net/lightseed/archive/2009/07/01/4312834.aspx 在保护模式下,我们的段寄存器其实都是由两部分组成的:一步分是可见的段选择子(segment selector),另外一部分是隐藏的基地址(base address)。那么第一条指令就和这个密切相关。

2CPU到哪里去取第一条指令

开门见山,当HW reset后,CPU会到(物理地址为)0FFFF FFF0H处去取指令并执行之。这个地址很明显是CPU的最高物理地址往下数16bytes的地址处。BIOS的第一条指令必须要被放到这里,否则的话。。。后果可想而知。

3、为什么是这里

我想只要是刚入门的freshman都会感到比较疑惑,这个地址(FFFF FFF0H)明明是大于1-Mbyte的地址了,而此时的CPU却是在实模式下的,那么CPU是怎么到这里去取指令的呢?

3.1 原理

不过看完上面这段话的描述,我们是不是感觉有点亲切呢?再回忆一下,其实在我们之前的讨论中关于Flat mode的时候,就接触到个概念了。在Flat mode中的时候,虽然我们是处于实模式,但是由于我们的段寄存器(segment register)是由两个部分组成的,一部分是可见的段选择子,另外一部分是隐藏部分(段基地址)。如果我们在protect mode中修改好了段寄存器的段基地址部分,然后返回实模式,那么只要不显示地修改段寄存器,CPU在寻址的时候仍然会照protect mode下的寻址方式来计算地址,即:segment selectoroffset

3.2 BISTCPU的状态

经过正确的power sequence后,CPU吃到CPURST#正常BISTBuilt-In Self-Test)后,CPU其实就正是处于Flat mode中。(比较特殊的实模式)那么让我们来看看正常的BIST后,CPU的(部分)寄存器的状态吧。见图1   1 BIST后部分寄存器的值   2 CPU关于CR0bit定义 看清楚了图2中定义的CR0bit0了么?PE,是指protect mode enable。那么我们再结合图1两个方框处关于CR0CS的初始值,可以很清楚地看到这个时候CPU是处于实模式的,然而CSBase却是等于FFFF0000H的,而且段界限是FFFFH,并且CS的选择子是等于F000H的。

3.3 详细计算

那这样以来,如果我们用CS:IP是用F000H:FFF0H的方式来操作的时候,CPU其实是会把地址这样算的。F000HCS的段选择子,从这里取出CS的基地址(就是FFFF0000H)再加上IP的值(FFF0H)就等于实际要访问的内存地址(正好是FFFF FFF0H[FFFF0000+FFF0H=FFFFFFF0H]。所以在32bitCPU上,这个第一条指令的计算是这样来的。 不过一般情况下HW reset后,BIOS都会在第一条指令这里安排一个far jump来显示地修改CS的值,目的就是能够让CS真正进入real mode。就是让CS能够遵从正常的real mode的寻址翻译规则。(CS base address = CS segment selector * 16)。那至于后面的BIOS coderun的环境,我想大家就都应该了解了。 关于第一条指令的讲述Bini前辈也曾详细说明过,这里是连接供大家参考。 http://www.ufoit.com/bbs/thread-106-1-1.html