GRUB Multiboot规范

GRUB Multiboot规范

​ 为记录设计引导程序时需要注意的相关规范,本文不对Multiboot作系统介绍,仅作为记录参考用。

$1 术语定义

  • 必须
    术语“必须”表示引导程序或OS映像需要服从某一规则,否则的话,引导程序或者OS映像就不能称为符合Multiboot规范的。
  • 应该
    术语“应该”表示引导程序或OS映像最好服从某一规则,但如果没有服从也是可以的。
  • 可以
    术语“可以”表示引导程序或OS映像服从某一规则是允许的。
  • 引导程序
    引导程序是负责载入最终的操作系统映像的一个或一组程序。引导程序本身可以由几个阶段组成,但是这属于实现细节而同本规范无关。只有引导程序最后的阶段——最终将控制权转交给操作系统的阶段——必须遵守本文中规定的规则,否则引导程序就不能称为符合Multiboot规范;在这之前的阶段可以怎么方便怎么设计。
  • OS映像
    OS映像是引导程序载入到内存的初始二进制映像,随后引导程序会将控制权转移给它,这样就启动了操作系统。典型的OS映像是包含了操作系统内核的可执行文件。
  • 引导模块
    引导模块是由引导程序同OS映像一同载入的其他起辅助作用的文件。引导程序并不理解这些文件,只会将它们的位置告知操作系统。
  • 符合Multiboot规范
    服从所有被标记为“必须”的引导程序或者OS映像被称为符合Multiboot规范。对于规范中那些被标记为“应该”或者“可以”的规则,符合Multiboot规范的引导程序或OS映像可以不必遵守。
  • u8
    无符号8位数据。
  • u16
    无符号16位数据。因为目标架构是高位优先(little-endian)的,所以u16按照高位优先编码。
  • u32
    无符号32位数据。因为目标架构是高位优先(little-endian)的,所以u32按照高位优先编码。
  • u64
    无符号64位数据。因为目标架构是高位优先(little-endian)的,所以u64按照高位优先编码。

$2 精确定义

引导程序/OS映像接口主要包括三个方面:

  1. 引导程序看到的 OS 映像的格式。
  2. 当引导程序启动操作系统时机器的状态。
  3. 引导程序传递给操作系统的信息的格式。
  • OS映像格式
    一个OS映像可以是一个普通的某种操作系统使用的标准格式的32位可执行文件,不同之处是它可能被连接到一个非默认的载入地址以避开PC的I/O区域或者其它的保留区域,当然它也不能使用共享库或其它这样可爱的东西。

    除了OS映像所使用的格式需要的头之外,OS映像还必须额外包括一个Multiboot头:

    • Multiboot头必须完整的包含在OS映像的前 8192 字节内;
    • 必须是longword(32位)对齐的;
    • 通常来说,它的位置越靠前越好,并且可以嵌入在text段的起始处,位于真正的可执行文件头之前。
  • Multiboot的头分布

  • Multiboot头的 magic 域

    • magic
      magic域是标志头的魔数,它必须等于十六进制值0x1BADB002。

    • flags
      flags域指出OS映像需要引导程序提供或支持的特性。0-15位指出需求:如果引导程序发现某些值被设置但出于某种原因不理解或不能不能满足相应的需求,它必须告知用户并宣告引导失败。16-31位指出可选的特性:如果引导程序不能支持某些位,它可以简单的忽略它们并正常引导。自然,所有flags字中尚未定义的位必须被置为0。这样,flags域既可以用于版本控制也可以用于简单的特性选择。
      如果设置了flags字中的0位,所有的引导模块将按页(4KB)边界对齐。有些操作系统能够在启动时将包含引导模块的页直接映射到一个分页的地址空间,因此需要引导模块是页对齐的。

      如果设置了flags字中的1位,则必须通过Multiboot信息结构(参见引导信息格式)的mem_*域包括可用内存的信息。如果引导程序能够传递内存分布(mmap_*域)并且它确实存在,则也包括它。

      如果设置了flags字中的2位,有关视频模式表(参见引导信息格式)的信息必须对内核有效。

      如果设置了flags字中的16位,则Multiboot头中偏移量8-24的域有效,引导程序应该使用它们而不是实际可执行头中的域来计算将OS映象载入到那里。如果内核映象为ELF格式则不必提供这样的信息,但是如果映象是a.out格式或者其他什么格式的话就必须提供这些信息。兼容的引导程序必须既能够载入ELF格式的映象也能载入将载入地址信息嵌入Multiboot头中的映象;它们也可以直接支持其他的可执行格式,例如一个a.out的特殊变体,但这不是必须的。

    • checksum
      域checksum是一个32位的无符号值,当与其他的magic域(也就是magic和flags)相加时,结果必须是32位的无符号值0(即magic + flags + checksum = 0)。

  • Multiboot头的 地址 域

    • 所有由flags的第16位开启的地址域都是物理地址。它们的意义如下:
    • header_addr
      包含对应于Multiboot头的开始处的地址——这也是magic值的物理地址。这个域用来同步OS映象偏移量和物理内存之间的映射。
    • load_addr
      包含text段开始处的物理地址。从OS映象文件中的多大偏移开始载入由头位置的偏移量定义,相减(header_addr - load_addr)。load_addr必须小于等于header_addr。
    • load_end_addr
      包含data段结束处的物理地址。(load_end_addr - load_addr)指出了引导程序要载入多少数据。这暗示了text和data段必须在OS映象中连续;现有的a.out可执行格式满足这个条件。如果这个域为0,引导程序假定text和data段占据整个 OS 映象文件。
    • bss_end_addr
      包含bss段结束处的物理地址。引导程序将这个区域初始化为0,并保留这个区域以免将引导模块和其他的于查系统相关的数据放到这里。如果这个域为0,引导程序假定没有bss段。
    • entry_addr
      操作系统的入口点,引导程序最后将跳转到那里。
  • Multiboot头的 图形 域

    • 所有的图形域都通过flags的第2位开启。它们指出了推荐的图形模式。注意,这只是OS映象推荐的模式。如果该模式存在,引导程序将设定它,如果用户不明确指出另一个模式的话。否则,如果可能的话,引导程序将转入一个相似的模式。
    • mode_type
      如果为0就代表线性图形模式,如果为1代表标准EGA文本模式。所有其他值保留以备将来扩展。注意即使这个域为0,引导程序也可能设置一个文本模式。
    • width
      包含列数。在图形模式下它是象素数,在文本模式下它是字符数。0代表OS映象对此没有要求。
    • height
      包含行数。在图形模式下它是象素数,在文本模式下它是字符数。0代表OS映象对此没有要求。
    • depth
      在图形模式下,包含每个象素的位数,在文本模式下为0。0代表OS映象对此没有要求。

// 未完 | 2019/05/27

发布了30 篇原创文章 · 获赞 7 · 访问量 4435

猜你喜欢

转载自blog.csdn.net/weixin_40005329/article/details/90611078