当前位置: 首页 > 操作系统 > 正文

ParalleX OS 设计与实现 启动篇multiboot方式

启动方式相关说明:

每个操作系统的启动都需要一套启动的机制,所以说在最早的时候各个操作系统启动的方式都是不同的,我们在设计实现自己的“操作系统”的时候,其实也可以自己写一段启动程序,但是个人觉得暂时没有什么必要,如果用现有的GRUB启动其实在后期可以节省不少事。但是启动的原理必须要清楚。《X86汇编语言:从实模式到保护模式》这本书讲的还是挺清楚的,大家可以看看。这里不再赘述原理。

关于我们选择的启动方式:multiboot 方式。这是一种GRUB启动的一种规范方式。MIT的教学系统XV6,清华大学的ucore 也是使用的这种启动规范。

 

multiboot启动规范

目标机器:主要面向PC,尤其是X86 架构。

目标规范:主要面向Linux,freebsd, netbsd,mach,vst 等自由操作系统设计。

关于保护模式他的解释:     应尽量降低生成OS映象的难度。在理想情况下,OS映象应该是该操作系统通常使用的普通32位可执行文件格式。应该能够像对待普通可执行文件格式一样用nm或者反汇编OS映象,而不应该用到特殊的工具来生成使用特殊文件格式的OS映象。如果这意味着将一部分的操作系统功能转移到引导程序中来的话,这很合适,因为任何引导程序用到的内存都应该可由它所创建的真正的系统自由使用,这样OS映象中的每一个比特都应该永远留在内存中。操作系统应该不必考虑如何进入32位地址模式,因为模式切换应该位于引导程序中,而这些程序通常需要将操作系统数据装入到1MB以上的内存,如果操作系统需要考虑这些问题的话创建OS映象的工作将变得更加困难。

不幸的是,仅在PC平台上的自由UNIX类系统中也有多得惊人的可执行文件格式——通常各种操作系统的格式都不相同。大多数的自由操作系统使用的是a.out格式的变种,但有一些已经改用了ELF格式。最好是引导程序不必为了载入OS映象而需要理解所有的可执行文件格式——否则的话引导程序又变成了某个操作系统专用的了。

这份规范采用了一种折衷的方案。符合Multiboot规范的OS映象总是包含一个magic Multiboot头(参见OS映像格式),这样引导程序就不必理解种类繁多的a.out变体或者其他什么可执行格式。magic头不必位于可执行文件的最前面,这样 OS 映象就可以在保持同a.out格式兼容的同时做到符合Multiboot规范。

关于模块:这个标准定义了如何指定载入模块。我们只要按照他的指示就可以插入相应的模块。

关于multiboot 头的一些规则

 

偏移量 类型 域名 备注
0 u32 magic 必需
4 u32 flags 必需
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域在头的magic域中定义,header_addr、load_addr、load_end_addr、bss_end_addr和entry_addr域在头的地址域中定义,mode_type、width、height和depth域则在头的图形域中定义。

如果设置了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映象对此没有要求。

以下有两个参考资料:

http://www.cnblogs.com/chio/archive/2008/01/01/1022430.html

https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Header-graphics-fields

本文固定链接: http://zmrlinux.com/2016/07/17/parallex-os-%e8%ae%be%e8%ae%a1%e4%b8%8e%e5%ae%9e%e7%8e%b0-%e5%90%af%e5%8a%a8%e7%af%87multiboot%e6%96%b9%e5%bc%8f/ | Kernel & Me

该日志由 root 于2016年07月17日发表在 操作系统 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: ParalleX OS 设计与实现 启动篇multiboot方式 | Kernel & Me