查看“Boot Sequence”的源代码
←
Boot Sequence
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
== POST == 当计算机被打开或重置时,它会运行一系列被称为POST-“P”ower-“O”n-“elf-“T”est的诊断。 这一顺序的最终结果是按照固件配置的顺序定位可引导设备,如软盘、CD-ROM或硬盘。 == 主引导记录 == (传统)BIOS检查可引导设备的引导签名,即所谓的幻数。 引导签名位于引导扇区(扇区号0)中,它分别在字节偏移量510和511处包含字节序列0x55、0xAA。 当BIOS找到这样一个引导扇区时,它被加载到内存中的<tt>0x0000:0x7c00</tt>(段0,地址0x7c00)。(但是,某些BIOS加载到<tt>0x7c0:0x0000</tt>(段0x07c0,偏移量0),这解析为相同的物理地址,但可能会令人惊讶。 一个好的实践是在启动扇区的一开始就强制执行CS:IP。) 然后将执行转移到新加载的引导记录。 在软盘上,引导记录的所有512字节(保存最后两个签名字节)可能包含可执行代码。 在硬盘驱动器上,[[MBR(x86)|主引导记录]](MBR)在偏移量0x0000-0x01bd处保存可执行代码,然后是四个[[Partition table | primary partitions]]的表项,每个项使用十六个字节(0x01be-0x01fd)和两个字节的签名(0x01fe-0x01ff)。 == 早期环境 == 这种早期执行环境是高度实现定义的,这意味着特定BIOS的实现。 “从不”对寄存器的内容做任何假设:它们可能被初始化为0,但也可能包含虚假值。 这包括标志寄存器和SP寄存器,您可能也没有有效的堆栈!唯一可以确定的是,DL寄存器保存了加载引导代码的驱动器代码。 CPU当前处于[[实模式]]。 (除非你运行的是一种罕见的BIOS,它认为为你激活[[保护模式]]是在帮你的忙。 这意味着您不仅必须编写代码来激活任何“其他”硬件上的保护模式,而且还应添加测试条件(如果已激活)。) == 内核 == 最后,引导加载程序将内核加载到内存中,并将控制权传递给它。 == 加载 == 现在我们知道要加载什么了,让我们看看如何加载。 如果从硬盘引导,则只有446字节可用于引导记录。 查看内核映像运行之前要做的事情列表,您会同意这并不多: *确定要从哪个分区启动(通过查找活动分区,或向用户提供要从中选择的已安装操作系统); *确定内核映像在引导分区上的位置(通过解释文件系统或从固定位置加载映像); *将内核映像加载到内存中(需要基本磁盘I/O); *启用保护模式; *为内核准备运行时环境(例如设置堆栈空间); 您不必按此顺序执行操作,但在调用<tt>kmain()</tt>之前,必须完成所有这些操作。 更糟糕的是,GCC只生成受保护模式的可执行文件,因此这个早期环境的代码是[[C#C做不到的事情| C做不到的事情]]之一。 有几种方法可以解决此问题: *“极客加载”:将上面列表中的所有内容压缩到启动记录中。这几乎是不可能的,并且不会为任何特殊情况处理或有用的错误消息留下空间。 *“一阶段加载”:编写一个用于切换的存根程序,并将其链接到内核映像前面。引导记录加载内核映像(低于1mb内存标记,因为在实模式下,这是内存上限!),跳入存根,存根切换到保护模式和运行时准备,跳入内核。 *“两阶段加载”:编写一个“单独的”存根程序,该程序加载到1mb内存标记以下,并执行上述列表中的所有操作。 === 传统方式 === 传统上,MBR将自己重新定位到<tt>0x0000:0x0600</tt>,从分区表确定活动分区,将该分区的第一个扇区(“分区启动记录”)加载到<tt>0x0000:0x7c00</tt>(因此前一次重新定位),并跳到该地址。 这被称为“链式装载”。如果您希望自己编写的引导记录能够进行双重引导(例如Windows),则它应该模拟这种行为。 === 捷径 === 除非您真的想[[滚动您自己的引导加载程序]](记录/存根)以获得教育价值,否则我们建议使用现成的[[:类别:引导加载程序|引导加载程序]]。 最突出的是[[GRUB]],这是一种两级引导加载程序,它不仅提供具有链加载功能的引导菜单,而且将早期环境初始化为定义良好的状态(包括[[Protected Mode]],并从BIOS读取各种感兴趣的信息),可以将通用可执行文件作为内核映像加载(而不像大多数其他引导加载程序那样需要平面二进制文件),支持可选的内核模块、各种文件系统以及if<tt>/正确配置,[[Diskless Booting]]。 === 一些方法 === 有许多可能的变体可以引导。以下是方法列表,但可能还有更多方法: *您可以使用一个未使用的分区并加载阶段2“raw” *您可以将阶段2放在MBR和第一个分区的开始之间 *您可以(像Lilo那样)编写一个内核文件,然后使用工具检测扇区(或集群)。然后让阶段1从列表中加载扇区。 *DOS和Windows是这样做的:创建一个空文件系统(格式化),然后将内核放在第一个文件中,将shell放在第二个文件中的空rootdir中。因此,加载程序只需加载rootdir中的第一个条目,然后加载第二个条目。 *旧Linux是从软盘引导的。第一个扇区(“boot”)以“raw”模式加载第二个阶段=不带文件系统(scond阶段是“setup”,在“boot”后面的扇区中)。第二个阶段设置了系统(视频模式、内存映射等),然后加载了真正的内核映像(打包在tgz/bz中)。 *几年前,这里有一个引导加载程序(称为“nuni”),它切换到pmode并加载一个文件,所有这些都在一个引导扇区中 == See Also == === 外部链接 === * [http://duartes.org/gustavo/blog/post/how-computers-boot-up Jun 2008: How Computers Boot Up] by Gustavo Duarte. * [http://duartes.org/gustavo/blog/post/kernel-boot-process Jun 2008:The Kernel Boot Process] by Gustavo Duarte. * IBM developerWorks' [https://developer.ibm.com/technologies/linux/articles/l-linuxboot/ Inside the Linux boot process] a very good, illustrated overview from BIOS to userspace. [[Category:Bootloaders]] [[Category:X86]] [[de:Bootprozess auf x86]]
返回至“
Boot Sequence
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
变体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息