X86 VirtualBox-未找到可引导介质

X86 VirtualBox-未找到可引导介质,x86,virtual-machine,virtualbox,bootloader,osdev,X86,Virtual Machine,Virtualbox,Bootloader,Osdev,关于类似标题的stackoverflow有很多问题。我读了所有的书,但没有一本能回答我的问题。这就是我提出这个问题的原因 我正在用汇编语言和C语言创建一个操作系统。我发现我必须将C代码编译成二进制格式,提取文本部分并将其保存为文件,然后将其转换为ISO,然后将其装入diskete的虚拟光盘驱动器,然后将我的操作系统装入VirtualBox。所以,这是我想要避免的大量工作。我不想每次都将二进制文件转换为ISO 因此,我决定将操作系统的二进制机器代码放入虚拟硬盘驱动器(VDI文件),然后将其设置为启

关于类似标题的stackoverflow有很多问题。我读了所有的书,但没有一本能回答我的问题。这就是我提出这个问题的原因

我正在用汇编语言和C语言创建一个操作系统。我发现我必须将C代码编译成二进制格式,提取文本部分并将其保存为文件,然后将其转换为ISO,然后将其装入diskete的虚拟光盘驱动器,然后将我的操作系统装入VirtualBox。所以,这是我想要避免的大量工作。我不想每次都将二进制文件转换为ISO

因此,我决定将操作系统的二进制机器代码放入虚拟硬盘驱动器(
VDI
文件),然后将其设置为启动顺序的顶部并加载,而不是从虚拟光盘驱动器
ISO
加载

我正在研究
VDI
是如何工作的,我发现它通常是动态分配的,并且只存储数据的开头。因此,
VDI
的开头代表一个标头,其余部分是存储在虚拟驱动器上的实际数据。因此,我发现数据从某个地址开始(在我的例子中,它是从
VDI
文件开始的
0x00200000

然后,我基本上用模式
55aa
从该地址填充到
VDI
文件的末尾。所以,我想现在这意味着磁盘是可引导的(因为在第一个扇区的末尾仍然是signature
55aa

我启动了虚拟机,它说:

找不到可引导介质!系统停止

有什么办法解决这个问题吗?为什么我的虚拟磁盘仍然无法启动

编辑
这里是实际的
VDI
文件:

您没有提供一个最小的完整的可验证示例,以显示引导加载程序以及如何将其放入VDI。但至少需要在主引导记录的最后2个字节中放置0xAA55。下面的示例创建了一个简单的引导加载程序;创建2MiB原始图像;将引导加载程序放置在原始映像中;并将原始图像转换为VDI

boot.asm

BITS 16
ORG 0x7C00

    xor ax, ax
    mov ds, ax
    mov ss, ax       ; Stack below bootloader
    mov sp, 0x7c00

    mov ax, 0xb800   ; Video segment b800
    mov es, ax

    ; Print Hello with white on light magenta
    mov word [es:0x0], 0x57 << 8 | 'H'
    mov word [es:0x2], 0x57 << 8 | 'e'
    mov word [es:0x4], 0x57 << 8 | 'l'
    mov word [es:0x6], 0x57 << 8 | 'l'
    mov word [es:0x8], 0x57 << 8 | 'o'

    ; End with infinite loop
    cli
endloop:
    hlt
    jmp endloop

; Fill out to 510 bytes and add boot signature
times 510 - ($ - $$) db 0
dw 0xAA55            ; add boot signature at the end of bootloader
创建2MB磁盘映像文件
1.raw

dd if=/dev/zero of=1.raw bs=1024 count=2048
rm -f 1.vdi
VBoxManage convertfromraw 1.raw 1.vdi --format VDI
将引导加载程序
boot.bin
放在文件
1.raw的开头,而不截断文件的其余部分:

dd if=boot.bin of=1.raw conv=notrunc
1.raw
创建名为
1.VDI
的VDI映像:

dd if=/dev/zero of=1.raw bs=1024 count=2048
rm -f 1.vdi
VBoxManage convertfromraw 1.raw 1.vdi --format VDI
当添加到VirtualBox下的虚拟机时,我会在屏幕上看到:


您的VDI文件 在您提供的图像文件
1.vdi
中,我在执行
hextump
时注意到了这一点:

这个输出告诉我,您在文件中反转了启动签名的字节。它应该是0x55,后跟0xaa。0xaa55作为一个字存储,字节反转

有效的引导介质可能不仅仅是获得正确的引导签名。一些BIOS可能会在引导加载程序中通常找到的前几个字节中搜索某些指令。找不到此类指令(示例通常包括JMP、XOR、CLI、MOV等)可能会导致它认为它不是有效的引导介质

一种测试末尾的0xAA55本身是否足够的方法,我使用了hexedit并修改了
1.vdi
文件,如下所示:


我将
fa
作为引导加载程序的第一个字节。现在,当我使用您的映像时,错误是找不到可引导介质!系统停止不再显示。这表明VirtualBox正在寻找的不仅仅是引导签名,而且正在进行某种健全性检查,以确定引导加载程序的开始是否是可执行指令。这在生物科学中并不少见。有些人可能会做这样的检查,有些人可能不会。目前,我还没有查看VirtualBox的源代码,以确定它执行的确切检查

错误表示介质不可引导;它没有提到可安装性。你做了什么使你的中速启动?@BoundaryPosition。修正了打字错误。@BoundaryPosition。“您是如何使介质可引导的?”-我用pattern
55 AA
@Olaf填充了整个虚拟驱动器。谢谢您的编辑。@MichaelPetch:我认为您是对的-这种期望来自对“可启动”的含义的误解,或者至少是一种假设,即下一步将显示不同的错误消息。您是否有过这样的感觉:您一直在写相同的答案?:-)@科迪格雷:答案之间有相似之处,是的。在这种情况下,我不知道有一个关于虚拟盒和VDI格式的现有答案,所以我想我会抛出一个答案lol。说真的,考虑到这个编程任务似乎很流行,您可能只想将这个答案迁移到文档中,然后永久链接到它。只要他们强迫文档进入我们的喉咙,我们就可以想出如何使它有价值。或者,也许值得创建一个关于开始创建引导加载程序的规范问答,以及来自另一个答案的故障排除提示,然后我们可以将问题作为该问题的重复来解决。在你的回答中有很多很好的介绍性材料,但很难找到。@CodyGray我们中的一些人已经为其提供了文档。我同意你的意见;-)@CodyGray:一个规范的Q&A(为什么不给这个加上标签?)比试图把有用性强塞进文档更有价值。
00200000  aa 55 aa 55 aa 55 aa 55  aa 55 aa 55 aa 55 aa 55
00200010  aa 55 aa 55 aa 55 aa 55  aa 55 aa 55 aa 55 aa 55
*
002001f0  aa 55 aa 55 aa 55 aa 55  aa 55 aa 55 aa 55 55 aa <-- Corrected signature
                                                               at 1fe & 1ff
00200200  aa 55 aa 55 aa 55 aa 55  aa 55 aa 55 aa 55 aa 55
*
002004c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
*
00300000
           v-- CLI instruction
00200000  fa 55 aa 55 aa 55 aa 55  aa 55 aa 55 aa 55 aa 55
00200010  aa 55 aa 55 aa 55 aa 55  aa 55 aa 55 aa 55 aa 55
*
002001f0  aa 55 aa 55 aa 55 aa 55  aa 55 aa 55 aa 55 55 aa
00200200  aa 55 aa 55 aa 55 aa 55  aa 55 aa 55 aa 55 aa 55
*
002004c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
*
00300000