1.2 After Power-On

[Home]  [Top]  [Previous]  [Next]


1.2.1 Overview

 

BIOS扮演的最重要的角色之一就是启动系统。当PC被打开时,它的系统内存中是空的,它需要马上找到一条代码以启动机器。这些代码就在BIOS中,因为BIOS被放置在ROM中,所以即使系统内存的其它部分是空的,但BIOS中的程序却总是可以使用的。

 

这一节我们来看一看在Power-on之后的“硬件”Booting阶段,系统到底都做了些什么。同时,也看一看通过硬盘启动OS和软盘启动OS之间究竟存在着哪些不同。


1.2.2 First Instruction Executed

 

CPU从物理地址FFFFFFF0h取出并执行硬件Reset之后的第一条指令。这个地址到最大物理地址4 GB之间只有16 Bytes的空间,包含软件初始化代码的EPROM必须被影射到这个地址。在Real Mode下,地址FFFFFFF0h超过了1 MB的物理地址范围。CS寄存器被分为两部分:可见的“Segment Selector”部分和隐藏的"Base Address"部分。

 

在Real Address Mode下,"Base Address"部分的值,等于将16-bit的"Segment Selector"左移4-bit所形成的20-bit地址,"Segment Selector"部分并不参与物理地址的计算,在Real Mode下,它仅仅被用来计算"Base Address"部分。而"Base Address"部分被真正的用于实际物理地址的计算。

 

在硬件Reset期间,CS中的"Segment Selector"部分被初始化为F000h,而"Base Address"部分被初始化为FFFF0000h,这与上述的原则不相符,但没有关系,因为"Base Address"已经有一个值了。所以,第一条指令的地址为Base Address + EIP = FFFF0000h + FFF0h = FFFFFFF0。

 

EPROM中放置着PC厂商所编写的代码(BIOS),被影射在地址FFFFFFF0h的代码必须为一条"far jump"或者"far call"指令或者产生一个中断,这样CS的"Segment Selector"的值将会被改变,从而"Base Address"部分的值也按照上述计算原则被改变为BIOS代码的影射地址。

从此以后,BIOS Boot Sequence代码开始被执行。


1.2.3 System Boot Sequence

 

系统BIOS是机器被加电之后首先被运行的程序。我们下面看一看一个典型的Boot Sequence所包含的步骤,当然,由于硬件BIOS厂商的不同,这些序列会有一些不同,但下面所列的,是你的主机被加电之后,通常都会发生的序列。

  1. 当机器被打开时,等电源稳定之后,电源会发送一个“加电成功信号”给芯片,以启动时钟生成器(8284);
  2. 然后,CPU重新自设定为初试状态,开始准备运行。当CPU最初被启动的时候,系统RAM中是空的,没有任何内容可供执行。当然CPU设计者也知道这一点,所以他们对CPU进行了预先编程,以让CPU在这个阶段总是去查找系统BIOS ROM中的一个固定的位置,以启动BIOS Boot Program,这个位置为FFFF0h,这个位置是UMA临近结尾的位置。之所以选择这个位置是因为,这样就不会引起由于ROM的大小改变而造成的兼容性问题。既然FFFF0h到UMA结束的位置之后16个字节,所以这里只放置着一个Jump指令,以进一步跳转到真正的BIOS startup program的位置。(不同的BIOS厂商可以将其放在不同的位置,只需要通过Jump指定就可以了)。
  3. 然后BIOS开始实施Power-On Self Test(POST),在这个过程中,如果遇到任何错误,Booting处理就会结束,机器会被挂起。
  4. 然后BIOS开始查找显示卡。精确的说,是查找被内建在BIOS内部的显示卡程序,并执行它,它通常被放在C0000h的内存位置,它的作用是初始化显示卡。绝大多数的现代显示卡都能够在显示器上显示它的相关信息。这就是为什么当我们开机的时候,首先会在显示器的顶端会出现关于显示卡的信息。
  5. 然后BIOS会查看其它设备的ROM,看一看这些设备之中哪些存在着BIOS,通常能够在C8000h的位置找到IDE/ATA硬盘的BIOS,并执行它们。如果找到任何其它设备的BIOSes,它们也会被执行。
  6. 然后BIOS显示它的启动屏幕。
  7. 然后BIOS开始做进一步的检测,包括我们可以看到的内存容量检测。在这个阶段,如果BIOS遇到任何错误,BIOS将会在屏幕上显示它的错误信息。
  8. 然后BIOS会根据自己的"系统资源列表“,来对系统资源进行进一步的检测以确定究竟那些系统资源(设备)被安装在机器上。有些计算机会逐步显示这些被检测到的设备。
  9. 如果BIOS支持Plug&Play标准,它将会检测和配置Plug&Play设备,并显示这些它找到的设备。
  10. 等着一些检测结束之后,BIOS会在系统屏幕上列出一个检测总结。
  11. 然后BIOS开始寻找一个启动设备,你可以通过配置BIOS来决定其搜索的顺序,这些设备包括Floppy Disk(A:),或者Hard Disk(C:),甚至还可以包括CD-ROM Driver或者其它设备。
  12. 当找到响应的启动设备之后,BIOS将会查找Boot信息以开始OS的启动过程。如果它找到了一个Hard Disk,它将会查找一个位于Cylinder 0, Head 0, Sector 1的Master Boot Record(硬盘的第一个扇区),如果它找到的是Floppy Disk,它也会读区软盘的第一个扇区。
  13. 如果找不到任何启动设备,系统将会显示一条错误信息,然后冻结系统。如果找到了响应的启动设备,BIOS会将读到的扇区放在内存7C00h的位置,并跳转到那里执行它。从此以后,就有硬件启动阶段进入了OS启动阶段。

总之,这个阶段有大量的事情要做,比如自检,初始化各种芯片,控制器,与端口;包括显示器,内存,键盘,软驱,串口等等;在这个过程中BIOS将检测到的数据放置于1K2KRAM,这个区域因此也被称为BIOS Data Area;同时还将中断向量以及BIOS程序运行所需要的Stack设置置于01KRAM。最终,POST执行INT 19h中断,找到可以启动的磁盘,并将boot程序装入内存7C00h,并将控制权交给OS的boot程序。

 


 

1.2.4 OS Boot Sequence

 

当BIOS INT 19h被执行以后,系统进入OS Booting阶段。

 

下面定义几个程序段名称:

Name Description Size limit
Master Booter 放置于Hard disk的第一个扇区(即MBR),用于装载boot block的程序。 466 bytes
Boot Sector 放置与Floppy的第一个扇区,或者Hard disk的某一分区的第一个扇区的用于装载Secondary boot,或其它程序的可运行程序。 512 bytes
Secondary Boot 放置于非Floppy/Hard disk的第一个扇区,以及Hard disk的任意分区的第一个扇区之外的任意其它位置,用于装载OS,或其它程序的可运行程序。 no limit

 

当用硬盘启动OS的时候,以上调用顺序为 MB -> BS -> SB -> OS;

当用软盘启动OS的时候,以上调用顺序为 BS -> SB -> OS。

 


 

1.2.4.1 硬盘启动

 

硬盘的第一个扇区(sector)被称作MBRMaster Boot Record)。由于硬盘可以有多个分区,所以MBR上,不仅放置着用于启动的可执行代码master boot,还放着磁盘分区表(DPT),占用66个字节,所以MBR中的可执行代码必须在512 - 66 = 446个字节以内。

 

Offset Content Size
0h Master booting program max 466 bytes
01BEh Disk Partition Table 64 bytes
01FEh Signature (HEX 55 AA) 2 bytes

 

Table 1.2.1- MBR Layout

 

 

Offset Content Size
01BEh Partition 1 data table 16 bytes
01CEh Partition 2 data table 16 bytes
01DEh Partition 3 data table 16 bytes
01FEh Partition 4 data table 16 bytes

Table 1.2.2 - DPT Layout 

 

Offset Content Data Type
00h boot indicator byte
01h beginning sector head number byte
02h beginning sector (2 high bits of cylinder #) byte
03h beginning cylinder# (low order bits of cylinder #) byte
04h system indicator byte
05h ending sector head number byte
06h ending sector (2 high bits of cylinder #) byte
07h ending cylinder# (low order bits of cylinder #) byte
08h number of sectors preceding the partition dword(4 bytes)
0Bh number of sectors in the partition dword

Table 1.2.3 - Layout of Partition Data Table

Boot indicator (BYTE)

       00  - non-bootable partition

       80  - bootable partition (one partition only)

 

System Indicator (BYTE)

       00 - unknown operating system

       01 - DOS with 12 bit FAT, 16 bit sector number

       02 - XENIX

       04 - DOS with 16 bit FAT, 16 bit sector number

       05 - DOS Extended partition (DOS 3.3+)

       06 - DOS 4.0 (Compaq 3.31), 32 bit sector number

       51 - Ontrack extended partition

       64 - Novell

       75 - PCIX

       DB - CP/M

       FF – BBT

 

Signature

       Hex 55AA marks the end of valid boot sector.

       This is also required in each of the partition boot records.

 

What does master booter should do?

 

        INT 19会将MBR512 bytes load到内存0x7c00中,然后JUMP0x7c00处,开始执行MBR的可执行程序master booter,Master booter最起码需要做这些事情:

  • 检测MAGICSignature)是否为合法值(Hex 55AA);
  • 将自己移动到其它位置,将0x7C000x7c00+512K的空间让出来,以备其后将boot sector程序装入这个位置,这样才能和直接从软盘直接装入boot sector程序相一致;具体移动到什么位置,则根据设计而定,理论上,可以移动到任何非冲突位置(即没有被预留为其它程序所用的位置);但一般情况下,都是在0X0008000X0A0000之间寻找一端空间存放。

  • 查看分区表,将被设为活动的分区的第一个Sector装入0X7C00的位置,正常的情况下,此Sector放置的就是boot sector程序;

  • 最终,master booter跳转到0X7C00的位置,开始执行boot sector

1.2.4.2 软盘启动

 

相对于硬盘启动过程,软盘启动则要简单的多,只需要将boot sector程序放置于软盘的第一个扇区。当INT 19从软盘启动的时候,会自动将boot sector读入内存的7C00h的位置,然后跳转到7C00h开始执行。

 


 

1.2.5 Other Information

 

下面是摘自于HELPPC2.1中的有关机器启动过程的信息:

 

POST - Cold Boot / Power On Self Test Activities

 - power supply starts Clock Generator (8284) with Power
   Good signal on BUS
 - CPU reset line is pulsed resetting CPU
 - DS, ES, and SS are cleared to zero

 

 Cold and Warm Boot both execute the following sequence
 - CS:IP are set to FFFF:0000 (address of ROM POST code)
 - jump to CS:IP  (execute POST, Power On Self test)
 - interrupts are disabled
 - CPU flags are set, read/write/read test of CPU registers
 - checksum test of ROM BIOS
 - Initialize DMA (verify/init 8237 timer, begin DMA RAM refresh)
 - save reset flag then read/write test the first 32K of memory
 - Initialize the Programmable Interrupt Controller (8259)
   and set 8 major BIOS ~interrupt~ vectors (interrupts 10h-17h)
 - determine and set configuration information
 - initialize/test CRT controller & test video memory (unless 1234h
   found in reset word)
 - test ~8259~ Programmable Interrupt Controller
 - test Programmable Interrupt Timer (~8253~)
 - reset/enable keyboard, verify scan code (AAh), clear keyboard,
   check for stuck keys, setup interrupt vector lookup table
 - hardware interrupt vectors are set
 - test for expansion box, test additional RAM
 - read/write memory above 32K (unless 1234h found in reset word)
 - addresses C800:0 through F400:0 are scanned in 2Kb blocks in
   search of valid ROM. If found, a far call to byte 3 of the ROM
   is executed.
 - test ROM cassette BASIC (checksum test)
 - test for installed diskette drives & ~FDC~ recalibration & seek
 - test printer and RS-232 ports.  store printer port addresses
   at 400h and RS-232 port addresses at 408h.  store printer
   time-out values at 478h and Serial time-out values at 47Ch.
 - NMI interrupts are enabled
 - perform ~INT 19~ (bootstrap loader), pass control to boot record
   or cassette BASIC if no bootable disk found
 - ~WARM BOOT~ procedure is now executed

 


 

1.2.6 For Further Reading

 

1.How It Works -- OS2 Boot Sector