簡體   English   中英

將啟動扇區保存在磁盤上,將操作系統保存在磁盤上,然后將其加載到內存中

[英]Having Trouble Saving Boot Sector On Disk And OS On Disk Then Loading It In Memory

背景資料

我正在開發一個像OS這樣的簡單DOS。 因此,我不打算很快進入保護模式。 操作系統將以匯編形式編寫; 順便說一下NASM語法。 引導扇區應該將引導扇區保存在硬盤的第一個扇區中,而OS的代碼保存在第二個扇區中。 這樣它就可以從硬盤引導,而不是從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.1

圖1.2 圖1.2

好的,你很抱歉。 沒有人知道這東西!

回到它工作的時候(您的圖1.2),您“必須”將CD映像中的扇區2讀取到0x7E00-類似於在引導扇區末尾所做的操作,僅從另一個驅動器( dl )中讀取。 我猜測BIOS認為CD映像是驅動器0。引導驅動器號應該在dl ,因此您可以dl會它(盡管將dh 0)。 完成此操作后,您可能會從0x7C00寫入硬盤驅動器(80h驅動器)扇區1,而從0x7E00寫入80h扇區2驅動器-正如您所做的那樣。 但是,您真的要在每次啟動時都這樣做嗎?

將boot.bin和os.bin復制到img.bin之后,我要做的是使用... John Fine的partcopy將img.bin寫入硬盤驅動器,如果可以找到它,或者rawwrite ,或者一個dd端口( Unix實用程序)。 或者,您也可以使用DEBUG。 或編寫一個小的程序來完成它並不難。 然后,您應該能夠從硬盤啟動,完全跳過iso和CD映像。

BIOS將扇區1加載到0x7C00,但是此后由啟動代碼將扇區2加載到0x7E00並跳轉到它...或將其寫入硬盤驅動器,再讀回並跳轉到它,但是這樣做似乎毫無意義。每次開機都可以。

隨着您的操作系統的增長,它將占用多個扇區,因此您需要讀取多個扇區。 如果您的代碼可以正常工作,但是在添加其他功能時崩潰,則可能是這種情況。 易於修復-只需關注os.bin的大小,並在超過512字節時讀取更多扇區。

次要提示:如果您的錯誤消息被打印,則您將“跌倒”以嘗試執行該消息,然后繼續“進入樹林”。 hang: jmp hang打印后掛住hang: jmp hang它。 您沒有收到錯誤(進位標志),因為您的代碼很高興將0x7E00寫入磁盤並回讀,即使那里沒有“代碼”。 我認為就是這樣

需要注意的一件事:Bios始終認為從其引導的硬盤驅動器是“ drive 80h”。 如果從其他驅動器啟動,則要將引導程序和操作系統寫入的驅動器可能是81h或82h或???。 小心!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM