VirtualBox - 找不到可启动媒体

时间:2017-04-23 01:41:28

标签: x86 virtual-machine virtualbox bootloader osdev

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

我在汇编程序和C中创建一个操作系统。我发现我必须将C代码编译为二进制格式,提取文本部分并将其保存为文件,然后将其转换为ISO,然后将其挂载到虚拟光学潜水diskete然后在VirtualBox中加载我的操作系统。所以,这是我想避免的很多工作。我不希望每次都将我的二进制文件转换为ISO。

所以,我决定将我的操作系统的二进制机器代码放到虚拟硬盘驱动器(VDI文件)中,然后将其设置为启动顺序的顶部并加载它而不是从虚拟光驱{{ 1}}。

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

然后,我基本上从该地址填充到模式VDI的{​​{1}}文件的末尾。所以,我想它现在意味着磁盘是可引导的(因为在第一个扇区的末尾仍然是签名VDI)。

我启动了虚拟机,它说:

  

找不到可启动媒体!系统暂停

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

修改

以下是实际的55 AA文件:1.vdi

1 个答案:

答案 0 :(得分:6)

您没有提供一个最小的完整可验证示例,显示引导加载程序以及如何将其引入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

然后我使用此命令创建引导加载程序文件boot.bin

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

创建2MiB磁盘映像文件1.raw

dd if=/dev/zero of=1.raw bs=1024 count=2048

将引导加载程序boot.bin放在文件1.raw的开头,而不截断文件的其余部分:

dd if=boot.bin of=1.raw conv=notrunc

1.vdi创建名为1.raw的VDI图像:

rm -f 1.vdi
VBoxManage convertfromraw 1.raw 1.vdi --format VDI

当添加到VirtualBox下的虚拟机时,我在显示屏上显示:

enter image description here

您的VDI文件

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

00200000  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

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

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

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

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

单独运行此更改并不起作用。然后我使用了hexedit并将CLI操作码(0xFA)作为扇区的第一个字节。生成的文件现在看起来像:

           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

我已将fa作为引导加载程序中的第一个字节。现在,当我使用您的图像时,错误找不到可启动媒体!系统暂停不再出现。这表明VirtualBox正在寻找的不仅仅是一个启动签名,并且正在进行某种健全性检查,以确定启动加载程序的启动是否似乎是可执行指令。这对于BIOS来说并不罕见。有些人可能会做这样的检查,有些人可能不会。此时,我还没有查看VirtualBox源代码,以确定它执行的确切检查。