• OpenBSD内核之引导PBR


      OpenBSD引导的第二部PBR,也是活动分区的一个扇区的代码,由第一步的MBR加载到0x7C00处,manpage里详细的讲解了过程和大致实现 biosboot(8) http://man.openbsd.org/OpenBSD-6.0/man8/i386/biosboot.8),代码在sys/arch/i386/stand/biosboot/目录下,主要就是其中的biosboot.S;和mbr.S一样,在代码的开头清晰的介绍了该代码要做的事情:

     

    /*
     * Memory layout:
     *
     * 0x00000 -> 0x07BFF    our stack        (to  31k)
     * 0x07A00 -> 0x07BFF    typical MBR loc        (at  30k5)
     * 0x07C00 -> 0x07DFF    our code        (at  31k)
     * 0x07E00 -> ...        /boot inode block    (at  31k5)
     * 0x07E00 -> ...        (indirect block if nec)
     * 0x40000 -> ...    /boot            (at 256k)
     *
     * The BIOS loads the MBR at physical address 0x07C00.  It then relocates
     * itself to (typically) 0x07A00.
     *
     * The MBR then loads us at physical address 0x07C00.
     *
     * We use a long jmp to normalise our address to seg:offset 07C0:0000.
     * (In real mode on x86, segment registers contain a base address in
     * paragraphs (16 bytes).  0000:00010 is the same as 0001:0000.)
     *
     * We set the stack to start at 0000:7BFC (grows down on i386)
     *
     * We then read the inode for /boot into memory just above us at
     * 07E0:0000, and run through the direct block table (and the first
     * indirect block table, if necessary).
     *
     * We load /boot at seg:offset 4000:0000.
     *
     * Previous versions limited the size of /boot to 64k (loaded in a single
     * segment).  This version does not have this limitation.
     */

     

      注释内容包含了mbr.S开头的内容,还是讲解了大致引导过程:BIOS MBR0x7C00处,然后MBR将自身重定位到0x7A00MBR加载PBR也就是biosboot.S0x7C00,然后jmp0x7C00处的biosboot.S执行。

      biosboot.S的特殊之处在于不像mbr.S里那样直接从磁盘扇区的第1扇区这种“物理”定位信息加载后续代码,也就是说biosboot需要能直接操作文件系统了,因为它后续加载的是/boot,要直接从根分区加载boot!对比其他的bootloader,比如GRUBGRUB能直接读各种各样的文件系统,其代码复杂度可想而知,OpenBSDbiosboot实际上并不能读文件系统,因为它只有512字节啊,这点空间不可能能放下文件系统驱动!biosboot采取的方法是在最终的二进制内容里直接保存/boot所在的磁盘扇区位置信息,当然不可能直接写死在biosboot.S代码里,采取的办法是打二进制patch,也就是直接修改编译后的二进制文件里的,通过用户态程序/usr/sbin/installboot/boot的物理位置信息写到编译后的biosboot中,然后将修改后的biosboot写到分区第一个扇区;这里涉及到ELF文件相关知识,在biosboot.S中有几个导出的符号,installboot/boot物理位置信息写到这几个符号所指的位置处,代码的注释里清晰的讲解了这几个导出符号:

     

    /*
     * The data passed by installboot is:
     *
     * inodeblk    uint32    the filesystem block that holds /boot's inode
     * inodedbl    uint32    the memory offset to the beginning of the
     *            direct block list (di_db[]).  (This is the
     *            offset within the block + $INODEOFF, which is
     *            where we load the block to.)
     * fs_bsize_p    uint16    the filesystem block size _in paragraphs_
     *            (i.e. fs_bsize / 16)
     * fs_bsize_s    uint16    the number of disk sectors in a filesystem
     *            block (i.e. fs_bsize / d_secsize). Directly written
     *            into the LBA command block, at lba_count.
     *            XXX LIMITED TO 127 BY PHOENIX EDD SPEC.
     * fsbtodb    uint8    shift count to convert filesystem blocks to
     *            disk blocks (sectors).  Note that this is NOT
     *            log2 fs_bsize, since fragmentation allows
     *            the trailing part of a file to use part of a
     *            filesystem block.  In other words, filesystem
     *            block numbers can point into the middle of
     *            filesystem blocks.
     * p_offset    uint32    the starting disk block (sector) of the
     *            filesystem
     * nblocks    uint16    the number of filesystem blocks to read.
     *            While this can be calculated as
     *            howmany(di_size, fs_bsize) it takes us too
     *            many code bytes to do it.
     *
     * All of these are patched directly into the code where they are used
     * (once only, each), to save space.
     *
     * One more symbol is exported, in anticipation of a "-c" flag in
     * installboot to force CHS reads:
     *
     * force_chs    uint8    set to the value 1 to force biosboot to use CHS
     *            reads (this will of course cause the boot sequence
     *            to fail if /boot is above 8 GB).
     */

     

      这几个值使biosboot能直接定位到磁盘上的bootbiosboot中和mbr一样也有CHSLBA相关的代码,按住shift键强制使用CHS模式。加载boot到0x40000,也就是256KB处,然后jmp到其中继续执行/boot

      OK,终于看完这些实模式的鬼东西了……后面空了再继续写boot后面的东西吧。

     

     

  • 相关阅读:
    上下,流动
    面对离去了的亲人,
    计算 star 之间 距离,
    咀嚼,
    python中的内嵌函数
    python中全局变量和局部变量
    python中函数的闭包
    python中函数的收集参数
    python中如何将局部变量扩展为全局变量(global关键字)
    python中的内嵌函数
  • 原文地址:https://www.cnblogs.com/logicbaby/p/6079526.html
Copyright © 2020-2023  润新知