BIOS启动过程分析

1        引言

1.1    文档目的

对于电脑用户来说,打开电源启动电脑几乎是每天必做的事情,但计算机在显示这些启动画面的时候在做什么呢?大多数用户都未必清楚了。下面就向大家介绍一下从打开电源到出现Linux的登录窗口,计算机到底干了些什么工作,BIOS在其中起到什么作用。

电脑的启动过程中有一个非常完善的硬件自检机制。对于采用Award BIOS的电脑来说,它在上电自检那短暂的几秒钟里,就可以完成100多个检测步骤。

1.2    术语和缩写


术语或缩写


描述


BIOS


基本输入/输出系统


CMOS


保存系统当前的硬件配置情况和用户的设定参数


POST


Power on self test, 加电自检


 


 

 

2       基本概念

2.1    BIOS

BIOS即基本输入/输出系统,它是被固化在计算机ROM芯片上的一组程序。它是微机系统软、硬件之间的一个可编程接口,通过跳线开关和系统配带的驱动程序盘,可以对ROM进行重写,方便地实现BIOS升级。

2.2    CMOS

CMOS是一块可读写的RAM芯片,保存系统当前的硬件配置情况和用户的设定参数;BIOS中装有一个程序称为“系统设置程序”,设置CMOS中的参数;CMOS由电池供电,断电后数据会丢失;前16字节用于存储时间

2.3    AMI、AWARD和PHONIX三大主流厂商

开发BIOS是一件技术含量很高的工作,从业人员也少;一流主板厂商的BIOS研发人员,年薪往往是以七位数字来计算的!

 

3       BIOS主要功能

BIOS的主要功能概括来说包括如下几部分:

1)POST

加电自检,检测CPU各寄存器、计时芯片、中断芯片、DMA控制器等

2)Initial

枚举设备,初始化寄存器,分配中断、IO端口、DMA资源等

3)Setup

进行系统设置,存于CMOS中。一般开机时按Del或者F2进入到BIOS的设置界面。

4)常驻程序

INT 10h、INT 13h、INT 15h等,提供给操作系统或应用程序调用。

5)启动自举程序

在POST过程结束后,将调用INT 19h,启动自举程序,自举程序将读取引导记录,装载操作系统。

4       BIOS源代码结构分析

4.1    AMI BIOS代码结构分析

AMI BIOS的代码主要分成三大部分:核心代码、芯片代码和OEM代码。

核心代码目录结构如下:

4.2    AWARD BIOS代码结构分析

AWARD BIOS的源代码为进行目录分类,所有的源码、编译链接工具、生成的中间文件都在同一个目录中。没有AMI代码结构组织得好。

5       BIOS常驻程序介绍

开机自检程序运行完后,将撤出内存。BIOS提供了一组常驻程序,主要包括INT 10h,INT 13h,INT 15h等等中断服务例程,提供给操作系统或应用程序调用,下面介绍几个常用的中断服务例程。X86提供了256个中断,中断向量表在内存的起始地址1024byte上,每个中断向量地址占用4个字节。

5.1    INT 13h中断例程

INT 13h为BIOS提供的对磁盘进行操作的中断例程,包括如下几种调用方式:

1)INT 13H,AH=00H 软、硬盘控制器复位;

2)INT 13H,AH=02H 读扇区说明;

3)INT 13H,AH=03H 写扇区;

4)INT 13H,AH=04H 检测扇区;

以上调用方法详细的说明请参考相关技术文档。

举例:读取软驱0面0道1扇区的内容到0:200

mov ax,0                     /* 初始化ax寄存器为0 */

mov es,ax                    /* 将es置为0 */

mov bx,200h        /* 将bx设置为200h ,此时es:dx = 0:200,为内存地址*/

mov al,1                      /* al保存扇区数 */

mov ch,0                     /* ch保存磁道号 */

mov cl,1                  /* cl保存扇区号 */

mov dl,0               /* dl保存驱动器,0表示软驱A */

mov dh,0                     /* dh保存磁头号 */

mov ah,2                     /* ah保存int13要调用的功能号,2表示读 */

int 13h                         /* 调用int13中断 */

入口参数:

ah=int 13h的功能号

al=读取的扇区数

ch=磁道号

cl=扇区号

dh=磁头号(对于软盘即面号,因为一个面用一个磁头来读写)

dl=驱动器号 软驱从0开始,0:软驱A,1:软驱B;硬盘从80h开始,

80h:硬盘C,81h:硬盘D。

es:bx指向接收从扇区读入数据的内存区

返回参数:

操作成功:ah=0,al=读入的扇区数

操作失败:ah=出错代码

 

5.2    INT 10h中断例程

屏幕I/O接口,切换各文字/图形模式,提供显示/绘图卷页服务。详细的调用方法可以参考相关的文档。例如00号功能:

功能号:00H

功能:设置显示模式
入口参数:AH=00H
   AL=显示模式
显示模式列表:

显示模式  显示模式属性
  00H       40×25    16色 文本
  01H       40×25    16色 文本
  02H       80×25    16色 文本
  04H       320×200   4色
  05H       320×200   4色
  06H       640×200   2色
  07H       80×25     2色 文本
  08H       160×200  16色
  09H       320×200  16色
  0AH       640×200   4色
  0BH       保留
  0CH       保留
  0DH       320×200  16色
  0EH       640×200  16色
  0FH       640×350   2色(单色)
  10H       640×350   4色
  11H       640×480   2色
  12H       640×480  16色
  13H       320×200 256色

 

5.3    INT 16h中断例程

BIOS提供的键盘读取中断服务,功能如下表:


AH


功能


返回参数


0


从键盘读一字符


AL=字符码

AH=扫描码


1


读键盘缓冲区的字符


如ZF=0

AL=字符码

AH=扫描码

如ZF=1,缓冲区空


2


取键盘状态字节


AL=键盘状态字节

 

调用方法:

MOV  AH,0         ; 读字符功能
INT   16H          ; 键盘BIOS调用

 

5.4    用debug工具获取中断例程的内存地址

在DOS模式下,进入DEBUG,输入

a100

int 10

t=100

得 0210:08A9

int 10h的中断服务程序入口地址存放在中断向量表中的物理地址是0000:0040H~0043H,指向CS:IP(0210:08A9),如下图执行结果:


 

6       启动过程分析

6.1    Linux系统开机启动的总体流程

 

 

6.2    BIOS启动过程概述

BIOS启动的过程主要包括POST过程和自举过程,其流程和执行指令地址的变化如下:

 

6.3    POST过程分析

POST过程在AWARD BIOS的源码中在BOOTROM.ASM文件中BootBlock_POST函数过程中实现,主要步骤如下:

1)初始化各种主板芯片组

2)初始化键盘控制器8042

3)初始化中断向量 ,中断服务例程.

4)初始化 VGA BIOS 控制器

5)显示BIOS的版本和公司名称

6)扫描软驱和各种介质容量

7)读取CMOS的启动顺序配置,并检测启动装置是否正常

8)调用INT 19h启动自举程序

以上每个过程都有大量的代码,在这不一一做仔细分析,请参考源代码。下面对第三步源码做一些分析。

6.4    中断向量表初始化过程源码分析

中断向量表存储在内存的第一个1k空间里,本节主要分析AWARD BIOS中中断向量服务例程的初始化过程。

;[]==============================================================[]

;

;      Initialize int. vectors (0-77h) to the spurious interrupt

;      handler. Then initialize 00h-1fh to their proper places.

;

;[]==============================================================[]        

POST_CODE 12

 

              mov ax,cs

              mov ds,ax

 

;

;      Initialize vectors 00-77h to SPURIOUS_INT_HDLR

;   。。。。。。

       。。。。。。

       。。。。。。

;

;      Initialize vectors 00-1fh to the real handlers

;

 

              lea   si,DGROUP:Int_Tbl

p10_21:

              lodsb                           ;load next offset

              cmp al,0ffh                   ;over?

              je    short Init_Vect_Over   ;Yes,skip

              movzx    di,al               ;get vector number

              shl   di,2                      ;set to coresspond offset

              movsw                        ;load offset from DS:[SI]

              mov ax,cs             ;get segment

              stosw                          ;load segment

              jmp short p10_21 ;next cycle

Init_Vect_Over:

 

              mov al,10111100b              ;Enable IRQ 0,1,6

              out  a8259+1,al

              sti

看以上蓝色部分代码,为初始化中断服务例程,红色部分Int_Tb1为BIOS定义的中断服务例程列表,用于替换相应的中断服务。Int_Tb1的定义如下:

INT_TBL:     db   2                          ; INT02

              DW OFFSET DGROUP:NMI_VECT           ; INT02 offset

              db   6                          ; INT06

              DW OFFSET DGROUP:LOADALL             ; INVALID OP-CODE

              db   8                          ; INT08

              DW OFFSET DGROUP:TIMER_VECT       ; INT08 offset

              db   9                          ; INT09

              DW OFFSET DGROUP:KBDINT_VECT    ; INT09 offset

              db   0eh                       ; INT0E

              DW OFFSET DGROUP:DSKINT_VECT     ; INT0E offset

              db   11h                       ; INT11

              DW OFFSET DGROUP:EQ_VECT              ; INT11 offset

              db   12h                      ; INT12

              DW OFFSET DGROUP:MEM_SZ_VECT   ; INT12 offset

              db   13h                      ; INT13

              DW OFFSET DGROUP:DSK_VECT           ; INT13 offset

              db   15h                      ; INT15

              DW OFFSET DGROUP:Multi_Service   ; INT15 offset

              db   16h                      ; INT16

              DW OFFSET DGROUP:KBD_VECT           ; INT16 offset

              db   19h                      ; INT19

              DW OFFSET DGROUP:INT19_VECT  ; INT19 offset

              db   1Ah                      ; INT1A

              DW OFFSET DGROUP:INT1A_VECT       ; INT1A offset

              db   1Eh                      ; INT1E

              DW OFFSET DGROUP:FD_BIOS_PARMS       ; INT1E offset

              db   0ffh                      ; over

中断服务例程对应的函数也在Bootrom.asm文件中有实现。替换的中断服务例程总结如下。


中断号


BIOS中断例程


属性


备注


INT02


NMI_VECT


硬中断


None Maskable Interrupt,不可屏蔽中断


INT06


LOADALL


错误中断


非法,不支持的指令


INT08


TIMER_VECT


硬中断


IRQ0,系统定时器中断


INT09


KBDINT_VECT


硬中断


IRQ1,键盘中断


INT0E


DSKINT_VECT


硬中断


IRQ6,软盘驱动器读写中断


INT11


EQ_VECT


软中断


PC外围设备检查


INT12


MEM_SZ_VECT


软中断


PC主存储器大小检查


INT13


DSK_VECT


软中断


磁盘I/O接口(读写、复位等)


INT15


Multi_Service


软中断


卡带接口服务程序,AT扩展中断服务调用,程序多任务


INT16


KBD_VECT


软中断


键盘读取服务程序


INT19


INT19_VECT


软中断


激活操作系统的入口点


INT1A


INT1A_VECT


软中断


BIOS时间接口


INT1E


FD_BIOS_PARMS


软中断


软盘驱动器参数地址表

AWARD的其他中断服务调用未在BIOS中指定服务例程。

6.5    自举过程源码分析

自举过程即为执行中断INT19的中断服务例程INT19_VECT的过程,该过程在AWARD的Bootrom.asm文件中实现,其主要功能为读取操作系统启动块,将其读入到内存0000:7C00h,并跳转至此处执行。下面分析一下操作系统启动块MBR是如何从磁盘中读取到内存0000:7C00h处的。

new_dsk:

              xor  dx,dx

              mov es,dx                    ; set to load at 0:offset Boot

 

              mov bx,offset Boot       ; location to load boot sector

              mov cx,1                      ; set to read one sector

[U1] 

              xor  ax,ax

              int    13h                             ; reset disk

[U2] 

              mov ax,0201h              ; read boot record

              int    13h                             ; read disk

              jc    short Boot_fail

[U3] 

              call  Check_Boot_Record  ; check boot sector valid ?

              jc    short Boot_fail             ; invalid boot sector.

              jmp far ptr Boot               ; go to boot code

[U4] Boot_Fail:

              lea   ax,Bad_Disk_Msg       ; boot failed

              mov cx,Bad_Disk_Msg_Len

              call  Disk_Fail_Routine

[U5]         xor  ax,ax                           ; g_ram

              jmp short new_dsk

[U6] 

 

 

Disk_Fail_Routine:

 

              mov dx,0ff01h

              call  Display_Str

 

       ;Beep out if no bootable media

              mov bl,2                      ; beep on override

              mov cx,1700h

              call  SND_SPKR_TONE

              xor  cx,cx

              loop       short $

              mov bl,5                      ; beep on override

              mov cx,3000h

              call  SND_SPKR_TONE

[U7] 

       ;wait for "Enter" key to continue

endless:

              xor  ah,ah                           ;wait ENTER key

              int    16h

              cmp ah,1ch

              jne   short endless

 

              ret

[U8] 

流程图如下:

 

7       参考资料

1)AMI和AWARD的BIOS源码

2)grub-0.97.tar.gz源码

3)AMI BIOS98 User Guide

4)AMI BIOS98 Technical Reference

5)《BIOS研发技术剖析》

6)网站搜索内容:

BIOS之家:www.bios.net.cn

Google

 [U1]初始化es:dx = 0000:7C00

 [U2]复位磁盘

 [U3]读取引导记录,失败则跳转至Boot_Fail

 [U4]检查启动扇区内容是否有效,无效则跳转至Boot_Fail,有效则直接跳转至启动代码

 [U5]Boot_Fail过程,初始化启动失败信息,并调用磁盘失败例程

 [U6]跳转至new_dsk,重新引导

 [U7]磁盘失败例程,显示启动失败信息,并发出两次报警

 [U8]等待用户输入”Enter”键,并返回至调用处,即批注U6处。

时间: 2024-12-22 21:07:17

BIOS启动过程分析的相关文章

U盘装系统之BIOS启动项设置

所有想通过制作U盘启动工具的装系统的人都应该知道,在电脑启动时,只有将U盘设置为第一启动项才会从U盘引导启动进入PE环境.从而可以在PE环境下对电脑硬盘重新分区 或者在PE环境下ghost安装系统.那如何将U盘设置为计算机的第一启动项呢?这主要跟BIOS主板有关,而国内市场上的BIOS主板厂商非常的多,从而导致计算机进入BIOS界面的按键都不太一样.常见的主要是F2,F3,F11,F12,当然也有通过esc进入BIOS设置界面的.另外还有一些产生可以不用进入BIOS界面而直接通过某个按键调整启动

UEFI启动与BIOS启动有何区别?

  UEFI启动是什么意思? 通俗的说,新的主板引导初始化的标注设置,相对于BIOS来说的,以前的U盘引导都是针对BIOS的,没法在UEFI主板上引导UEFI的文件到PE里,也有的PE把这个精简了.UEFI全称"统一的可扩展固件接口",是一种详细描述类型接口的标准.这种接口用于操作系统自动从预启动的操作环境,加载到一种操作系统上. UEFI启动是一种新的主板引导项,正被看做是有近20多年历史的BIOS 的继任者.顾名思义,快速启动是可以提高开机后操作系统的启动速度.由于开机过程中UEF

BIOS启动和UEFI启动比较说明

UEFI启动是什么意思? 通俗的说,新的主板引导初始化的标注设置,相对于BIOS来说的,以前的U盘引导都是针对BIOS的,没法在UEFI主板上引导UEFI的文件到PE里,也有的PE把这个精简了.UEFI全称"统一的可扩展固件接口",是一种详细描述类型接口的标准.这种接口用于操作系统自动从预启动的操作环境,加载到一种操作系统上. UEFI启动是一种新的主板引导项,正被看做是有近20多年历史的BIOS 的继任者.顾名思义,快速启动是可以提高开机后操作系统的启动速度.由于开机过程中UEFI的

BIOS启动时有报警声

  在BIOS启动的时候,如果有报警声,那就说明电脑存在一些故障.不同的报警声代表不同的故障所在,可以按照报警声判断故障. 1.Award BIOS 1短:系统正常启动,代表电脑没有任何问题. 2短:常规错误,进入CMOS Setup,重新设置不正确的选项. 1长1短:内存或主板出错,更换一条内存试试,如果不行,只有更换主板. 1长2短:显示器或者显卡出错. 1长3短:键盘控制器错误,检查主板. 1长9短:主板Flash RAM或EPROM错误,BIOS损坏.换块Flash RAM进行尝试. 不

ActivityManagerService启动过程分析

之前讲Android的View的绘制原理和流程的时候,讲到过在Android调用setContentView之后,Android调用了一个prepreTravle的方法,这里面就提到了ActivityManagerService. ActivityManagerService提供的主要功能:       (1)统一调度各应用程序的Activity       (2)内存管理       (3)进程管理 上一篇我们分析Android启动过程的文章中我们分析到了SystemServer,当时我们只是

《Android框架揭秘》——1.2节通过启动过程分析Android Framework

1.2 通过启动过程分析Android FrameworkAndroid框架揭秘Android源码数量极其庞大,以Android 2.2为例,除去Linux代码,代码数量大于4GB.若想理解和掌握这么庞大的Android系统,需要耗费大量的时间,付出极大的努力.并且,到现在为止,也没有相关资料对Android Frame作系统完整的讲解说明. 那么,分析Android Framework用什么方法好呢?回答这一问题之前,先回想一下我们是如何分析他人编写的程序代码的.在分析程序代码时,我们通常从程

OpenWrt启动过程分析+添加自启动脚本【转】

一.OpenWrt启动过程分析 转自: http://www.eehello.com/?post=107   总结一下OpenWrt的启动流程:1.CFE->2.linux->3./etc/preinit->4./sbin/init ->5./etc/inittab ->6./etc/init.d/rcS->7./etc/rc.d/S* ->8.    OpenWrt是一个开放的linux平台,主要用于带wifi的无线路由上. 类似于Ubuntu.Red Hat.

探讨Linux内核启动之BIOS启动阶段

本文讲解linux内核启动之BIOS启动阶段,640KB的RAM是BIOS设计者自由使用的区域,如何使用取决于 BIOS软件的设计者,4GB的物理地址空间至少被划分为两个部分,一部分是内存的地址空间,另外一部分地址空间用于对BIOS芯片存储单元进行寻址. Linux内核启动有很多值得学习的地方,这里我们主要介绍BIOS启动阶段,包括介绍指令寄存器CS:EIP等方面. Linux内核启动代码复杂.庞大,让人感觉难以入手,正是因为它的复杂性,任何一本教材都会把相关的内容进行分类讲解,例如中断处理,文

Android Service的启动过程分析

Android Service的启动过程分析 刚开始学习Service的时候以为它是一个线程的封装,也可以执行耗时操作.其实不然,Service是运行在主线程的.直接执行耗时操作是会阻塞主线程的.长时间就直接ANR了. 我们知道Service可以执行一些后台任务,是后台任务不是耗时的任务,后台和耗时是有区别的喔. 这样就很容易想到音乐播放器,天气预报这些应用是要用到Service的.当然如果要在Service中执行耗时操作的话,开个线程就可以了. 关于Service的运行状态有两种,启动状态和绑