作者:252575936_8ea84a | 来源:互联网 | 2023-02-05 19:59
关于标题类似的stackoverflow有很多问题。我读了所有这些文章,但没有一个回答我的问题。这就是为什么我打开这个问题。
我正在用汇编器和C创建一个操作系统。我发现必须将C代码编译为二进制格式,提取文本部分并将其保存为文件,然后将其转换为ISO,然后将其安装到diskete的虚拟光驱中,然后在VirtualBox中加载我的操作系统。因此,这是我要避免的许多工作。我不想每次都将二进制文件转换为ISO。
因此,我决定将操作系统的二进制计算机代码放入虚拟硬盘驱动器(VDI
文件),然后将其设置为引导顺序的顶部并加载,而不是从虚拟光盘驱动器加载ISO
。
我正在研究VDI
工作原理,发现它通常是按名称分配的,并且只存储数据的开头。因此,的开头VDI
代表标题,其余的代表存储在虚拟驱动器上的实际数据。因此,我发现数据从某个地址开始(就我而言,它是0x00200000
从VDI
文件的开头开始)。
然后,我基本上VDI
使用pattern 从该地址填充到文件末尾55 AA
。因此,我想它现在意味着磁盘是可引导的(因为第一个扇区的末尾仍是签名55 AA
)。
我启动了虚拟机,它说:
找不到可启动媒体!系统停止
有什么办法解决这个问题?为什么我的虚拟磁盘仍然无法启动?
编辑
这是实际的VDI
文件:1.vdi
1> Michael Petc..:
您没有提供一个最小的完整可验证示例,其中显示了引导加载程序以及如何将其装入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
然后,我使用以下命令创建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
来自的VDI映像1.raw
:
rm -f 1.vdi
VBoxManage convertfromraw 1.raw 1.vdi --format VDI
当添加到VirtualBox下的虚拟机时,我在显示屏上看到了这一点:
您的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
将引导加载程序放置为int的第一个字节。现在,当我使用您的映像时,出现错误:找不到可启动媒体!系统停止不再出现。这表明VirtualBox不仅在寻找引导签名,而且还在进行某种健全性检查,以确定引导加载程序的启动是否似乎是可执行指令。这在BIOS中并不罕见。有些人可能会做这样的检查,有些人则不会。目前,我还没有查看VirtualBox源代码来确定其执行的确切检查。