【操作系统】MBR
Legacy引导方式,选择从硬盘引导,一般都是由BIOS载入硬盘主引导扇区看它是否“OK”(也就是判断0xAA55标识)。如果主引导扇区最后两个字节是0xAA55(0x55,0xAA)那么这是个可引导的扇区,BIOS转入入口点。MBR中的指令一般做什么呢?找到活动分区,把活动分区DBR载入到0x7C00处,转入运行。当然此时的MBR已经把自己转移到内存别处,一般是0x600处。
来一张硬盘结构图。
主引导扇区的指令部份只有446字节,剩下的66字节是4个分区表(DPT)和一个可引导标识0xAA55。
分区表的格式:
BYTE bActive; //只能是MBR_ACTIVE、MBR_INACTIVE,否则非法
BYTE bStartHead; //起始磁头
BYTE bStartSector; //起始扇区
BYTE bStartCylinder; //起始磁道
BYTE bFSType; //文件系统格式
BYTE bEndHead; //结束磁头
BYTE bEndSector; //结束扇区
BYTE bEndCylinder; //结束磁道
DWORD dwLBAStart; //分区起始扇区索引
DWORD dwLBASectors; //分区总扇区数
主引导扇区只有4个分区表,因此你只能给硬盘分4个主分区。
(问:为什么有人电脑有很多分区呢?答:他其实是用了逻辑分区,逻辑分区有个虚拟MBR。详情以后再讲)
可以看到MBR有两种表示分区位置和大小的方式,一种是CHS寻址方式(磁道、磁头、扇区的“3D”寻址方式),一种是LBA寻址方式(整个硬盘是一个“扇区数组”,用一个32位(本来LBA是48位)的扇区索引来表示)。
MBR现在有点过时了,目前流行GPT分区。 MBR用的是32位LBA,因此最大寻址只有2TB的硬盘空间。
bActive的值必须是0x00或0x80,否则不合法。
送上自家硬盘反汇编一份。
00007C00 33C0 xor ax,ax
00007C02 8ED0 mov ss,ax
00007C04 BC007C mov sp,0x7c00
00007C07 8EC0 mov es,ax
00007C09 8ED8 mov ds,ax
00007C0B BE007C mov si,0x7c00
00007C0E BF0006 mov di,0x600
00007C11 B90002 mov cx,0x200
00007C14 FC cld
00007C15 F3A4 rep movsb
00007C17 50 push ax
00007C18 681C06 push word 0x61c
00007C1B CB retf
0000061C FB sti
0000061D B90400 mov cx,0x4
00000620 BDBE07 mov bp,0x7be
00000623 807E0000 cmp byte ,0x0
00000627 7C0B jl 0x634
00000629 0F850E01 jnz word 0x73b
0000062D 83C510 add bp,byte +0x10
00000630 E2F1 loop 0x623
00000632 CD18 int 0x18
00000634 885600 mov ,dl
00000637 55 push bp
00000638 C6461105 mov byte ,0x5
0000063C C6461000 mov byte ,0x0
00000640 B441 mov ah,0x41
00000642 BBAA55 mov bx,0x55aa
00000645 CD13 int 0x13
00000647 5D pop bp
00000648 720F jc 0x659
0000064A 81FB55AA cmp bx,0xaa55
0000064E 7509 jnz 0x659
00000650 F7C10100 test cx,0x1
00000654 7403 jz 0x659
00000656 FE4610 inc byte
00000659 6660 pushad
0000065B 807E1000 cmp byte ,0x0
0000065F 7426 jz 0x687
00000661 666800000000 push dword 0x0
00000667 66FF7608 push dword
0000066B 680000 push word 0x0
0000066E 68007C push word 0x7c00
00000671 680100 push word 0x1
00000674 681000 push word 0x10
00000677 B442 mov ah,0x42
00000679 8A5600 mov dl,
0000067C 8BF4 mov si,sp
0000067E CD13 int 0x13
00000680 9F lahf
00000681 83C410 add sp,byte +0x10
00000684 9E sahf
00000685 EB14 jmp short 0x69b
00000687 B80102 mov ax,0x201
0000068A BB007C mov bx,0x7c00
0000068D 8A5600 mov dl,
00000690 8A7601 mov dh,
00000693 8A4E02 mov cl,
00000696 8A6E03 mov ch,
00000699 CD13 int 0x13
0000069B 6661 popad
0000069D 731C jnc 0x6bb
0000069F FE4E11 dec byte
000006A2 750C jnz 0x6b0
000006A4 807E0080 cmp byte ,0x80
000006A8 0F848A00 jz word 0x736
000006AC B280 mov dl,0x80
000006AE EB84 jmp short 0x634
000006B0 55 push bp
000006B1 32E4 xor ah,ah
000006B3 8A5600 mov dl,
000006B6 CD13 int 0x13
000006B8 5D pop bp
000006B9 EB9E jmp short 0x659
000006BB 813EFE7D55AA cmp word ,0xaa55
000006C1 756E jnz 0x731
000006C3 FF7600 push word
000006C6 E88D00 call word 0x756
000006C9 7517 jnz 0x6e2
000006CB FA cli
000006CC B0D1 mov al,0xd1
000006CE E664 out 0x64,al
000006D0 E88300 call word 0x756
000006D3 B0DF mov al,0xdf
000006D5 E660 out 0x60,al
000006D7 E87C00 call word 0x756
000006DA B0FF mov al,0xff
000006DC E664 out 0x64,al
000006DE E87500 call word 0x756
000006E1 FB sti
000006E2 B800BB mov ax,0xbb00
000006E5 CD1A int 0x1a
000006E7 6623C0 and eax,eax
000006EA 753B jnz 0x727
000006EC 6681FB54435041 cmp ebx,0x41504354
000006F3 7532 jnz 0x727
000006F5 81F90201 cmp cx,0x102
000006F9 722C jc 0x727
000006FB 666807BB0000 push dword 0xbb07
00000701 666800020000 push dword 0x200
00000707 666808000000 push dword 0x8
0000070D 6653 push ebx
0000070F 6653 push ebx
00000711 6655 push ebp
00000713 666800000000 push dword 0x0
00000719 6668007C0000 push dword 0x7c00
0000071F 6661 popad
00000721 680000 push word 0x0
00000724 07 pop es
00000725 CD1A int 0x1a
00000727 5A pop dx
00000728 32F6 xor dh,dh
0000072A EA007C0000 jmp word 0x0:0x7c00
0000072F CD18 int 0x18
00000731 A0B707 mov al,
00000734 EB08 jmp short 0x73e
00000736 A0B607 mov al,
00000739 EB03 jmp short 0x73e
0000073B A0B507 mov al,
0000073E 32E4 xor ah,ah
00000740 050007 add ax,0x700
00000743 8BF0 mov si,ax
00000745 AC lodsb
00000746 3C00 cmp al,0x0
00000748 7409 jz 0x753
0000074A BB0700 mov bx,0x7
0000074D B40E mov ah,0xe
0000074F CD10 int 0x10
00000751 EBF2 jmp short 0x745
00000753 F4 hlt
00000754 EBFD jmp short 0x753
00000756 2BC9 sub cx,cx
00000758 E464 in al,0x64
0000075A EB00 jmp short 0x75c
0000075C 2402 and al,0x2
0000075E E0F8 loopne 0x758
00000760 2402 and al,0x2
00000762 C3 ret
00000763 49 dec cx
00000764 6E outsb
00000765 7661 jna 0x7c8
00000767 6C insb
00000768 6964207061 imul sp,,word 0x6170
0000076D 7274 jc 0x7e3
0000076F 6974696F6E imul si,,word 0x6e6f
00000774 207461 and ,dh
00000777 626C65 bound bp,
0000077A 004572 add ,al
0000077D 726F jc 0x7ee
0000077F 7220 jc 0x7a1
00000781 6C insb
00000782 6F outsw
00000783 61 popaw
00000784 64696E67206F imul bp,,word 0x6f20
0000078A 7065 jo 0x7f1
0000078C 7261 jc 0x7ef
0000078E 7469 jz 0x7f9
00000790 6E outsb
00000791 67207379 and ,dh
00000795 7374 jnc 0x80b
00000797 656D gs insw
00000799 004D69 add ,cl
0000079C 7373 jnc 0x811
0000079E 696E67206F imul bp,,word 0x6f20
000007A3 7065 jo 0x80a
000007A5 7261 jc 0x808
000007A7 7469 jz 0x812
000007A9 6E outsb
000007AA 67207379 and ,dh
000007AE 7374 jnc 0x824
000007B0 656D gs insw
000007B2 0000 add ,al
000007B4 00637B add ,ah
000007B7 9A1F45E0A7 call word 0xa7e0:0x451f
000007BC 670000 add ,al
000007BF 0000 add ,al
000007C1 0000 add ,al
000007C3 0000 add ,al
000007C5 0000 add ,al
000007C7 0000 add ,al
000007C9 0000 add ,al
000007CB 0000 add ,al
000007CD 0000 add ,al
000007CF 0000 add ,al
000007D1 0000 add ,al
000007D3 0000 add ,al
000007D5 0000 add ,al
000007D7 0000 add ,al
000007D9 0000 add ,al
000007DB 0000 add ,al
000007DD 0000 add ,al
000007DF 0000 add ,al
000007E1 0000 add ,al
000007E3 0000 add ,al
000007E5 0000 add ,al
000007E7 0000 add ,al
000007E9 0000 add ,al
000007EB 0000 add ,al
000007ED 0000 add ,al
000007EF 0000 add ,al
000007F1 0000 add ,al
000007F3 0000 add ,al
000007F5 0000 add ,al
000007F7 0000 add ,al
000007F9 0000 add ,al
000007FB 0000 add ,al
000007FD 0055AA add ,dl
可以看到这个MBR先把自己移动到0x600处,用BP指向当前DPT,循环查找活动分区,没找到活动分区则INT 0x18,否则继续,检测INT 0x13扩展磁盘功能是否可用,如果可用就用LBA寻址读取分区DBR,否则用CHS寻址读取DBR。读取DBR到0x7C00,判断签名是否为0xAA55,如果不是继续读取,如果是,转入运行。如果都不能运行,打印文本“分区表无效”、“没有操作系统”、“引导出错”,最后当机。
循环节用得不像一个汇编玩得好的人写的,难道是用TC写的?
这个MBR用BIOS中断0x10功能0xE输出字符到屏幕,详见:
http://www.ctyme.com/intr/rb-0106.htm
检查过BIOS的扩展读取功能,使用了BIOS中断0x13功能0x41(BX=0x55AA,注意不是0xAA55),详见:
http://www.ctyme.com/intr/rb-0706.htm
用过BIOS扩展LBA寻址读取功能INT 0x13功能0x42,详见:
http://www.ctyme.com/intr/rb-0708.htm
也用过BIOS普通CHS寻址读取功能INT 0x13功能0x2,详见:
http://www.ctyme.com/intr/rb-0607.htm
附上一份自己写的MBR引导代码。org 0x600
bits 16
Start:
;定位段
xor ax,ax
mov ds,ax
mov es,ax
mov ss,ax;建立栈
mov sp,0x7c00
;移动自身到0x600
cld
mov si,0x7c00
mov di,0x600
mov cx,256
rep movsw;按字拷贝,256个字
jmp 0x600+(NewStart-Start);绝对
;低位内存的指令开始的位置
NewStart:
;寻找可引导分区
FindPart:
mov cx,4;4个分区表项
mov bx,DPT1
test byte,0x80
jnz GetPart
.BadPart:
add bx,16;每分区表项16字节
loop FindPart
NoBootPart:
;没找到可引导分区
mov si,NoPartMsg
mov cx,NoPartMsgLen
call ShowStr
xor ax,ax
int 0x16
int 0x18
GetPart:
;已找到可引导分区,bx指向分区表头
mov ax,
mov ,ax
mov ax,
mov ,ax
mov ah,0x42
mov si,DAP
;dl的值本来就是这个磁盘的序号。一开始就没改变过它。
int 0x42
cmp word,0xAA55
jnz FindPart.BadPart
jmp 0x7c00
;过程:显示字符串
;参数:
;si 字符串指针
;cx 字符串长度
ShowStr:
mov ah,0xe
mov bx,0x0007
.CharOut:
lodsb
or al,al
jz .NoMoreChar
int 0x10
loop .CharOut
.NoMoreChar:
ret
DAP: ;磁盘地址包,用于读取硬盘
.SizeOf:
dw .End-DAP ;包大小
.NbPacket:
dw 1 ;要传输的块数量
.Buf: ;缓冲区
dw 0x7c00 ;偏移
dw 0 ;段
.LBA:
dq 0
.End:
NoPartMsg db "Invalid system disk."
NoPartMsgLen equ $-NoPartMsg
;到分区表前的部分填充0
times (510-64)-($-$$) db 0
;分区表,共64个字节
DPT1: times 16 db 0
DPT2: times 16 db 0
DPT3: times 16 db 0
DPT4: times 16 db 0
Sign dw 0xAA55;签名 这个要Mark 计算机相关的计数原理还是要学习一个的。Mark了
页:
[1]