按年代顺序...
最初没有硬盘,并且(如果您没有使用“ROM 中的 BASIC”)计算机是从软盘启动的。在这种情况下,卷(软盘)的第一个扇区包含操作系统的引导加载程序。
添加硬盘后不久,并使用类似的方案工作(其中卷/硬盘的第一个扇区包含操作系统的引导加载程序)。
然而,人们很快意识到将整个“大”硬盘用于单个卷是愚蠢/不灵活的。因此发明了一种分区方案,将硬盘分成多个卷。在这种情况下,磁盘的第一个扇区(MBR)包含一个分区表,其中一个被标记为“活动”分区,以及一些用于“链式加载”活动分区(引导加载程序)的第一个扇区的代码。这变得“非常标准”,然后人们将其扩展为支持多个不同的操作系统,并且大多数引导管理器都使用这种方法支持多个操作系统。
注意 1:我将“引导管理器”定义为您用来选择要引导的操作系统的东西,而“引导加载程序”定义为旨在引导所选特定操作系统的东西。理想情况下,它们彼此无关,启动管理器应该与任何操作系统无关,最终用户应该能够用他们喜欢的任何东西更改启动管理器,而不会扰乱或影响任何操作系统或任何启动加载程序。可悲的是,(对于 Windows)微软对允许多个不同的操作系统使用简单、健全和支持良好的方法启动持敌意(包括允许同时安装同一版本 Windows 的多个实例,这可能很有用 - 例如一个用于工作的操作系统和一个用于孩子的单独操作系统都安装在同一台计算机上)并尝试用自己的“扼杀理智”
随着时间的流逝,添加了更多设备。首先是网卡和从网络启动的能力。这与“从磁盘启动”完全不同。相反,网卡的 ROM(在与 DHCP 服务器协商后)从服务器下载整个“引导文件”(不限于 1 个扇区,如果您愿意,可以是 500 KiB),然后提供一个 API(它变成称为“PXE API”),引导加载程序可以使用它来访问网络(例如发送/接收数据包,使用 TFTP 协议下载更多文件等)。
添加的另一种类型的设备是 CD-ROM。为此,创建了一个新规范(“El Torito 可启动 CD-ROM 规范”),部分原因是您可以拥有一个包含多个架构的多个条目的引导目录(例如,一个用于“80x86 PC”,一个用于“PowerPC”,等)并让固件为正在引导的计算机选择最合适的引导加载程序。为此,PC 有 3 种方法 - 模拟软盘、模拟硬盘或“不模拟”。仿真选项与原始的“从磁盘引导”方法(并使用 512 字节扇区等)的工作方式相同,但受到限制且速度较慢,除了与旧版操作系统的兼容性外,可能不应用于任何其他用途。对于“无仿真”,它与原来的完全不同“
甚至更晚;UEFI 被发明出来。对于 80x86 PC,它有 2 种风格 - 32 位 80x86 和 64 位 80x86。理论上,您可以拥有一个 64 位 UEFI 引导加载程序,它可以切换到保护模式/32 位并启动 32 位操作系统;并且您可以拥有一个 32 位 UEFI 引导加载程序,它可以切换到长模式/64 位并启动 64 位操作系统。但是,32 位 UEFI 非常少见(一些旧的 Apple Mac,几乎没有),这些计算机很可能也支持“BIOS 兼容启动”;因此不值得支持 32 位 UEFI。对于一般的 UEFI,它加载并执行整个文件(从任何引导设备)并提供引导加载程序可以使用的 API(例如,设置视频模式、获取内存映射、加载其他文件等) )。
注意 2:UEFI 尝试使其启动,无论您从哪种类型的设备启动,启动工作都相同。实际上,这并不能很好地工作,您可能需要一个不同的 CD 引导加载程序(访问 CD 本身上的文件,并且不限于 FAT 文件系统映像)和一个不同的引导加载程序网络(即使它只是允许您将 IP 地址传递给操作系统并避免在操作系统启动后重复缓慢的 DHCP 内容)。
UEFI 还引入了一种新的分区方案(GPT 或“GUID 分区表”)。这有多个优点,并且(对于作为计算机上唯一操作系统安装的新操作系统)可能应该被视为默认设置(并且旧的“MBR 分区”可能应该被认为是过时的,仅与旧操作系统兼容)。
大多; 对于 80x86,您可能需要 4 个或更多不同的引导加载程序:
- 一个用于 BIOS 和未分区的磁盘设备(软盘)
- 一个用于使用“MBR 分区”分区的 BIOS 和磁盘设备
- 一种用于使用“GPT 分区”分区的 BIOS 和磁盘设备
- 一个用于 BIOS 和网络启动/PXE
- 一个用于 BIOS 和“无仿真”CD 引导
- 一个用于 64 位 UEFI 磁盘
- 一张用于 64 位 UEFI CD-ROM
- 一个用于 64 位 UEFI 网络
当然,所有这些情况都“足够不同”,以至于尝试拥有一个涵盖多种不同情况的通用引导加载程序是愚蠢的(并且在有相似之处的情况下,例如“仅 512 字节”限制是如此限制你如果你尝试将注定失败)。
我还“强烈建议”在引导加载程序和操作系统的其余部分之间进行某种抽象(例如,为操作系统定义的“引导协议”描述引导加载程序如何设置,将信息传递给操作系统并传输控制到操作系统);这样整个操作系统中的任何代码都不需要知道或关心固件是什么(如果它是 BIOS 或 UEFI 或其他东西,比如可能kexec()
)。这意味着任何人都可以创建更多的引导加载程序(以支持其他情况和其他设备);并且(只要一切都符合您的抽象规范)整个操作系统将与新的引导加载程序一起工作而无需任何更改。
在 FAT32 下,我有 MBR 引导加载程序从 Bochs 读取由 bximage 生成的虚拟磁盘映像的第一个扇区。我应该将显示黑屏的第二个编译代码放在哪里(哪个扇区)?如何使用 dd 实用程序来做到这一点?我的第二个编译代码文件只有 9 个字节。
这大多是错误的。对于“BIOS 硬盘”,您应该有一个 MBR(与操作系统完全无关)和分区,并且您的操作系统的引导加载程序应该从分区的第一个扇区开始(并且应该设计用于DS:SI
查找描述其分区的分区表条目,并dl
确定该分区在哪个设备上)。
是否需要 VBR?
对于某些情况(从 UEFI、网络、CD-ROM 引导),VBR 没有意义。在某些情况下(从 BIOS 硬盘或 BIOS USB 闪存启动)它是“理论上可选的”,但非常推荐;因为某些 BIOS 可能无法识别它(尤其是对于 USB 闪存盒),而其他操作系统会假定磁盘未格式化(并会告诉他们的用户磁盘需要初始化/分区,从而使用户相信您的操作系统是垃圾,并导致用户意外或故意将您的操作系统从磁盘上擦除)。
我如何知道数据区域 (FAT32) 的开始和结束位置?
对于脂肪;卷/分区的第一个扇区中的 BPB(“BIOS 参数块”,它被错误命名,因为它几乎完全不被 BIOS 使用)中的字段告诉您有多少保留扇区,多少扇区等信息在每个集群中,等等。真的,如果你打算使用世界上最糟糕的文件系统之一来处理不合适的事情(例如,对于操作系统的主分区,需要有效的权限/安全性和容错等),那么你'将需要了解有关 FAT32 的所有内容,以便您可以编写代码以允许操作系统在启动后支持它。