MBR的介紹網上不少,沒錯,就那個最後以0x55AA結尾的512字節的引導塊,OpenBSD提供了引導MBR實現;OpenBSD在x86上的引導過程爲MBR --> PBR --> boot --> kernel,其總體過程在boot_i386(8) (http://man.openbsd.org/OpenBSD-6.0/man8/i386/boot_i386.8)中有詳細講解,讓咱們直接上代碼吧,MBR的代碼在sys/arch/i386/stand/mbr/目錄下,主要就是其中的mbr.Sspa
代碼是AT&T格式的彙編,但開頭的註釋已經幾乎將其功能介紹完了:code
/* * Memory layout: * * 0x07C00 -> 0x07DFF BIOS loads us here (at 31k) * 0x07E00 -> 0x17BFC our stack (to 95k) * * 0x07A00 -> 0x07BFF we relocate to here (at 30k5) * * 0x07C00 -> 0x07DFF we load PBR here (at 31k) * * The BIOS loads us at physical address 0x07C00. We use a long jmp to * normalise our address to seg:offset 07C0:0000. We then relocate to * 0x07A00, seg:offset 07A0:0000. * * We use a long jmp to normalise our address to seg:offset 07A0:0000 * We set the stack to start at 07C0:FFFC (grows down on i386) * The partition boot record (PBR) loads /boot at seg:offset 4000:0000 */
大概幫翻一下就是BIOS會將mbr.S加載到0x7C00處,而後mbr.S將本身複製並重定性到0x7A00處,而後將PBR加載到本身原來的位置0x7C00處,整個過程使用的棧在0x07E00 ~ 0x17BFC,而後jmp到PBR繼續執行,PBR而後加載/boot到4000:0000,mbr.S是實模式程序,固然涉及到x86實模式的尋址方式,整個過程就是這樣了。orm
MBR雖然有510字節,但實際用戶代碼的只有400+字節,由於MBR裏還包含一個分區表,分區在MBR末尾定義:blog
/* partition table */ /* flag, head, sec, cyl, type, ehead, esect, ecyl, start, len */ . = DOSPARTOFF /* starting address of partition table */ pt: .byte 0x0,0,0,0,0,0,0,0 .long 0,0 .byte 0x0,0,0,0,0,0,0,0 .long 0,0 .byte 0x0,0,0,0,0,0,0,0 .long 0,0 .byte DOSACTIVE,0,1,0,DOSPTYP_OPENBSD,255,255,255 .long 0,0x7FFFFFFF /* the last 2 bytes in the sector 0 contain the signature */ . = 0x1fe
基本上就是每一個分區的開始結束扇區、各類flag等信息,其中一個flag是表示是否爲「活動分區」的,mbr.S執行是會檢查這個標誌,並將活動分區的第一個扇區(512字節)加載到0x7C00(MBR在開始執行時已經將本身從定位到0x7A00處了),而後jmp到0x7C00執行PBR。get
加載PBR也就是讀磁盤,讀磁盤能夠使用傳統的CHS模式或者LBA模式,經過int 13檢測硬件是否支持LBA,不然回退到CHS模式操做,或者能夠在啓動時按住shift鍵強制使用CHS模式。it
另外還有一點,就是BIOS會在執行MBR前將引導的設備號放到DL寄存器中,第一塊硬盤爲0x80。io
OK,mbr.S的內容基本就這些了,代碼仍是至關清晰的,這就當個簡單的筆記吧,熟悉的同窗直接跳過這篇。table