【问题标题】:How to go about making a two-stage FAT32 USB bootloader?如何制作两阶段的 FAT32 USB 引导加载程序?
【发布时间】:2015-02-14 06:27:08
【问题描述】:

我正在制作自己的操作系统,并且我已经阅读了有关自制 OSdev 的所有内容。但是,我不明白如何制作两阶段引导加载程序。更具体地说,我不明白如何让我的第一阶段在 FAT32 文件系统上定位第二阶段。

图表:第一阶段 -> 第二阶段(启用 pmode、gdt 等)-> 内核

USB 规格:

  • 4 GB,3.75 GB 可用

有什么建议吗???

【问题讨论】:

    标签: assembly usb bootloader osdev fat32


    【解决方案1】:

    我自己正在开发一个自己编写的 OS 2(现在已经一年多了)。我已经为 FAT12/16 和 FAT32 编写了一个两阶段的引导加载程序,并且有一个显着的区别:

    • 在 FAT12/16 上,编写引导加载程序非常容易
    • 在 FAT32 上这非常困难,因为许多位于 FAT12/16 加载程序第二阶段的第一个扇区的东西必须已经在 FAT32 的引导扇区中。

    据我所知,甚至 Windows 都坚持认为第二阶段文件是根目录上的第一个文件之一(在这种情况下,需要较少的引导扇区中的代码)或使用一些具有固定扇区号的额外扇区将引导扇区“扩展”到 > 512 字节。

    对于应该与同一磁盘上的其他系统共存的自己的操作系统,这两种方法都行不通。

    我的引导加载程序的工作方式如下:

    它计算第一个簇的扇区号。它包含一个子例程,可以通过给定的簇号(它们是 32 位!)和一个簇相关的扇区来读取一个扇区。

    读取根目录的第一个扇区(簇号已知)并搜索包含第二阶段代码的文件。然后读取第二个扇区,依此类推。

    当一个簇的所有扇区都被读取时,必须读取 FAT 以获得根目录下一个簇的簇号。这是 FAT12/16 引导加载程序的第二阶段代码中的部分,但对于 FAT32 引导加载程序必须位于引导扇区本身。

    一旦找到目录条目,您将加载第二阶段文件的第一个簇的第一个扇区。加载文件的其余部分可以通过第二阶段文件的第一个扇区中的代码来完成!

    使用 INT 13h 时,函数 42h(1995 年以后的 BIOS 支持的线性磁盘读取)如果您只使用非常短的错误消息,那么 512 字节的引导扇区就足够了。使用 INT 13h,函数 2(C/H/S 磁盘读取)我没有设法写入 FAT32 引导扇区,因为 512 字节还不够。

    【讨论】:

    • 512 字节对于第一阶段应该足够了,你甚至不需要特别优化大小。否则,是的,我也是这样做的。
    • @Jester - 你忘了文件系统:FAT32。与 EXT2 不同,文件系统元信息存储在第一个扇区中,因此您只剩下大约 430 个字节用于代码。 “第二阶段”存储在一个文件中,这意味着您必须使用引导扇区中的代码解析整个根目录。这就是为什么微软使用一个额外的扇区——在 GRUB 中这将被称为 1.5 阶段——或者假设他们的文件是根目录中的第一个文件。
    • 大声笑我没有忘记,你不必向我解释。解析根目录很简单。
    • @Jester 你的操作系统是开源的吗?
    • 有一点时间调试它,所以here it is。它适用于软盘或高清的 FAT12/16/32,并留有 86 个字节用于错误消息和 crc。再三考虑,应该过滤掉长文件名条目以避免错误的文件匹配。
    【解决方案2】:

    您确定需要编写自己的引导加载程序吗?

    已经有很多可用的 x86 引导加载程序(Lilo、Grub 和 Extlinux 等)。它们不是特定于 Linux 的;只要您的操作系统符合the multiboot specification,它们中的任何一个都可以启动您的操作系统。使用其中任何一种都可以为您节省大量的开发时间。

    总而言之,定位第二阶段引导加载程序的最常见方法是:

    1. 将其存储在 MBR 之后、第一个分区之前的空闲空间中。 (假设存在这样的空间,但它在大多数磁盘上都存在。)

    或

    1. 将扇区号列表嵌入到第一阶段引导加载程序中,将其引导至第二阶段引导加载程序所在的位置。

    【讨论】:

    • 问题是,我想制作自己的引导加载程序,因为许多其他引导加载程序具有太多功能。我喜欢 GRUB,但我现在还不需要模块或多重引导功能。我不会分发这个操作系统,它仅供私人使用。
    猜你喜欢
    • 1970-01-01
    • 2013-05-05
    • 2016-03-22
    • 2015-11-18
    • 2019-08-24
    • 2016-02-14
    • 1970-01-01
    • 2019-07-08
    • 2020-04-29
    相关资源
    最近更新 更多