首页 文章

无法在磁盘上保存引导扇区并在磁盘上运行OS然后将其加载到内存中

提问于
浏览
1

背景资料

我正在开发一个简单的DOS操作系统 . 所以我不打算很快进入保护模式 . 操作系统将以汇编语言编写;顺便说一句NASM语法 . 引导扇区应该将引导扇区保存在硬盘的第一个扇区上,OS代码保存在第二个扇区上 . 这样它就可以从硬盘启动,而不是从CD映像启动 .

问题

问题是启动扇区似乎可以在硬盘上正确保存所有内容 . 但是当我重新启动VMware Player并弹出虚拟CD-ROM时 . 它引导背景绿色(图1.1) . 这只能意味着引导扇区没有加载地址0x7e00的第二个扇区,并且无法跳转 . 奇怪的是进位标志没有被设置,所以我假设没有发生错误 . 所以基本上当我从CD-ROM映像启动时,它会显示一切正常(如图1.2) . 但是当我重新启动并从硬盘启动时,它无法跳转到应该在0x7e00加载的操作系统 . 引导扇区加载为0x7c00 . 我假设我的段地址是正确的,也许我的偏移地址不正确,或者我的磁盘写入和读取是完全错误的?

操作系统已成功完成的事情

  • 以软件中断的形式进行基本系统调用 . 修改了IVT(中断向量表)

  • 在主硬盘上加载引导扇区,BIOS可以将引导扇区从硬盘加载到内存位置0x7c00

可能导致问题的准则

Here is the boot.asm code:

[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

Here is the 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

Here is the script build.bat code:

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

Post Script

中断21h,22h,23h,24h,25h,26h是我为我的操作系统编写的自定义软件中断 . 如果您有任何疑问或需要更多代码或信息,我将在此提供更多信息 .

解决方案

对于那些关心的人,我通过在VirtualBox创建的VHD中编写img.bin并从VHD启动来解决它 . 所以它就像一个魅力 . 顺便说一下,我使用了十六进制编辑器 .

Figure 1.1
Figure 1.1

Figure 1.2
Figure 1.2

1 回答

  • 1

    好的,你原谅了 . 没有人知道这个东西!

    回到它工作的时候(你的图1.2),你"must have"从你的CD映像读取扇区2到0x7E00 - 类似于你在bootsector末尾所做的,只来自不同的驱动器( dl ) . 我猜测BIOS认为CD映像是驱动器0.启动驱动器号应该在 dl 中,所以你可能可以不管它(尽管使 dh 0) . 执行此操作后,您可以从0x7C00写入硬盘驱动器(驱动器80h)扇区1,从0x7E00写入驱动器80h扇区2 - 就像您正在做的那样 . 但是每次启动时你真的想要这样做吗?

    将boot.bin和os.bin复制到img.bin之后我会做的是将img.bin写入硬盘驱动器... John Fine的 partcopy 如果你能找到它,或 rawwrite ,或者 dd 的端口(一个Unix实用程序) . 或者你可以用DEBUG来做 . 或者写一个小程序来做这件事并不难 . 然后你应该能够从硬盘启动,完全跳过iso和CD映像 .

    BIOS将扇区1加载到0x7C00,但之后由引导代码将扇区2加载到0x7E00并跳转到它...或者将其写入硬盘驱动器,将其读回并跳转到它,但这似乎没有意义这在每次启动时 .

    随着操作系统的增长,它将占用多个扇区,因此您需要读取多个扇区 . 如果您的代码正常工作,但是当您再添加一个函数时崩溃,这可能就是正在发生的事情 . 轻松修复 - 只需关注os.bin的大小,并在超过512字节时读取更多扇区 .

    Minor nit:如果您的错误消息被打印出来,那么您将"fall through"尝试执行该消息并打开"into the woods" . 打印后放置 hang: jmp hang 以捕获它 . 你那里没有"code" . 我认为_2907411正在发生......

    有一点需要注意:Bios总是认为它启动的硬盘是“驱动80h” . 如果从其他驱动器启动,则要编写启动器和操作系统的驱动器可能驱动81h或82h或??? . 小心!

相关问题