stackoverflow 上有很多类似标题的问题。我阅读了所有这些,但没有一个能回答我的问题。这就是我打开这个问题的原因。

我正在用汇编器和C创建操作系统。我发现我必须将C代码编译为二进制格式,提取文本部分并将其保存为文件,然后将其转换为ISO,然后将其安装到磁盘的虚拟光驱中,然后在 VirtualBox 中加载我的操作系统。所以,这是我想避免的很多工作。我不想每次都将我的二进制文件转换为 ISO。

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

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

然后,我基本上从那个地址填充到 VDI 文件的末尾,使用模式 55 AA 。所以,我想现在这意味着磁盘是可启动的(因为在第一个扇区的末尾仍然是签名 55 AA )。

我启动了虚拟机,它说:



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

编辑

这是实际的 VDI 文件:1.vdi

最佳答案

您没有提供显示引导加载程序以及如何将其放入 VDI 的最小完整可验证示例。但至少您需要将 0xAA55 放在主引导记录的最后 2 个字节中。下面的示例创建了一个简单的引导加载程序;创建一个 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 下的虚拟机时,我会在显示屏上看到:

x86 - VirtualBox - 找不到可启动媒体-LMLPHP

您的 VDI 文件

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



此输出向我表明您反转了文件中引导签名的字节。它应该是 0x55 后跟 0xaa。 0xaa55 作为 WORD 存储,字节颠倒。

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

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



仅凭该更改运行是行不通的。然后我使用了 hexedit 并放置了一个 CLI 操作码(0xFA)作为扇区的第一个字节。生成的文件现在看起来像:



我已将 fa 作为引导加载程序的第一个字节。现在,当我使用您的图像时出现错误 No bootable medium found!系统停止不再出现。这表明 VirtualBox 正在寻找的不仅仅是引导签名,而是在进行某种完整性检查以确定引导加载程序的开始是否是可执行指令。这对于 BIOS 来说并不少见。有些人可能会做这样的检查,有些人可能不会。目前我还没有查看 VirtualBox 源代码来确定它为做出决定而执行的确切检查。

关于x86 - VirtualBox - 找不到可启动媒体,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43566542/

10-11 18:53