首页 > 代码库 > OpenBSD内核之引导MBR

OpenBSD内核之引导MBR

  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.S

  代码是AT&T格式的汇编,但开头的注释已经几乎将其功能介绍完了:

 

/* * 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,然后jmpPBR继续执行,PBR然后加载/boot4000:0000mbr.S是实模式程序,当然涉及到x86实模式的寻址方式,整个过程就是这样了。

 

  MBR虽然有510字节,但实际用户代码的只有400+字节,因为MBR里还包含一个分区表,分区在MBR末尾定义:

 

/* 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字节)加载到0x7C00MBR在开始执行时已经将自己从定位到0x7A00处了),然后jmp0x7C00执行PBR

  加载PBR也就是读磁盘,读磁盘可以使用传统的CHS模式或者LBA模式,通过int 13检测硬件是否支持LBA,否则回退到CHS模式操作,或者可以在启动时按住shift键强制使用CHS模式。

  另外还有一点,就是BIOS会在执行MBR前将引导的设备号放到DL寄存器中,第一块硬盘为0x80

 

  OKmbr.S的内容基本就这些了,代码还是相当清晰的,这就当个简单的笔记吧,熟悉的同学直接跳过这篇。

OpenBSD内核之引导MBR