【问题标题】:How can I copy an existent BPB and put it in my bootloader code如何复制现有的 BPB 并将其放入我的引导加载程序代码中
【发布时间】:2021-12-11 05:26:06
【问题描述】:

我目前正在开发一个简单的操作系统(GitHub:https://github.com/Nutty000/PlanetOS

我想让操作系统在真实硬件上运行,但由于文件系统的原因,我无法做到这一点...我希望我的操作系统基于 FAT32 文件系统,但我需要以某种方式不覆盖MBR 上的 BPB。我想过编写一个程序来复制现有的 BPB 并将其放在我的 .bin 可引导文件的开头,但是:

  1. 我不知道如何制作那个程序,磁盘相关的东西对我来说太难和困惑了

  2. BPB 太大,如果我复制它,那么我的引导加载程序代码将不适合 512 字节

  3. 我不知道我应该复制现有 MBR 代码的哪些部分

我试图解决这个问题好几个小时,如果我犯了任何语法错误,请见谅。

【问题讨论】:

标签: assembly bootloader osdev fat32 mbr


【解决方案1】:

对于 MBR

MBR“应该”(见注释)具有 BPB 的唯一情况是未分区磁盘,其中磁盘的第一个扇区也是文件系统的第一个扇区。这主要是旧软盘,仅此而已(其他所有内容要么使用分区,要么使用具有不同规则的 ISO9660 之类的文件系统)。

注意:“应该”表示如果没有 BPB,某些操作系统(例如 Windows)会抱怨磁盘未格式化。对于 BPB 的存在,固件或硬件没有严格的要求;并且您的操作系统可以根据自己的需要制定自己的规则。

对于旧软盘,操作系统开发人员通常会做相反的事情 - 例如他们将拥有(或编写)一个实用程序来创建正确/所需大小的软盘映像(例如,标准 3.5 英寸软盘为 1440 KiB),为该软盘格式创建合适的 BPB;然后将映像复制到他们想要的任何软盘中,而不用关心软盘以前的内容(可能在格式化软盘之后立即进行,或者作为格式化软盘的一部分)。更常见的是(现在软盘本身已经过时,实际上它们实际上不存在)软盘映像直接在模拟器中使用,或者合并到 CD 映像/ISO 中并用于软盘模拟,其中没有物理软盘磁盘(并且不涉及“以前的内容”)。

如果您确实需要在保留现有 BPB 的同时写入磁盘的新第一个扇区;然后您可以编写一个实用程序来执行此操作(例如,将旧的第一个扇区读入缓冲区,然后覆盖 BPB 之前的前几个字节和缓冲区中 BPB 之后的其余部分,然后将修改后的缓冲区写回磁盘);或者您可以使用现有工具(特别是大多数 *nix 系统上的 dd 实用程序)。

另请注意,FAT32 对软盘没有意义(因为您需要 FAT12 的卷的体积很小)。

对于 FAT32 分区的第一个扇区(不是 MBR)

对于分区磁盘,如果您使用 FAT32,则分区的第一个扇区除了 BPB(FAT32 文件系统要求)之外,还可能包含引导加载程序的第一个扇区(用于 BIOS,而不是 UEFI)。在这种情况下,它主要是应用于不同扇区的相同解决方案(例如,使用良好的 BPB 覆盖以适应分区/磁盘,或使用工具保留旧的 BPB 并仅修改第一个扇区的“非 BPB”部分)。

请注意,最终您将编写某种操作系统安装程序,允许用户创建分区、格式化分区并在新分区上安装操作系统(包括引导加载程序和许多其它文件)。通常,您编写的操作系统安装程序将在您编写的操作系统之上运行(并从 CD 或 USB 启动);除了使用内核、驱动程序等之外,还将回收您为操作系统编写的大量实用程序(例如分区管理工具等)。

  1. 我不知道应该复制现有 MBR 或分区的第一个扇区代码的哪些部分

BPB 的位置和大小取决于它的版本。幸运的是,它们都在维基百科(https://en.wikipedia.org/wiki/BIOS_parameter_block)上进行了描述。

大多数情况下,为了涵盖“最坏/最大的情况”,您要确保引导加载程序不使用 0x000B 到 0x0059 的偏移量(以及用于将引导加载程序的第一个扇区与预现有的 BPB 保留从偏移量 0x000B 到 0x0059 的字节)。

当然,对于 512 字节的扇区大小,丢失大约 80 字节的 BPB 会使引导加载程序的第一个扇区更难包含找到正确分区所需的代码,然后加载自身的其余部分或第二个扇区阶段(特别是如果有足够的健全性/错误检查和足够的错误消息)。有时人们通过在安装引导加载程序时设置一些变量(例如“分区中第二扇区的 LBA”)来缓解问题(如果您编写自己的引导加载程序安装程序,这相对容易)。

【讨论】:

  • 根据 Michael Petch 的说法,固件不需要 BPB 来引导 MBR,但在某些情况下,某些 BIOS 会用不需要的 BPB 字节覆盖 MBR 的字节。 Bootloader works in emulators but not on real hardware / Custom bootloader booted via USB drive produces incorrect output on some computers 显示它正在启动但做奇怪的事情。也许这些引导加载程序碰巧在某个地方有几个字节,看起来像是粗略启发式的 BPB 签名,或者这些 BIOS 只是盲目地复制。
  • @PeterCordes:是的。对于这些情况,正确的解决方案是对 USB 进行分区,这样固件就不必尝试模拟过时的垃圾(这样您就不必将内核 + 驱动程序 + 其他所有内容的“许多 MiB”压缩成微不足道的最多 2.88 MiB 的模拟软盘空间)。;-)
  • 当然,只是想说明 BIOS 可能会启动您的 MBR,但会搞砸。您的答案的早期部分描述事物的方式不会提醒未来的读者在查看事情是否在不在 MBR 中留下 BPB 空间的情况下工作时考虑这种可能性。由于裸 PC 硬件没有调试工具,因此您不会在单步执行时注意到这一点,因为您不能轻松地做到这一点。
  • 我没想到我的问题会得到如此长而有用的答案,非常感谢你帮助我,我试图解决这个问题好几个小时!
【解决方案2】:

MBR 中没有 BPB。您正在混合两种类型的引导扇区。

MBR(主引导记录)是磁盘上的第一个扇区。它在其分区表中包含从偏移量 01BEh 开始的分区信息。在这种引导扇区中,前 446 个字节 (512-64-2) 可用于加载 DBR 的引导扇区程序。
DBR(DOS 引导记录)是分区上设置为可从分区表引导的第一个扇区。这种引导扇区确实包含一个 BPB(BIOS 参数块)。对于 FAT32,它占用前 90 个字节。考虑到最后的强制引导扇区签名,您有 420 个字节 (512-90-2) 可用。

我不知道如何制作那个程序,磁盘相关的东西对我来说太难和困惑了

这对于想要创建自己的操作系统的人来说太糟糕了。

BPB 太大,如果我复制它,那么我的引导加载程序代码将不适合 512 字节

您必须针对代码大小优化代码。所需的结构就是它们。

我不知道我应该复制现有 MBR 代码的哪些部分

首先将现有的 DBR 从磁盘复制到一个文件,例如。 'MyDBR.bin'。 然后像这样写你的引导扇区(FASM):

  jmp begin
  nop
  FILE 'MyDBR.bin':3,87
Begin:

  ...

  times 510-($-$$) db 0
  dw 0AA55h

【讨论】:

  • 如果磁盘是软盘,则 MBR 有一个 BPB。
  • @fuz:像软盘一样格式化的更大存储单元,在第一个扇区有一个 BPB,也称为“超级软盘”。
猜你喜欢
  • 1970-01-01
  • 2018-01-26
  • 2017-08-29
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
  • 1970-01-01
相关资源
最近更新 更多