裸机与引导程序
裸机是什么?
裸机其实就是不包含操作系统的计算机,若是定义的更严格一点,那可以说是不包含任何应用程序的计算机。但对PC来讲,PC出厂时都是被厂商烧入了BIOS的,所以裸机的叫法一般就指只包含BIOS的计算机了。
x86平台的引导
x86平台的引导对于很多有心人应该在网络上很多地方了解过了,但要说操作系统却总是避免不了说的这些,所以这儿就以尽量简单易懂的方式向大家讲述这是怎么一回事。
前面说道PC出厂时都被厂商烧入了BIOS程序,而BIOS的功能至少有以下几点:
硬件自举与初始化
中断服务
基本引导
计算机上电或复位后,在执行第一条指令前,cs寄存器被置为0xf000, ip指令指针寄存器置为0xfff0,对于i8086的机器,寻址方式遵循实模式下的寻址,第一条指令的地址就是0xffff0,即1M地址的末尾16字节开始处,但从i80386以后,第一条指令的寻址方式就是通过CS的隐藏寄存器寻址,如下图是在执行第一条指令前CS寄存器及其隐藏寄存器的状态。
其中隐藏寄存器dh,dl中保存的其实就是段描述符,在执行第一条指令前PC还没有到实模式,当然也不是保护模式,不过寻址却采用保护模式的那种机制,从图中看出段基址base=0xffff0000,再加上偏移量,ip=0xfff0,所以pc上电或复位后执行的第一条指令就是地址0xfffffff0处的指令(不了解保护模式下的寻址方式的可百度)。
接着便是执行BIOS代码,因为intel规定在即非保护模式,也非实模式的状态下重新给CS寄存器载入值后,CPU将进入实模式,所以,执行完第一条指令后(jmpf 0xf000:e05b),CS的值会重新载入(长跳转的特征),CPU将进入实模式。至此,CPU将在实模式下开始执行BIOS例程,当硬件,中断等初始化完毕后,BIOS将按指定的启动顺序读取硬盘或软盘等第一个扇区的512字节到0x7c00地址处,并跳转到该地址处开始执行。
引导程序例子
从以上介绍的80x86平台上电或复位后的启动特征,我们可以知道在磁盘或软盘等存储设备第一个扇区(MBR)中存储的代码即为在BIOS例程执行后的首先开始执行的代码。所以我们可以将我们想要执行的代码写入磁盘的MBR中,这样就能够在裸机上执行我们设计的程序了。如下是一个例子及在vbox虚拟机上的演示。
/* header.S */
BOOTSEG = 0x07c0
SYSSEG = 0x10000
VIDEO_TEXT_SEG = 0xb800
#define MSG(x, color, offset) movw $x, %si; \
movw $color, %dx; \
movw $offset, %di; \
call message
#define OFFSET(x) (x*2)
.section ".bstext", "ax"
.global bs_sect_start
bs_sect_start:
ljmp $BOOTSEG, $_start
_start:
movw %cs, %ax
movw %ax, %ds
movw %ax, %ss
xorw %sp, %sp
//set %es segment
movw $VIDEO_TEXT_SEG, %ax
movw %ax, %es
sti
cld
MSG(notify, 0x7, OFFSET(0))
1:
hlt
jmp 1b
notify:
.asciz "/* Under glibc some of the constants involved have gotten"
/*
src: ds:si
dst: es:di
*/
1:
stosb
movb %dl, %al