Multiboot规范(1)

1.      Multiboot规范的简介

本章描述Multiboot规范的某些粗略的信息。注意这不是规范本身的一部分。

1.1. Multiboot规范的背景

每个操作系统倾向于装备自己的启动载入器。在一个机器上安装一个新的操作系统,通常涉及安装一套新的启动机制,具有完全不同的安装时(install-time)及启动时(boot-time)用户接口。通过典型的链式机制,使得多个操作系统可靠地共存在一台机器上,这可以是个噩梦。对于一个特定的操作系统,只有很少或没有启动载入器的选择——如果伴随操作系统的启动载入器不是你想要的,或在你的机器上不能工作,你就拧巴了。

虽然我们不可能在现存的专有(proprietary)操作系统上解决这个问题,对于自由操作系统社区的少数人来说,碰个头,然后为流行的自由操作系统解决这个问题,应该不会太困难。这正是这个规范的目的。基本上,它描述了一个启动载入器与一个操作系统之间的接口,这样,任何遵循的启动载入器,应该能够载入任何遵循的操作系统。这个规范不规定启动载入器应该如何工作——仅规定它们必须如何与要载入的操作系统接洽。

1.2. 目标架构

这个规范主要瞄准PC,因为它们最普遍,并且具有最多种多样的操作系统及启动载入器。不过,某些其它架构可能需要一个启动规范,但还没有现成的,这个规范的一个修改,剥除特定于x86的细节,也可以适用于它们。

1.3. 目标操作系统

这个规范针对自由32位操作系统,这些系统可以相当容易地被修改来支持这个规范,不需要许多官僚的繁文缛节。这个规范主要为之设计的自由操作系统是,Linux,FreeBSD及NetBSD的内核,Mach,及VSTa。期望其它将要出现的自由操作系统,将从一开始就采用它,并因而能立即利用现有的启动载入器。如果专有操作系统提供商最终也采纳这个规范,这会非常好,不过可能只是一个白日梦。

1.4. 启动源

写出兼容的,可从多种源上包括软盘、硬盘,以及访问网络载入OS映像的启动载入器是有可能的。

基于硬盘的启动载入器可能使用各种技术来找出相关的OS映像,并在硬盘上启动模块数据,比如通过特殊文件系统的解释(如,BSD/Mach的启动载入器),使用预先计算的块列表(如,LILO),从一个特殊的启动分区载入(如,OS/2),或甚至从另一个操作系统里载入(如,VSTa启动代码,它从DOS载入)。类似的,基于网络的启动载入器可以使用各种网络硬件及协议。

期望构建能支持多种载入技术的启动载入器,增加它们的可移植性,强壮性,及用户友好性。

1.5. 在启动时刻配置一个操作系统

出于这个或那个原因,在启动时刻,用户能够动态地向操作系统提供一些配置,通常是必须的。而这个规范不应该规定启动载入器如何得到这个配置消息,标准方式,使启动载入器把这样的消息传给操作系统。

1.6. 如何使得OS的开发更容易

OS映像应该能够容易地生成。理想地,一个OS映像应该只是一个普通的,该操作系统通常使用的文件格式的32位可执行文件。应该能像普通执行映像那样nm或反汇编OS映像。构造一个特殊的文件格式的OS映像,不应该要求特殊的工具。如果这意味着把某些工作从操作系统挪到了启动载入器,这可能是合适的,因为所有被启动载入器使用的内存,在创建了启动进程后,通常将会再次可用,相反在OS映像中每个比特通常都会永久驻留在内存里。操作系统不需要操心一开始进入32位模式,因为一般而言,为了把操作系统载入1MB以上的边界,模式切换代码需要在启动载入器中,强制操作系统这样做,会使得OS映像的构建要困难得多。

很不幸,即便在自由的,类Unix,基于PC的操作系统里,有种类繁多的可执行文件格式——通常每个操作系统有一个不同的格式。绝大多数相关的自由操作系统使用a.out格式的某个变体,但其中一些正在移向elf。为了载入OS映像,启动载入器不需要解释所有现存的不同类型的可执行文件格式的能力,是非常期望的——否则,启动载入器实际上又成了操作系统的特例。

这个规范采纳了这个问题的一个折衷的解决方案。Multiboot兼容的OS映像总是包含一个奇妙的Multiboot头(参考3.1节【OS映像格式】,3页),它允许启动载入器载入该映像,而不需要理解繁多的a.out变体,或其它可执行格式。这个魔法头不需要在可执行文件的最开头,因此内核映像,除了成为Multiboot兼容外,仍然可以符合本地的a.out变体的格式。

1.7. 启动模块

许多现代操作系统内核,比如Mach及VSTA的微内核,本身不包含足够的机构来使得系统完全可运行:它们要求在启动时刻,存在额外的软件模块来访问设备,安装文件系统等。而这些额外的模块可以嵌入到伴随内核本身的主OS映像中,而当所形成的映像接受了控制权时,操作系统把它分离开,这通常更灵活,能更好地利用空间,如果启动载入器可以首先独立地把这些额外的模块载入,对操作系统及用户也更方便。

因此,这个规范应该为启动载入器提供一个标准的方法,向操作系统显示载入什么模块,及何处可以找到它们。启动载入器不需要支持多个载入模块,但它们被强烈鼓励这样做,因为不这样,某些操作系统将无法启动。

2.      规范中使用的术语的定义

Must          当任意启动载入器或OS映像需要遵循一个规则时,我们使用术语must——否则,这个启动载入器或OS映像不是Multiboot兼容的。

Should       当任意启动载入器或OS映像被建议遵循一个规则时,我们使用术语should,但它不需要一定遵循这个规则。

May           当任意启动载入器或OS映像允许遵循一个规则时,我们使用术语may。

boot loader

载入要在机器上运行的,最终的操作系统映像的任何程序或程序组。启动载入器本身可能包括几个阶段,但这是一个与这个规范无关的实现细节。仅启动载入器的最后阶段——最终把控制传递给一个操作系统——必须遵循在这个文档中指出的规则,以实现Multiboot兼容;更早的启动载入器阶段可以最方便的方式设计。

OS image 一个启动载入器载入到内存,并移交控制来启动一个操作系统的,初始二进制映像。OS映像通常是一个包含操作系统内核的可执行文件。

boot module

其它由启动载入器,与OS映像一起,载入内存的辅助文件,但在调用时,只需把它们的位置传递给操作系统。

Multiboot-compliant

一个遵循Multiboot兼容必须的规则的启动载入器或OS映像。当这个规范指定一个规则是should或may时,一个Multiboot兼容的启动载入器/映像不必要遵循这个规则。

u8             无符号8位数据类型。

u16           无符号16位数据类型。因为目标平台是little-endian的,u16以little-endian编码。

U32           无符号32位数据类型。因为目标平台是little-endian的,u32以little-endian编码。

U64           无符号64位数据类型。因为目标平台是little-endian的,u64以little-endian编码。

3.      Multiboot规范的确切定义

一个启动载入器/OS映像接口主要是三个方面:

1          由启动载入器看到的一个OS映像的格式。

2          当启动载入器启动一个操作系统时,机器的状态。

3          由启动载入器传递给操作系统的信息的格式。

3.1.      OS映像的格式

一个OS映像可能是一个,对于这个特定的操作系统而言,标准格式的普通32位可执行文件,除了它可能被链到一个非缺省的载入地址,以避免载入到PC的I/O区域的顶部或其它的保留区域,同样它不应该使用共享库或其它花哨的特性。

一个OS映像,除了该OS映像所使用文件格式的头部外,必须包含一个称为Multiboot头的额外的头部。Multiboot头部必须被完整包含在OS映像的前8192字节内,而必须与长字(32位)对齐。一般而言,它应该尽早出现,并可能嵌入在可执行文件头部后,代码段的开头。

3.1.1.        Multiboot头的布局

Multiboot头的布局必须如下:

偏移 类型              域名                     注意

0            u32              magic                  要求

4            u32              lags                     要求

8            u32              checksum            要求

12          u32              header_addr               如果设置了flags[16]

16          u32              load_addr            如果设置了flags[16]

20          u32              load_end_addr           如果设置了flags[16]

24          u32              bss_end_addr             如果设置了flags[16]

28          u32              entry_addr          如果设置了flags[16]

32          u32              mode_type          如果设置了flags[2]

36          u32              width                   如果设置了flags[2]

40          u32              height                  如果设置了flags[2]

44          u32              depth                   如果设置了flags[2]

域‘magic’,‘flags’及‘checksum’定义在3.1.2节【头部魔数域】,4页,域‘header_addr’,‘load_addr’,‘load_end_addr’,‘bss_end_addr’及‘entry_addr’定义在3.1.3节【头部地址域】,5页,而域‘mode_type’,‘width’,‘height’及 ‘depth’定义在3.1.4节【头部图形化域】,5页。

3.1.2.        Multiboot头部的魔数域

‘magic’ 域‘magic’是标识这个头的魔数,它必须是十六进制数0x1BADB002。

‘flags’   域‘flags’指定OS映像所要求的特性,或对启动载入器的要求。0-15位显示要求;如果启动载入器看到这些比特中有比特被设置,但不能理解这个标志,或出于某些原因不能满足其代表的要求,它必须通知用户,并且这个OS映像载入失败。16-31位显示可选的特性;如果这个区域内有比特被设置,但启动载入器不能理解,它可能只是忽略它们,并如常处理。理所当然,所有‘flags’中尚未定义的比特,必须在OS映像中设置为0。这样,‘flags’域,除了选择简单特性外,还可用于版本控制。

如果‘flags’字中的第0位被设置,那么所有与操作系统一起载入的启动模块必须在页(4KB)边界上对齐。某些操作系统在启动期间,能够直接把包含启动模块的页面映射到一个页对齐的地址,因此要求启动模块页对齐。

如果‘flags’字中的第1位被设置,那么可用内存的信息,至少是Multiboot 消息结构(参考3.3节【启动信息格式】,7页)的 ‘mem_*’ 域,被包括。 如果启动载入器能够传递一个内存映射图(‘mmap_*’域),而且这样的域存在,它也可能被包括。

如果‘flags’字中的第2位被设置,关于视频模式表(参考3.3节【启动信息格式】,7页)的信息必须对内核可用。如果‘flags’字中的第6位被设置,那么在Multiboot头偏移为12-28处的域有效,启动载入器应该使用它们,而不是在实际可执行头中的域,来计算何处载入OS映像。如果内核映像是elf格式,这个信息不需要提供,但如果内核是a.out格式或其它格式,则必须提供。兼容的启动载入器必须能载入elf格式的映像,或在Multiboot头中嵌入载入地址信息的映像;它们可能也直接支持其它可执行格式,比如特定的a.out变体,不过这不要求。

‘checksum’

域‘checksum’是一个32位无符号值,当加上其它魔数域(即,‘magic’及‘flags’)时,其和必须是无符号32位数0。

3.1.3.        Multiboot头的地址域

所有被flag第16位激活的地址域都是物理地址。每个的含义如下:

header_addr

包含对应于Multiboot头开始的地址——magic值被期望载入的物理内存位置。这个域用于同步OS映像偏移与物理内存地址间的映射。

load_addr

包含代码段开头的物理地址。在OS映像中,开始载入的偏移,由Multiboot头部所在偏移减去(header_addr – load_addr)来定义。Load_addr必须小于等于header_addr。

load_end_addr

包含数据段末尾的物理地址。(load_end_addr – load_addr)指出了要载入多少数据。这暗示在OS映像中代码段及数据段必须连续;对于现存的a.out可执行格式,这是成立的。如果这个域是0,启动载入器就假定代码段与数据段占据了整个OS映像文件。

bss_end_addr

包含bss段末尾的物理地址。启动载入器初始化这个区域为0,并保留它所占据的内存,以避免在这个区域放入启动模块及与操作系统相关的其它数据。如果这个域是0,启动载入器就假定bss段没有出现。

entry_addr

为了开始运行操作系统,启动载入器应该跳转到的物理地址。

3.1.4.        Multiboot头的图形化域

所有的图形化域被flag的第2位所激活。它们指定了首选的图形化模式。注意到这仅是OS映像的一个建议的模式。如果该模式存在,当用户没有显式指定一个模式时,启动载入器应该设置它。否则,如果可能,启动载入器应该进入一个类似的模式。

每个域的含义如下:

mode_type

对于线性图形模式,包含‘0’,或‘1’对于EGA-标准文本模式。余下为未来扩展保留。注意到启动载入器可能设置一个文本模式,即便这个域包含‘0’。

width         包含列的个数。在一个图形化模式中,这以像素为单位,在一个文本模式中,以字符为单位。值0表示OS映像没有偏好。

height         包含行的个数。在一个图形化模式中,这以像素为单位,在一个文本模式中,以字符为单位。值0表示OS映像没有偏好。

depth         包含,在一个图形化模式下,每个像素的比特数;而在一个文本模式中,这为0。值0表示OS映像没有偏好。

3.2.      机器状态

当启动载入器调用32位操作系统时,机器必须具有如下状态:

‘EAX’   必须包含魔数‘0x2BADB002’;这个值的出现,向操作系统表示,它由一个Multiboot兼容的启动载入器载入(即,相对于可以载入该操作系统的,其它类型启动载入器)。

‘EBX’   必须包含由启动载入器提供的,Multiboot信息结构的32位物理地址(参考3.3节【启动信息格式】,7页)。

‘CS          必须是一个偏移为‘0’,限长为‘0xFFFFFFFF’的32位读/执行代码段。具体值没有定义。

‘DS’

‘ES’

‘FS’

‘GS’

‘SS’       必须是一个偏移为‘0’,限长为‘0xFFFFFFFF’的32位读/写数据段。具体值没有定义。

‘A20 gate’必须激活。

‘CR0’    第31位(PG)必须被清除。第0位(PE)必须被设置。其它位未定义。

‘EFLAGS’

第17位(VM)必须被清除。第9位(IF)必须被清除。其它位未定义。

所有其它处理器寄存器及标记位都未定义。这包括,特别是:

‘ESP’    一旦需要,OS映像必须构建自己的栈。

‘GDTR’    即便段寄存器如上所示那样设置,‘GDTR’可能是无效的,因此OS映像必须不加载任何段寄存器(就算只是重载相同的值!),直到它设立自己的‘GDT’。

‘IDTR’  OS映像必须保持禁止中断,直到它设立自己的IDT。

然而,在正常的工作次序中,启动载入器不应该改动其它机器状态,即,如BIOS初始化的那样(或DOS,如果那是启动载入器运行的地方)。换而言之,操作系统在载入后,应该能够进行诸如BIOS调用的操作,只要在这样做之前,它不改写BIOS数据结构。同样,启动载入器必须不改动以正常BIOS/DOS值编写的PIC,即便在切换到32位模式过程中,它改变了它们。

3.3.      启动信息格式

进入到操作系统,EBX寄存器包含Multiboot信息数据结构的物理地址,通过它,启动载入器向操作系统传递重要信息。操作系统可以使用或忽略,所选择的该结构体的任意部分;由启动载入器传入的所有信息仅供参考。

Multiboot信息结构体及其相关的子结构体,可能被启动载入器放在内存的任一处(当然,为内核及启动模块所保留的内存是例外)。避免改写这个内存,直到它没有使用价值,这是操作系统的责任。

Multiboot信息结构(就目前的定义)的格式如下:

            +----------------------+

0           | flags                      | (要求)

            +----------------------+

4           | mem_lower           | (如果设置了flags[0],出现)

8           | mem_upper           | (如果设置了flags[0],出现)

            +----------------------+

12         | boot_device          |(如果设置了flags[1],出现)

            +----------------------+

16         | cmdline                 | (如果设置了flags[2],出现)

            +----------------------+

20         | mods_count          |(如果设置了flags[3],出现)

24         | mods_addr            | (如果设置了flags[3],出现)

            +----------------------+

28 - 40 | syms                      | (如果设置了flags[4]或flags[5],出现)

            +----------------------+

44         | mmap_length       |(如果设置了flags[6],出现)

48         | mmap_addr          |(如果设置了flags[6],出现)

            +----------------------+

52         | drives_length        |(如果设置了flags[7],出现)

56         | drives_addr           |(如果设置了flags[7],出现)

            +----------------------+

60         | config_table          |(如果设置了flags[8],出现)

            +----------------------+

64         | boot_loader_name|(如果设置了flags[9],出现)

            +----------------------+

68         | apm_table             |(如果设置了flags[10],出现)

            +----------------------+

72         | vbe_control_info  |(如果设置了flags[11],出现)

76         | vbe_mode_info     |

80         | vbe_mode             |

82         | vbe_interface_seg |

84         | vbe_interface_off |

86         | vbe_interface_len |

      +----------------------+

第一个长字显示在Multiboot信息结构体中其它域存在及有效性。所有尚未定义的比特位必须由启动载入器设为0。操作系统不能理解的任意比特组应该被忽略。这样,域‘flags’还起到版本指示器的作用,允许Multiboot信息结构体在将来进行无损害的扩展。

如果在‘flags’中设置了第0位,那么域‘mem_*’是有效的。‘mem_lower’及‘mem_upper’分别表示低位内存和高位内存的数量,以KB(kilobyte)为单位。低位内存从地址0开始,而高位内存从地址1M开始。低位内存最大的可能值是640KB。为高位内存所返回的值最大是第一个高位内存空洞的地址减去1M。但不保证就是这个值。

如果在‘flags’中设置了第1位,那么域‘boot_device’是有效的,并显示从哪个BIOS硬盘设备上启动载入器载入OS映像。如果OS映像不从一个BIOS硬盘上载入,那么这个域必须不出现(第3位必须被清除)。操作系统可能使用这个域作为确定其自己根设备的一个暗示,但它不要求这样做。域‘boot_device’在4个1字节子域中布置如下:

+-------+-------+-------+-------+

 | part3  | part2 | part1  | drive |

+-------+-------+-------+-------+

第一个字节包含BIOS设备号,它可被BIOS的INT 0x13底层接口所理解:即,0x00对应软盘,0x80对应第一个硬盘。

余下3个字节指定了启动分区。‘part1’指定最上层的分区号,‘part2’指出在最上层分区的一个子分区等。分区号总是从0开始。没有设置的分区字节必须被设置为0xFF。例如,如果硬盘使用单层DOS分区规划,那么‘part1’包含DOS分区号,而‘part2’及 ‘part3’都是0xFF。另一个例子,如果一个硬盘首先划分为DOS分区,然后其中一个DOS分区被进一步使用BSD硬盘标签(disklabel)策略划分为几个BSD分区,那么‘part1’包含这个DOS分区号,‘part2’包含在这个DOS分区中的BSD子分区,而‘part3’是0xFF。

DOS扩展分区由从4开始的分区号表示,而不是作为嵌套子分区,即便扩展分区所立足的硬盘布局本质上是分层的。例如,如果启动载入器从,一个以传统DOS形式分区的硬盘的第二个扩展分区启动,那么‘part1’将是5,而‘part2’及‘part3’都将是0xFF。

如果在‘flags’中设置了第2位,域‘cmdline’是有效的,它包含了要传递给内核的命令行的物理地址。这个命令行是一个普通C样式的,以0结尾的字符串。

如果在‘flags’中设置了第3位,那么域‘mods’向内核显示,什么启动模块会伴随内核映像载入,以及可以在何处找到它们。‘mods_count’包含了载入模块的个数;‘mods_addr’包含了第一个模块结构的物理地址。‘mods_count’可能是0,表示不载入启动模块,就是设置了‘flags’的第一位比特。每个模块结构体的格式如下:

    +-------------------+

0   | mod_start          |

4   | mod_end           |

    +-------------------+

8   | string                 |

    +-------------------+

12 | reserved (0)       |

    +-------------------+

头两个域包含了启动模块本身开头与结尾的地址。域‘string’提供了一个任意的字符串来关联这个特定的启动模块;它是一个0结尾的ASCII字符串,就像内核命令行。域‘string’可能是0,如果没有字符串可关联这个模块。通常,这个字符串可能是一个命令行(比如,如果操作系统把启动模块处理作可执行程序),或一个路径名(比如,如果操作系统把启动模块处理作在一个文件系统中的文件),不过它确切的使用,取决于操作系统。域‘reserved’必须被启动载入器设置为0,并且为操作系统所忽略。

警告:第4与第5比特位是互斥的。

如果在‘flags’中设置了第4位,那么在Multiboot信息结构体中,从第28个字节开始的以下域是有效的:

    +-------------------+

28 | tabsize              |

32 | strsize               |

36 | addr                  |

40 | reserved (0)      |

    +-------------------+

这些域表示何处可以找到,来自一个a.out内核映像的符号表。‘addr’是一个a.out格式的nlist结构体数组大小(4字节无符号长整形)的物理地址,其后紧跟着这个数组本身,然后是一组以0结尾的ASCII字符串的大小(4字节无符号长整形,并加上sizeof(unsigned long)),最后是这组字符串本身。‘tabsize’是符号表大小的参数(在符号段开头找到),而‘strsize’是随后的符号表所引用的字符串表大小的参数(在字符串段开头找到)。注意到‘tabsize’可能是0,表示没有符号,即便设置了‘flags’中的第4位。

如果在‘flags’中设置了第5位,那么在Multiboot信息结构体中,从第28个字节开始的以下域是有效的:

   +-------------------+

28 | num                  |

32 | size                   |

36 | addr                  |

40 | shndx                |

    +-------------------+

这些域表示何处是来自一个ELF内核的段头表(section header table),每个项的大小,项的个数,及用作名字索引的字符串表。它们对应于在可执行及可链接格式(ELF)规范的程序头(program header)中的‘shdr_*’项(‘shdr_num’,等)。所有的段被载入,然后ELF段头的物理地址域指向内存中的段(如何读出段头的细节,参考i386 ELF 文档)。注意到‘shdr_num’可能是0,表示没有符号,即便设置了‘flags’中的第5位。

如果在‘flags’中设置了第5位,那么域‘mmap_*’是有效的,表示包含由BIOS提供的一个机器内存映射的缓存的地址及长度。其中,‘mmap_addr’是这个地址,而‘mmap_length’是这个缓存的总体大小。这个缓存由以下一个或多个size/structure对组成(‘size’实际上用于跳到下一对):

   +-------------------+

-4 | size                   |

    +------------------+

0   | base_addr         |

8   | length               |

16 | type                  |

    +-------------------+

其中‘size’是关联结构体的字节大小,它至少是20。‘base_addr’是起始地址。‘length’是该内存区域的字节大小。‘type’是所代表的地址区域的种类,其中值1表示为可用的ram,而当前其它值表示一个保留区域。

该映射保证列出所有可以正常使用的标准ram。

如果在‘flags’中设置了第7位,那么域‘drives_*’是有效的,表示第一个drive结构体的物理地址,及drive结构体的大小。‘drives_addr’是这个地址,而‘drives_length’是drive结构体的总大小。注意到‘drives_length’可以是0。每个drive结构体的格式如下:

           +-------------------+

0          | size                    |

           +-------------------+

4          | drive_number    |

           +-------------------+

5          | drive_mode       |

           +-------------------+

6          | drive_cylinders |

8          | drive_heads       |

9          |drive_sectors     |

           +--------------------+

10 - xx | drive_ports        |

           +--------------------+

域‘size’指定这个结构体的大小。这个大小,依赖于端口的数目,是可变的。注意到因为对齐的原因,这个大小可能不等于(10 + 2 * 端口的数目)。

域‘drive_number’包含了BIOS设备号。域‘drive_mode’代表由启动载入器使用的访问模式。当前,以下模式被定义:

‘0’ CHS 模式(传统的柱面/头/扇区(cylinder/head/sector)取址模式)。

‘1’ LBA 模式(逻辑块取址模式(Logical Block Addressing mode))。

‘drive_cylinders’,‘drive_heads’及‘drive_sectors’这三个域表示由BIOS检测出来的驱动的几何数据。‘drive_cylinders’包含柱面数目。‘drive_heads’包含柱头个数。‘drive_sectors’包含每个磁道的扇区数。

域‘drive_ports’包含在BIOS代码中使用的I/O端口数组。这个数组由0个或以上的无符号2字节整数构成,以0结尾。注意到这个数组可能包含任意数目的,不与该驱动真正相关的I/O端口 (比如DMA控制器端口)。

如果在‘flags’中设置了第8位,那么域‘config_table’是有效的,它表示由GET CONFIGURATION BIOS调用返回的rom配置表的地址。如果这个BIOS调用失败,这个表的大小必须为0。

如果在‘flags’中设置了第9位,域‘boot_loader_name’是有效的,它包含了一个启动该内核的启动载入器名字的地址。这个名字是一个普通C-样式以0结尾的字符串。

如果在‘flags’中设置了第10位,域‘apm_table’是有效的,它包含了一个定义如下的APM表的物理地址:

    +----------------------+

0   | version                 |

2   | cseg                      |

4   | offset                    |

8   | cseg_16                |

10 | dseg                      |

12 | flags                     |

14 | cseg_len               |

16 | cseg_16_len         |

18 | dseg_len               |

    +----------------------+

域‘version’,‘cseg’,‘offset’,‘cseg_16’,‘dseg’,‘flags’,‘cseg_len’,‘cseg_16_len’,‘dseg_len’分别表示版本号,32位保护模式代码段,入口点的偏移,16位保护模式代码段,16位保护模式数据段,flags,32位保护模式代码段的长度,16位保护模式代码段的长度,16位保护模式数据段的长度。只有域‘offset’是4个字节,其它的都是2个字节。更多信息,参考先进电源管理(APM)BIOS接口规范。

如果在‘flags’中设置了第11位,表示图形化表可用。如果内核已经在‘Multiboot Header’中表示,它接受一个图形模式,它才能被设置。

域‘vbe_control_info’及‘vbe_mode_info’分别包含了由VBE Function 00h返回的VNE控制信息的物理地址,及由VBE Function 01h返回的VBE模式信息。

域‘vbe_mode’表示在VBE 3.0中所规定格式中的当前视频模式。

余下的域‘vbe_interface_seg’,‘vbe_interface_off’,及‘vbe_interface_len’包含了定义在VBE 2.0+中的一个保护模式接口表。如果这个信息不可用,这些域包含0。注意VBE 3.0定义了另一个保护模式接口,它与旧的不兼容。如果你希望使用新的保护模式接口,你将不得不自己查找这个表。

用于图形化表的域是为VBE设计的,但Multiboot启动载入器可能在非-VBE模式上模拟 VBE,仿佛它们就是VBE 模式。

 


你可能感兴趣的:(OS,header,dos,interface,图形,操作系统相关)