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 下的虚拟机时,我会在显示屏上看到:
您的 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/