4

作为世界上至少有一次在他/她的生活中的程序员,我正在尝试创建我的“革命性”,新的和唯一的操作系统。:D

好吧,我正在使用一个虚拟模拟器(Oracle VM Virtual Box),为此我创建了一个新的未知操作系统,带有一个 vmdk 磁盘。我喜欢 vmdk 因为它们只是普通文件,所以我可以将引导加载程序粘贴到虚拟硬盘的前 512 个字节上。

现在,我正在尝试读取该虚拟磁盘的下一个扇区,我将在该扇区上粘贴一个显示消息的简单内核。

我有两个问题:

  • 我是否正确读取了第二段(前 -512 字节 - 被引导加载程序占用)? 代码:

    ReadDisk:
        mov bx, 0x8000  ; segment
        mov es, bx
        mov bx, 0x0000  ; offset
    
        mov ah, 0x02  ; read function
        mov al, 0x01  ; sectors - this might be wrong, trying to read from hd
        mov ch, 0x00  ; cylinder
        mov cl, 0x02  ; sector
        mov dh, 0x00  ; head
        mov dl, 0x80  ; drive - trying to read from hd
        int 0x13   ; disk int
        jc ReadDisk
        jmp [es:bx]   ; buffer
    

    在这里,我在检查 CF 后收到错误消息。但是,如果我使用 INT 13, 1 来获取最后一条状态消息,则 AL 为 0 - 因此不会保存任何错误。

  • 我是否将我的简单内核粘贴到 vmdk 内的正确位置?我所做的是将它粘贴在文件的第 512 个字节之后,正如我所说,前 512 个字节是引导加载程序。该文件如下所示:

    BE 45 7C E8 16 00 EB FE B4 0E B7 00 B3 07 CD 10 <- First sector
    C3 AC 08 C0 74 05 E8 EF FF EB F6 C3 B4 00 B2 80
    CD 13 BE 5D 7C 72 F5 BB 00 80 8E C3 BB 00 00 B4 
    02 B0 06 B5 00 B1 01 B6 00 B2 07 CD 13 BE 4E 7C 
    72 CF 26 FF 27 57 65 6C 63 6F 6D 65 21 00 52 65 
    61 64 69 6E 67 20 65 72 72 6F 72 21 00 52 65 73 
    65 74 74 69 6E 67 20 65 72 72 6F 72 21 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA <- Boot-loader signature
    B4 0E B0 2E CD 10 EB FE 00 00 00 00 00 00 00 00 <- Start of the second sector
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    

所以,这就是我试图将内核添加到第二个扇区的方式。你认为这有什么问题?谢谢!

更新

好的,我现在没有收到任何错误,但我没有看到正在执行的加载代码。它应该在窗口上显示一个点:

;--------------------------------------------
; 'load.asm'
; loaded from 'boot.asm'

[org 0x8000]
[bits 16]

;--------------------------------------------

main:
mov ah, 0x0E  ; print function
mov al, '.'   ; ascii char
int 0x10   ; IO int

jmp $    ; hang
4

2 回答 2

6

这里有一个问题:

jmp [es:bx]

这将读取一个地址,一个 16 位偏移量,实际上是从包含在寄存器es(段部分)和bx(偏移量部分)中的地址处的内存位置开始,然后设置ip为该 16 位偏移量。

您可能想要使用的是:

jmp some_constant1:some_constant2

这将设置cssome_constant1和。不出所料,这两个常量的好候选分别是 0x8000 和 0,因为这是加载代码的位置。ipsome_constant2

现在,第二个问题在这里:

[org 0x8000]

org告诉 NASM 以这样一种方式生成代码,即如果在偏移量 0x8000 处加载它就可以工作。现在,偏移量 0x8000 与段 0x8000 不同。如果您使用jmp 0x8000:0,那么您还应该使用:

[org 0]
于 2012-06-21T09:56:04.580 回答
1

失败后重试。我认为当磁盘旋转时您会收到没有消息的错误指示,因此模拟器可能会在第一次故意失败。在 bochs 和 qemu 中,四次尝试对我来说效果很好,但我没有在其他任何东西上尝试过。您可能还需要在读取之前重置驱动控制器以清除任何先前的错误。使用带有al清除的中断 0x13 和中的驱动器号dl


注意:对驱动器编号进行硬编码目前可能有效,但不支持从其他驱动器启动。启动引导加载程序时, BIOS 应保留驱动器号dl,以便您保存。

于 2012-06-17T21:33:41.203 回答