分类: LINUX
2013-05-21 14:25:04
BIOS启动的过程主要包括POST过程和自举过程,其流程和执行指令地址的变化如下:
POST过程在AWARD BIOS的源码中在BOOTROM.ASM文件中BootBlock_POST函数过程中实现,主要步骤如下:
1)初始化各种主板芯片组
2)初始化键盘控制器8042
3)初始化中断向量 ,中断服务例程.
4)初始化 VGA BIOS 控制器
5)显示BIOS的版本和公司名称
6)扫描软驱和各种介质容量
7)读取CMOS的启动顺序配置,并检测启动装置是否正常
8)调用INT 19h启动自举程序
以上每个过程都有大量的代码,在这不一一做仔细分析,请参考源代码。下面对第三步源码做一些分析。
中断向量表存储在内存的第一个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中指定服务例程。
自举过程即为执行中断INT19的中断服务例程INT19_VECT的过程,该过程在AWARD的Bootrom.asm文件中实现,其主要功能为读取操作系统启动块,将其读入到内存0000:7C00h,并跳转至此处执行。下面分析一下操作系统启动块MBR是如何从磁盘中读取到内存0000:7C00h处的。
new_dsk:
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
int 13h ; reset disk
int 13h ; read disk
jc short Boot_fail
jc short Boot_fail ; invalid boot sector.
jmp far ptr Boot ; go to boot code
lea ax,Bad_Disk_Msg ; boot failed
mov cx,Bad_Disk_Msg_Len
call Disk_Fail_Routine
jmp short new_dsk
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
endless:
xor ah,ah ;wait ENTER key
int 16h
cmp ah,1ch
jne short endless
ret
流程图如下:
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之家: