ali*_*ali 5 assembly osdev sector hard-drive x86-16
作为世界上任何一个程序员,至少有一次他/她一生都在尝试创建自己的“革命性”,新的,唯一的操作系统。:D
好吧,我正在使用一个虚拟仿真器(Oracle VM Virtual Box),为此我创建了一个带有vmdk磁盘的新的unknwon操作系统。我喜欢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
Run Code Online (Sandbox Code Playgroud)
在这里,我检查了CF后收到错误消息。但是,如果我使用INT 13,则获取最后的状态消息时,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
Run Code Online (Sandbox Code Playgroud)因此,这就是我尝试将内核添加到第二个扇区的方法。您认为这有什么问题?谢谢!
更新
好的,我现在没有任何错误,但是看不到正在执行的已加载代码。它应该在窗口上显示一个点:
;--------------------------------------------
; '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
Run Code Online (Sandbox Code Playgroud)
一个问题在这里:
jmp [es:bx]
Run Code Online (Sandbox Code Playgroud)
实际上,这将从寄存器es(段部分)和bx(偏移部分)中包含的地址处的存储位置读取一个地址,即16位偏移量,然后将其设置ip为该16位偏移量。
您可能要使用的是:
jmp some_constant1:some_constant2
Run Code Online (Sandbox Code Playgroud)
这将设置cs到some_constant1和ip到some_constant2。毫不奇怪,这两个常量的分别为0x8000和0,因为这是加载代码的位置。
现在,第二个问题在这里:
[org 0x8000]
Run Code Online (Sandbox Code Playgroud)
这org告诉NASM以这样的方式生成代码:如果将其加载到偏移量0x8000,它将可以工作。现在,偏移量0x8000与段0x8000不同。如果使用jmp 0x8000:0,则还应该使用:
[org 0]
Run Code Online (Sandbox Code Playgroud)