如何制作可启动软盘映像?

How to make a bootable floppy disc image?

假设我已经构建了一个汇编程序(基本打印),所以我有一个 .BIN 文件。
现在我想让它成为一个可引导的软盘映像(一个虚拟的),这样当我启动一个 OS (在 vm 中)时,它会首先执行位于该虚拟上的我的程序的汇编指令软盘.
如何正确地做到这一点?

你可以使用 my boot sector loaders (ldosboot boot.asm for FAT12 / FAT16 FS) and my boot image creation script to make a 1440 KiB file system image preloaded with your kernel executable and a loader in the first sector. You'll also need my macro collection. Here's an example shell session to clone the repos and build an image. This is using hg (Mercurial) to load the repos, wget to get a release of my debugger as an example program, Info-ZIP's unzip to unpack it, NASM 来 assemble 加载程序和图像,并且 qemu 可以 运行 一切都一次 assembled.

$ hg clone https://hg.pushbx.org/ecm/lmacros
destination directory: lmacros
requesting all changes
adding changesets
adding manifests
adding file changes
added 143 changesets with 171 changes to 38 files
new changesets 3a982025dd94:323cc150061e
updating to branch default
29 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg clone https://hg.pushbx.org/ecm/ldosboot
destination directory: ldosboot
requesting all changes
adding changesets
adding manifests
adding file changes
added 588 changesets with 650 changes to 15 files (+2 heads)
new changesets 13cf6bb0b5f5:07f4ba0ef8cd
updating to branch default
15 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg clone https://hg.pushbx.org/ecm/bootimg
destination directory: bootimg
requesting all changes
adding changesets
adding manifests
adding file changes
added 88 changesets with 88 changes to 1 files
new changesets 966f8a094eca:fa44558212e7
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ wget https://pushbx.org/ecm/download/ldebug.zip
--2021-11-18 13:05:18--  https://pushbx.org/ecm/download/ldebug.zip
Resolving pushbx.org (pushbx.org)... 2a01:488:66:1000:b01c:1258:0:1, 176.28.18.88
Connecting to pushbx.org (pushbx.org)|2a01:488:66:1000:b01c:1258:0:1|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7131575 (6.8M) [application/zip]
Saving to: 'ldebug.zip'

ldebug.zip           100%[=====================>]   6.80M  --.-KB/s    in 0.03s

2021-11-18 13:05:18 (259 MB/s) - 'ldebug.zip' saved [7131575/7131575]

$ unzip ldebug.zip bin/ldebugu.com
Archive:  ldebug.zip
  inflating: bin/ldebugu.com
$ nasm -I lmacros/ -I ldosboot/ ldosboot/boot.asm -D_COMPAT_FREEDOS -D_QUERY_GEOMETRY=0 -D_LBA=0 -D_USE_PART_INFO=0 -o boot.bin
ldosboot/boot.asm:420: warning: Possibly crossing 64 KiB boundary while reading file (sector size >= 1024) [-w+user]
ldosboot/boot.asm:1851: warning: FAT12: 18 bytes still available. [-w+user]
$ nasm -I lmacros/ -I bootimg/ bootimg/bootimg.asm -D_BOOTFILE="'boot.bin'" -D_PAYLOADFILE="::rename,'bin/ldebugu.com','KERNEL.SYS'" -o diskette.img
$ qemu-system-i386 -fda diskette.img -boot order=a -curses

bootimg 的文档是 in a comment at the top of the main source file。我使用 _BOOTFILE 定义(设置为双引号字符串,因此 NASM 接收带引号的字符串)来指示引导扇区文件,并且主要 _PAYLOADFILE 定义指定包含调试器可执行文件, 将其重命名为 KERNEL.SYS 以便 _COMPAT_FREEDOS 加载程序使用的默认名称将找到我们的可执行文件。

除了 FreeDOS 兼容性选择之外,boot.asm 需要一些额外的开关来禁用启动 1440 KiB 软盘映像不需要的功能。这是因为 FreeDOS 兼容加载器需要比我的 (lDOS) 默认值更多的 space。

最后,您指定要加载的文件(默认值如 KERNEL.SYS 或使用 boot.asm 指定的文件名中的一个文件定义了 _LOAD_NAME_LOAD_EXT ) 需要采用正确的格式。 FreeDOS 加载协议相当简单:您的整个文件被加载到地址 600h,可以使用分段地址 60h:0 寻址,并且 cs:ip 完全按照 60h:0 设置。寄存器 bl 接收您从中引导的 ROM-BIOS 单元,并且 ss:bp 指向内存中某处的 FS 引导扇区的副本。所有其他寄存器,尤其是段寄存器,是不确定的,如果您想使用它们,必须由您的代码初始化。

请注意,FreeDOS 加载协议不同于此级别的大多数其他加载协议,因为 bl 设置为加载单元。根据使用的加载程序,dl 可能与 bl 不同,在这种情况下 bl 是正确的,而 dl 是不正确的。加载单元也可以在 ss:bp 指向的引导扇区副本中找到,对于 FAT32 在 byte [ss:bp + 40h] 中,对于 FAT12 和 FAT16 在 byte [ss:bp + 24h] 中。