使用自定义引导加载程序创build可启动的ISO映像

我正试图将我用汇编语言编写的引导程序转换为ISO映像文件。 以下是来自MikeOS bootloader的代码。 这是我的bootloader代码:

BITS 16 start: mov ax, 07C0h ; Set up 4K stack space after this bootloader add ax, 288 ; (4096 + 512) / 16 bytes per paragraph mov ss, ax mov sp, 4096 mov ax, 07C0h ; Set data segment to where we're loaded mov ds, ax mov si, text_string ; Put string position into SI call print_string ; Call our string-printing routine jmp $ ; Jump here - infinite loop! text_string db 'This is my cool new OS!', 0 print_string: ; Routine: output string in SI to screen mov ah, 0Eh ; int 10h 'print char' function .repeat: lodsb ; Get character from string cmp al, 0 je .done ; If char is zero, end of string int 10h ; Otherwise, print it jmp .repeat .done: ret times 510-($-$$) db 0 ; Pad remainder of boot sector with 0s dw 0xAA55 ; The standard PC boot signature 

我input以下命令:

 nasm -f bin -o boot.bin boot.asm 

这个命令工作正常,并提供一个.bin输出。 接下来我input下面的命令:

 dd if=boot.bin of=floppy.img count=1 bs=512 

这也工作得很好,给了我的.img输出文件。 当我input这个命令:

 dd if=boot.bin of=floppy.img skip seek=1 count=1339 

我得到以下错误: dd: unrecognized operand 'skip' 。 我在DD文档中读到skip属性必须有一个分配给它的编号。 任何想法我应该input什么数字跳过属性(例如skip = 1)。

接下来我input以下命令:

 mkdosfs -C floppy.img 1440 

我得到以下错误: mkdosfs: unable to create floppy.img 。 我如何解决我遇到的问题? 有没有另一种更简单的方法,我可以将我的bootloader .bin文件转换为ISO映像?

看来你发现你从这个StackOverflow的答案创建一个可启动的ISO映像的例子。 不幸的是,你选择了一个在许多方面不正确的答案。 假装你从未见过这个答案。

在大多数Linux发行版中,存在称为genisoimagemkisofs的程序。 这几天他们其实是同一个节目。 无论你在哪里都可以用下面的例子来代替。 我的例子将假定ISO创建工具被称为genisoimage


在你的问题中,你在boot.asm文件中有一些bootloader代码。 您正确地将其组装到引导扇区二进制映像:

 nasm -f bin -o boot.bin boot.asm 

这将创建引导扇区的boot.bin 。 下一步是创建一个软盘映像并将boot.bin放在第一个扇区中。 你可以这样做:

 dd if=/dev/zero of=floppy.img bs=1024 count=1440 dd if=boot.bin of=floppy.img seek=0 count=1 conv=notrunc 

第一个命令只是简单地将一个零填充的磁盘映像等同于1.44MB软盘(1024 * 1440字节)的大小。 第二个命令将boot.bin放入floppy.img的第一个扇区,而不截断文件的其余部分。 seek=0表示寻找第一个扇区(512字节是DD块的默认大小)。 count=1指定我们只想从boot.bin复制1个扇区(512字节)。 conv=notrunc表示在写入输出文件之后,剩余的磁盘映像保持不变(不被截断)。


在如上所示构建磁盘映像之后,可以使用以下命令创建ISO映像:

 mkdir iso cp floppy.img iso/ genisoimage -quiet -V 'MYOS' -input-charset iso8859-1 -o myos.iso -b floppy.img -hide floppy.img iso/ 

上面的命令首先创建一个名为iso的子目录,它将包含要放在最终CD-ROM映像上的文件。 第二个命令只是将我们的floppy.img复制到iso目录,因为我们需要启动。 第三个命令完成繁重的工作,并建立ISO映像。

  • -V 'MYOS'设置音量标签(可以是任何你想要的)
  • -input-charset iso8859-1设置正在使用的字符集。 不要改变它
  • -o myos.iso表示ISO映像将被输出到文件myos.iso
  • -b floppy.img表示我们的ISO将是可引导的,而正在使用的引导映像是floppy.img文件
  • -hide floppy.img是不需要的,但它隐藏了最终的ISO目录列表的启动镜像。 如果你要挂载这个ISO文件,并在文件上列出文件, floppy.img就不会出现。
  • 命令结尾处的iso/是将用于构建ISO映像的目录。 它至少需要包含我们的可启动软盘映像,但是你可以把你想要的其他文件放到iso/目录中。

生成的ISO映像myos.iso可以启动。 使用QEMU发射这样的图像的一个例子:

 qemu-system-i386 -cdrom ./myos.iso 

对于CD; 有一个规范(“El Torito”),描述了可启动光盘的工作原理; 在前16个(2048字节)扇区未被使用的地方,固件使用了一个“引导目录”来决定它应该使用哪个引导装载程序(这样你就可以拥有一个引导非常不同系统的单个CD–例如PC BIOS,UEFI ,PowerPC等),然后是引导加载程序本身。

仅“PC BIOS”有三种可能性:

  • 模拟软盘(使用存储在CD上的“软盘映像”)
  • 模拟硬盘(使用存储在CD上的“硬盘映像”)
  • 没有模拟

前两个选项大多只用于兼容目的(硬盘旧操作系统不支持从CD启动,如MS-DOS); 并具有性能影响(例如,模拟加载一个512字节的虚拟扇区,固件必须加载真实的2048字节扇区并丢弃多余的1536字节)。 任何在过去15年以上设计/编写的操作系统都应该使用“不仿真”。

对于“不仿真”:

  • 该固件会加载您的整个引导加载程序(最高可达512 KiB),而不仅仅是一个扇区
  • CD上的扇区是2048字节(而不是512字节)。 并应通过加载。 “INT 0x13扩展”(而不是旧的/有限的“CHS磁盘功能”,你会用于软盘)
  • 不需要BIOS参数块(对于软盘应该被认为是强制性的)
  • 不需要分区表(对于包括GPT在内的硬盘应该被视为强制性的)
  • 您可能需要支持ISO9660作为文件系统(以查找引导加载程序需要加载的内核和/或其他文件)而不是FAT。

还要注意(一般情况下)“PC BIOS”,你可能要5个不同的引导装载程序(一个用于软盘,一个用于“MBR分区”硬盘,一个用于“GPT分区”硬盘,一个用于CD,一个用于网络启动)。 这些情况都是不一样的(对于其中的三种情况,“一个512字节的初始扇区只有”限制足够严格),使“一个引导加载程序支持的所有设备”的想法变成一场灾难。

为了实际生成ISO; 你可以使用现有的工具(例如mkisofs),或者你可以编写你自己的工具(ISO9660和“El Torito”都相对容易理解,编写你自己的工具来生成一个ISO可以在两天之内完成,这就像操作系统开发项目中的海洋下降)。