计算机 x86 开机启动原理

========================

一. 启动BIOS

1. 启动BIOS是通过硬件的特殊设计完成的

加电瞬间强行置 CS:0xFFFF,IP:0x0000,如此 CS:IP 就指向 0xFFFF0。BIOS 的入口地址即为0xFFFF0

2.定位BIOS后便开始执行BIOS代码(比如自检)。最重要的任务就是在内存中建立中断向量表和中断服务程序。

如: 0x00000—0x003FF 的1KB构建中断向量表
   0x00400—0x004FF 用256字节构建 BIOS 数据区
   0x0E2CE 加载了 8KB 左右的中断服务程序

PS: CPU加点后首先在16位实模式下工作(故:CS:0xFFFF)

      代码既是电路,电路既是代码,设计固定的代码电路(硬件的特殊设计)

 

二. 加载操作系统内核

1.第一步加载引导程序到内存。

BIOS程序发出int 0x19中断,CPU在中断向量表中找到中断服务程序入口地址后执行。此段代码BIOS设计好,与操作系统无关。此中断程序把软驱的0号磁头对应盘面的0磁道1扇区的内容拷贝至内存0x07C00,此扇区的内容即是linux 0.11的引导程序bootsect,他会把软盘中的操作系统陆续加载进内存

   两头约定,定位识别

两头约定就是指约定操作系统必须把最开始执行的代码放在0盘面0磁道1扇区,约定BIOS在接到启动命令后要把启动扇区的代码加载到0X07C00。这样只要操作系统的设计者和BIOS的设计者遵照这个约定,BIOS就能顺利的引导操作系统的启动。

2.第二步,加载setup代码

linux设计者很好的规划了实模式下1MB内存的使用:
===============================================================
SETUPLEN = 4    ! nr of setup-sectors
BOOTSEG  = 0x07c0   ! original address of boot-sector
INITSEG  = 0x9000   ! we move boot here - out of the way
SETUPSEG = 0x9020   ! setup starts here
SYSSEG   = 0x1000   ! system loaded at 0x10000 (65536).
ENDSEG   = SYSSEG + SYSSIZE  ! where to stop loading

步骤

首先要复制bootsect,就是把自己从BOOTSEG位置复制到INITSEG。从现在起操作系统已经不需要依赖BIOS,可以完全按照自己的意图分配内存使用。

将Setup程序加载到内存需要依靠BIOS提供的int 0x13中断向量所指的中断服务程序(磁盘服务程序)。使用0x13中断必须先给他“传参”,指定的扇区和加载内存的位置传给他。

linux会从第2个扇区到第4个扇区加载至内存0x90200处

3. 加载system模块。使用的依然是int 0x13中断

    看书 《linux内核完全注释》... ...