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

Linux 使用自定义引导加载程序创建可引导ISO映像,linux,assembly,nasm,osdev,dd,Linux,Assembly,Nasm,Osdev,Dd,我正在尝试将我用汇编语言编写的引导加载程序转换为ISO映像文件。以下是引导加载程序中的代码。以下是我的引导加载程序代码: 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

我正在尝试将我用汇编语言编写的引导加载程序转换为ISO映像文件。以下是引导加载程序中的代码。以下是我的引导加载程序代码:

   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 
mkdosfs -C floppy.img 1440 
此命令工作正常,并提供.bin输出。接下来,我键入了以下命令:

dd if=boot.bin of=floppy.img count=1 bs=512 
dd if=boot.bin of=floppy.img skip seek=1 count=1339
这也很好,并给了我.img输出文件。键入此命令时:

dd if=boot.bin of=floppy.img count=1 bs=512 
dd if=boot.bin of=floppy.img skip seek=1 count=1339
我得到以下错误:
dd:无法识别的操作数“跳过”
。我在DD文档中读到,skip属性必须有一个编号。知道我应该用skip属性键入什么数字吗(例如skip=1)

接下来,我键入以下命令:

nasm -f bin -o boot.bin boot.asm 
mkdosfs -C floppy.img 1440 

我收到以下错误:
mkdosfs:无法创建软盘.img
。如何解决我遇到的问题?有没有其他更简单的方法可以将bootloader.bin文件转换为ISO映像

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

在大多数Linux发行版上,存在一个名为
genisoimage
mkisofs
的程序。这些天他们实际上是同一个节目。在下面的示例中,可以替换您拥有的任何一个。我的示例将假定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'
    设置卷标(它可以是您想要的任何内容)
  • -输入字符集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

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

仅“PC BIOS”就有3种可能:

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

对于“无仿真”:

  • 固件加载整个引导加载程序(可能高达512 KiB),而不仅仅是一个扇区
  • CD上的扇区为2048字节(而不是512字节);并应通过加载。“int 0x13扩展”(而不是用于软盘的旧的/有限的“CHS磁盘功能”)
  • 不需要BIOS参数块(这对于软盘来说是必需的)
  • 不需要分区表(对于硬盘,包括GPT,分区表应视为必需)
  • 您可能希望支持ISO9660作为文件系统(查找引导加载程序需要加载的内核和/或其他文件),而不是FAT
另外请注意(通常)对于“PC BIOS”,您可能需要5个不同的引导加载程序(一个用于软盘,一个用于“MBR分区”硬盘,一个用于“GPT分区”硬盘,一个用于CD,一个用于网络引导)。这些情况完全不同(其中3种情况下的“仅限一个512字节初始扇区”限制足够严格),因此“al”