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

问题描述 投票:8回答:2

我试图将我用汇编语言编写的引导加载程序转换为ISO映像文件。以下是MikeOS 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

我输入以下命令:

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

此命令工作正常,它提供.bin输出。接下来我输入以下命令:

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

这也很好,并给了我.img输出文件。当我输入此命令时:

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

我收到以下错误:dd: unrecognized operand ‘skip’。我在DD文档中读到skip属性必须分配一个编号。任何想法我应该使用skip属性键入什么数字(例如,skip = 1)。

接下来我输入以下命令:

mkdosfs -C floppy.img 1440 

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

linux assembly nasm osdev dd
2个回答
17
投票

您似乎找到了从此StackOverflow Answer创建可引导ISO映像的示例。不幸的是,您在许多方面选择了一个不正确的答案。假装你从未见过那个答案。

在大多数Linux发行版中,存在一个名为genisoimagemkisofs的程序。这些天他们实际上是同一个程序。您可以在下面的示例中替换您的任何一个。我的示例将假设ISO创建实用程序称为genisoimage


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

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并在其上执行ls列出文件,则不会出现floppy.img
  • 命令末尾的iso/是用于构建ISO映像的目录。它至少需要包含我们的可启动软盘映像,但您可以将所需的任何其他文件放入iso/目录中。

可以引导生成的ISO映像myos.iso。使用QEMU启动此类图像的示例:

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

4
投票

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

仅对于“PC BIOS”,有3种可能性:

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

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

对于“无仿效”:

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

另请注意(一般情况下)对于“PC BIOS”,您可能需要5种不同的引导加载程序(一种用于软盘,一种用于“MBR分区”硬盘,一种用于“GPT分区”硬盘,一种用于CD,和一个用于网络启动)。这些情况都足够不同(并且“对于这些情况中的3个”仅限于一个512字节的初始扇区“限制是足够的限制)以使”一个引导加载程序支持的所有设备“想法成为灾难。

实际生成ISO;您可以使用现有工具(例如mkisofs),或者您可以编写自己的工具(ISO9660和“El Torito”都相对容易理解,编写自己的工具来生成ISO可以在不到2天的时间内完成,这对于OS开发项目来说就像是一片海洋。

© www.soinside.com 2019 - 2024. All rights reserved.