2013-05-04 46 views
1

背景信息

我正在開發一個簡單的DOS操作系統。所以我不打算很快進入保護模式。操作系統將以彙編形式編寫;順便說一句,NASM語法。引導扇區應該將引導扇區保存在硬盤的第一個扇區上,並在第二扇區上保存OS的代碼。以便它可以從硬盤啓動,而不是從CD映像啓動。無法保存磁盤上的引導扇區和磁盤上的操作系統然後將其加載到內存中

The Issue

問題是引導扇區似乎在硬盤上正確保存了一切。但是當我重新啓動VMware Player時,彈出虛擬光盤。它啓動一個背景綠色(圖1.1)。這隻能意味着引導扇區不會加載地址爲0x7e00的第二個扇區,並且無法跳轉。奇怪的是進位標誌沒有被設置,所以我假設沒有錯誤發生。所以基本上,當我從CD-ROM映像啓動時,它顯示了一切正常(圖1.2)。但是當我重新啓動並從硬盤啓動時,它無法跳轉到應該在0x7e00加載的操作系統。引導扇區在0x7c00加載。我假設我的網段地址是正確的,也許我的偏移地址不正確,或者我的磁盤寫入和讀取完全錯誤?

事情是,OS圓滿完成

  • 基本系統軟件的中斷調用的形式。改性的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 Figure 1.1

圖1。2 Figure 1.2

+0

不清楚0x7E00處的「OS」來自何處。 BIOS會將您的啓動扇區加載到0x7C00,然後將其寫入硬盤(在引導扇區中做一件奇怪的事情)。然後,您將0x7E00寫入硬盤並讀回來......但是,首先如何獲得0x7E00? – 2013-05-05 03:54:42

+0

那麼我沒有顯示整個代碼,可能是你的困惑的原因。然後你又可能是對的。我在我的問題中發佈了更多代碼。 – 2013-05-05 14:21:37

+0

@FrankKotler嗯,我想從硬盤啓動,而不是CD映像。我對操作系統開發很陌生,所以如果我沒有正確地做事,請原諒我。 :D – 2013-05-05 14:24:41

回答

1

好的,你可以原諒。沒有人知道這件事!回到它工作的狀態(圖1.2),你必須從你的CD映像讀取扇區2到0x7E00--類似於你在引導扇區末尾做的操作,只能從另一個驅動器中讀取(dl )。我猜測BIOS認爲CD映像是驅動器0.啓動驅動器號應該在dl,所以你可能可以保持獨立(使dh 0)。完成此操作後,您可能會從0x7C00寫入硬盤驅動器(驅動器80h)扇區1,並從0x7E00寫入驅動器80h扇區2 - 正如您所做的那樣。但是,每次開機時你真的想這麼做嗎?

我會做什麼,複製BOOT.BIN和os.bin到img.bin後,是用寫img.bin到硬盤驅動器...約翰精細的partcopy如果你能找到,或rawwrite,或dd(Unix工具)的端口。或者你可以用DEBUG來完成。或者自己寫一個小程序來做它並不難。然後,您應該能夠從硬盤啓動,完全跳過iso和CD映像。

BIOS將扇區1加載到0x7C00,但在此之後,它的啓動代碼會將扇區2加載到0x7E00並跳轉到它或者將其寫入硬盤驅動器,然後將其讀回硬盤驅動器,但是它似乎毫無意義地在每次啓動時都這樣做。

隨着您的操作系統的增長,它將佔用多個扇區,所以您需要讀取多個扇區。如果你的代碼正在工作,但是當你添加一個函數時會崩潰,這可能是發生了什麼事情。容易修復 - 只需注意os.bin的大小,並在超過512字節時讀取更多扇區。

小問題:如果你的錯誤信息被打印出來,你就會「墮落」,試圖執行這條消息並進入「進入樹林」。打印後放上hang: jmp hang即可。您沒有收到錯誤(攜帶標誌),因爲您的代碼很高興地將0x7E00寫入磁盤並將其讀回,即使這裏沒有「代碼」。我認爲這就是發生了什麼...

有一點要注意:Bios總是認爲它啓動的硬盤驅動器是「驅動器80h」。如果你從其他驅動器啓動,你想要寫入啓動扇區和操作系統的驅動器可能是驅動器81h或82h或???。小心!

+0

感謝它幫助了我很多。順便說一句,我在Windows 8上這樣做,因爲我的機器不能運行PartCopy,因爲我的機器是64位機器。你推薦什麼替代方案?我會標記你的答案。 – 2013-05-05 20:09:12

+0

我既沒有Windows也沒有運行64位,所以我不知道PartCopy的一個很好的選擇。也許有一個適用於64位Windows的RawWrite版本?如果一切都失敗了,那麼你在那裏會有「幾乎」這樣做的代碼。添加代碼首先從CD映像中讀取並寫入硬盤驅動器?然後扔掉這個「自定義」的啓動扇區並寫一個「常規」的啓動扇區?更好的辦法是找到能在Win64上完成的事情,我想呢? – 2013-05-05 22:10:13

+0

好的,謝謝,沒問題。 – 2013-05-05 22:13:01