|
楼主 |
发表于 2004-9-27 09:02:48| 字数 2,606| - 湖南省湘潭市 电信
|
显示全部楼层
MBR
下面我就再对MBR做一些辅助性的说明,请各位指正。
硬盘主引导记录(MBR)位于硬盘的0面0道1扇区(也就是整个硬盘的第一个扇区),分为3部分:主引导程序(446字节),分区表(64字节)和有效标志(2字节,就是那个55AA)。
比如用 fdisk 程序对硬盘进行分区,把当前硬盘分为1主分区(C盘)和1扩展分区(D、E、F盘等等),并把主分区(C盘)作为可引导的活动分区。那么fdisk就会把这两个分区信息(1个主分区、1个扩展分区)写入到 MBR的64字节的分区表信息区。然后安装操作系统时,操作系统就会在安装它的分区上安装操作系统引导程序(如当你分区完毕并格式化各分区后在C盘安装windows,那么Windows就会在活动分区建立一个主引导程序用于启动windows自己)。
现在我们再来看看机器启动系统的过程以及硬盘的主引导记录到底做了些什么。
启动机器时,机器首先加电自检,BIOS程序完成各项初始化工作,然后检测硬盘,并把硬盘的MBR装入到0000:7c00的内存地址,然后就把控制权交给MBR的主引导程序,MBR的主引导程序获得控制权后按顺序完成一下工作:
1、把自己从内存0000:7c00H移到0000:600H
2、检查分区表项有效性
3、寻找唯一的引导分区项(一个硬盘最多只能有一个可引导分区,也就是平常我们在用fdisk分区时所设置的活动分区)并,将之对应的引导记录读入0000:7C00。
4、将控制权转交给可引导分区的引导程序(也就是程序跳转到0000:7c00).
接下来的事情就是由可引导分区的引导程序完成对操作系统的引导,已经不关MBR的事了。
从以上我们可以看到MBR的重要性以及它的作用,MBR的引导程序获得控制权的时间紧随与BIOS程序之后,位于所有操作系统引导程序执行之前并且不归属于任何分区。
机器用446字节的长度在硬盘的首扇区存放MBR的主引导程序,但事实上硬盘主引导程序的长度(包括程序指令和错误提示信息)根本没到446字节(是以FDISK产生的主引导程序为例),所以我们就有机会(病毒也有机会,另外还有多系统引导工具都是通过修改硬盘的MBR来实现的,如:Linux的lilo,GRUB等。)在这些空闲的空间里面加入代码,以达到XXXXXX目的(如将打开L2 cache的代码加进去等)。
明白了这些之后其实我们自己都可以很轻松的写出硬盘MBR上的那个主引导程序,只要完成以上几大工作既可。下面有一个MBR主引导程序(不是我写的,),大家可以看一下(与Fdisk产生的那个基本相同):
;MBR.ASM
; MASM MBR
; LINK MBR
; EXE2BIN MBR
.MODEL tiny
.CODE
;设置寄存器及堆栈值
org 0
Head:
Start:
cli
xor ax,ax
mov ss,ax
mov sp,7C00H ;ss:sp=0:7C00H
mov si,sp
push ax
pop es
push ax
pop ds ;es=ds=0
sti
;将程序代码由0:7C00H移动到0:0600H处
cld
mov di,600H
mov cx,100H ;100H Words=512 Bytes,即一个扇区大小
repne movsw
db 0EAH ;这个是FAR JUMP的机器码
dw offset Continue+600H, 0000H ;这个是跳转目的地址,即0:061DH
;搜索可引导分区
Continue:
mov si,600H+1BEH ;si指向分区表
mov bl,4 ;四个分区
FindBoot:
cmp byte ptr[si],80H
je SaveRec ;读扇区位置
cmp byte ptr[si],0
jne Invaild ;无效分区
add si,10H
dec bl
jnz FindBoot
int 18H ;进入ROM BASIC
;读取引导分区的扇区,柱面号
SaveRec:
mov dx,[si]
mov cx,[si+2]
mov bp,si
;检查其余分区表
FindNext:
add si,10H
dec bl
jz SetRead
cmp byte ptr[si],0 ;是否存在非法分区
je FindNext
Invaild:
mov si,offset ErrMsg1+600H
;字符串输出子程序
PrintStr:
lodsb
cmp al,0
je DeadLock
push si
mov bx,7
mov ah,0EH ;输出字符
int 10H
pop si
jmp short PrintStr ;下一字符
DeadLock:
jmp short DeadLock ;无穷循环,也可以写成jmp $
;读引导扇区
SetRead:
mov di,5 ;读取次数
ReadBoot:
mov bx,7C00H
mov ax,201H
push di
int 13H ;cx,dx已经在SaveRec处得到
pop di
jnc GoBoot ;成功则启动
xor ax,ax
int 13H ;reset驱动器,然后再读取
dec di
jnz ReadBoot
mov si,offset ErrMsg2+600H
jmp short PrintStr 失败输出信息,并进入无穷循环
;检查读入的引导扇区
GoBoot:
mov si,offsetErrMsg3+600H
mov di,7C00H+1FEH
cmp word ptr[di],0AA55H
jne PrintStr ;非AA55标志则输出错误信息
mov si,bp ;si指向可启动分区
db 0EAH,0,7CH,0,0 ;跳转至0:7C00H
ErrMsg1 db 'Invaild partition table',0
ErrMsg2 db 'Error loading operating system',0
ErrMsg3 db 'Missing operating system',0
Tail:
FillNum equ 1BEH-(Tail-Head) ;计算填0数目
db FillNum dup(0)
;四个分区表项数据,跟分区情况有关,详细含义另解
PartTable db 80H,1,1,0,4,4,0D1H,2,11H,0,0,0,0FEH,0FFH,0,0
db 0,0,0C1H,3,5,4,0D1H,0FEH,0FFH,0FFH,0,0,0ACH,53H,0,0
db 20H dup(0)
ID dw 0AA55H
end start
注意前面的“ .MODEL tiny”,这样的话此程序编译后可以用exe2bin之类的工具可以轻易把它转换成.com文件的。
[ Last edited by noblame on 2004-9-27 at 09:18 ] |
|