汇编 - 读取虚拟磁盘的下一个扇区

时间:2012-06-17 20:18:31

标签: assembly virtual hard-drive osdev sector

作为世界上任何一位程序员,至少有一次在他/她的生活中,我正在努力创造我的“革命性”,新的和唯一的操作系统。 :d

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

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

我有两个问题:

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

    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
    

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

更新

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

;--------------------------------------------
; '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

3 个答案:

答案 0 :(得分:3)

这里有一个问题:

jmp [es:bx]

这将从寄存器es(段部分)和bx(偏移部分)中包含的地址的存储单元读取地址,即16位偏移量,然后将ip设置为该16位偏移量。

您可能想要使用的是:

jmp some_constant1:some_constant2

这会将cs设置为some_constant1,将ip设置为some_constant2。不出所料,这两个常量的良好候选者分别为0x8000和0,因为这是代码加载的位置。

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

[org 0x8000]

这个org告诉NASM生成代码,如果在偏移0x8000处加载它将起作用。现在,偏移量0x8000与段0x8000不同。如果您使用jmp 0x8000:0,那么您还应该使用:

[org 0]

答案 1 :(得分:1)

失败后再试一次。我认为当磁盘旋转时,您将收到错误指示而没有消息,因此仿真器可能会故意第一次失败。在bochs和qemu中,四次尝试对我来说都很有效,但我还没有尝试过任何其他事情。您可能还希望在读取之前重置驱动器控制器以清除以前的任何错误。使用al清除中断0x13和dl中的驱动器号。


注意:硬编码驱动器号可能现在可以使用,但不允许您支持从其他驱动器启动。启动引导加载程序时,BIOS应将驱动器号保留在dl,以便保存。

答案 2 :(得分:1)

我在http://forum.osdev.org/viewtopic.php?f=1&t=25463&start=0

解决了这个问题

谢谢!