背景资料
我正在开发一个类似 OS 的简单 DOS。所以我不打算很快进入保护模式。操作系统将以汇编语言编写;顺便说一句,NASM 语法。引导扇区应该将引导扇区保存在硬盘的第一个扇区,并将操作系统代码保存在第二个扇区。这样它就可以从硬盘启动,而不是从 CD 映像启动。
问题
问题是引导扇区似乎将所有内容正确保存在硬盘上。但是当我重新启动 VMware Player 并弹出虚拟 CD-ROM 时。它引导背景为绿色(图 1.1)。这只能意味着引导扇区没有加载地址 0x7e00 处的第二个扇区,并且无法跳转。奇怪的是没有设置进位标志,所以我假设没有发生错误。所以基本上当我从 CD-ROM 映像启动时,它会显示一切正常,如图 1.2 所示。但是当我重新启动并从硬盘启动时,它无法跳转到应该在 0x7e00 加载的操作系统。引导扇区在 0x7c00 加载。我假设我的段地址是正确的,也许我的偏移地址不正确,或者我的磁盘写入和读取完全错误?
操作系统成功完成的事情
软件中断形式的基本系统调用。修改了 IVT(中断向量表)
在主硬盘上加载引导扇区,BIOS可以将引导扇区从硬盘加载到内存位置0x7c00
可能导致问题的代码
这是 boot.asm 代码:
[ORG 0x7c00] ; BIOS loads at 0x7c00 in memory
jmp start
%include "C:\Users\OSDEV\OS-SRC\MonsterOS\source\syscalls\syscalls.inc"
start:
xor ax, ax ; make it zero
mov ds, ax ; Data segment is zero
;Set desired video mode (Graphics Mode)
mov ah, 0
mov al, 12h
int 10h
call init_int
;Set desired background color (Green)
mov ah, 0x0b
mov bh, 0
mov bl, 2
int 10h
; Display Box Shaped Cursor
mov ch, 0
mov cl, 7
mov ah, 1
int 10h
;Save BootLoader on the DISK
xor ax, ax
mov es, ax ; ES <- 0
mov cx, 1 ; cylinder 0, sector 1
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk)
mov bx, 7c00h ; segment offset of the buffer
mov ax, 0301h ; AH = 03 (disk write), AL = 01 (number of sectors to write)
int 13h
;Save OS on the DISK
xor ax, ax
mov es, ax ; ES <- 0
mov cx, 2 ; cylinder 0, sector 2
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk)
mov bx, 7e00h ; segment offset of the buffer
mov ax, 0301h ; AH = 03 (disk write), AL = 01 (number of sectors to write)
int 13h
;Load OS from DISK at 0x7e00
xor ax, ax
mov es, ax ; ES <- 0
mov cx, 2 ; cylinder 0, sector 2
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk)
mov bx, 7e00h ; segment offset of the buffer
mov ax, 0201h ; AH = 02 (disk read), AL = 01 (number of sectors to read)
int 13h
jc err
jmp 0h:0x7e00 ; Jump To OS
err:
mov ax, err_msg
mov bh, 0
mov bl, 0xf
int 21h ; Print error message
err_msg: db 'Error Failed To Load OS From Disk!', 0
times 510-($-$$) db 0
db 0x55
db 0xAA
这是os.asm:
[ORG 0x7e00]
xor ax, ax ; make it zero
mov ds, ax ; Data segment is zero
mov es, ax
; Clear Screen
int 27h
;Set desired background color (Green)
mov ah, 0x0b
mov bh, 0
mov bl, 2
int 0x10
; Display Box Shaped Cursor
mov cx, 0607h
mov ah, 1
int 10h
; Print Desired Message
mov ax, msg
mov bh, 0
mov bl, 0xf
int 21h
int 23h ; Print newline
hang:
mov ax, buffer
int 25h ; SIZE(buffer)
mov ax, buffer
int 24h ;ZERO(buffer)
; Print Desired Message
mov ax, cli_msg
mov bh, 0
mov bl, 0xf
int 21h ; print ax=msg bl=blue
; Get Input
mov bx, buffer
int 22h ; Read From Keyboard And Print The String With Line Feed
; ECHO String Stored At The Address Buffer
mov ax, buffer
mov bh, 0
mov bl, 0xf
int 21h ;
int 23h ; Print newline
jmp hang
msg: db 'Welcome To MonsterOS!', 0
cli_msg: db 'MonsterOS> ', 0
buffer: times 64 db 0
这是脚本 build.bat 代码:
nasm -f bin C:\Users\OSDEV\OS-SRC\MonsterOS\source\boot.asm -o C:\Users\OSDEV\OS-SRC\MonsterOS\bin\boot.bin
nasm -f bin C:\Users\OSDEV\OS-SRC\MonsterOS\source\os.asm -o C:\Users\OSDEV\OS-SRC\MonsterOS\bin\os.bin
copy /b C:\Users\OSDEV\OS-SRC\MonsterOS\bin\boot.bin + C:\Users\OSDEV\OS-SRC\MonsterOS\bin\os.bin C:\Users\OSDEV\OS-SRC\MonsterOS\bin\img.bin
miso C:\Users\OSDEV\OS-SRC\MonsterOS\bin\os.iso -ab C:\Users\OSDEV\OS-SRC\MonsterOS\bin\img.bin
后期脚本
中断 21h、22h、23h、24h、25h、26h 是我为我的操作系统编写的自定义软件中断。如果您还有任何问题或需要更多代码或信息,我在这里提供更多信息。
解决方案
对于那些关心的人,我通过在 VirtualBox 创建并从 VHD 引导的 VHD 中编写 img.bin 来解决它。所以它就像一个魅力。顺便说一句,我使用了十六进制编辑器。
图 1.1
图 1.2