2013-08-16 72 views
2

我正在爲我的定製內核編寫引導程序,它(引導程序)基於Linux內核v0.1 boot.s。下面是代碼:HLT指令無hlt

.set BOOTSEG, 0x7c0 
.set LOADSEG, 0x9000 
.set SYSSEG, 0x1000 

start: 
//copy the WHOLE bootloader to new location 
movw BOOTSEG, %ax 
movw %ax, %ds 
xor  %si, %si 
movw LOADSEG, %ax 
movw %ax, %es 
xor  %di, %di 
movw 256, %cx 
rep  movsw 

//jump to new location 
cli 
movw LOADSEG, %ax 
movw %ax, %es 
ljmp $LOADSEG, $loaded 

loaded: 
// ... 

movw $0x3, %ax 
int $0x10 

// ... 

當我試圖跳轉到新位置的Bochs寫道:WARNING: HLT instrucion with IF=0,但目前還沒有hlt指令都在我的代碼。跳Bochs繼續運行後,但無法正常工作,例如:int $0x10未清除屏幕。

可能是我複製的bootloader出錯了,但是它類似於Linux。

那麼,有人可以幫我解決這個問題嗎?

+0

'cat boot.S | grep hlt'不返回任何內容? – Benoit

+0

它對我的引導加載程序和Linux也不會​​返回任何結果。 – Vanzef

+0

'movw 256,%cx' - 不應該有'$'嗎?可能還有其他地方呢? –

回答

3

Bochs說你的IF(中斷標誌,允許的inerrupt)是0,所以這個問題一定在你的跳遠。你必須確保

    代碼後 loaded
  1. 標籤不包含任何hlt說明
  2. 你已經爲您正確loaded標籤偏移(檢查你使用compilator或鏈接器設置)

根據到你的osdev post,你試圖將GDT的段選擇器關聯到段寄存器。如果在實模式下執行,則段寄存器的值不會用於獲取GDT條目,但它們將被移位並添加到標準實模式段的偏移量。我敢打賭,如果您註釋掉(或刪除)將代碼段設置爲GDT條目的代碼,那麼一切都將起作用。嘗試一下。

它應該工作的原因很簡單:將您的CS段從LOADSEG更改爲0x8,實際模式的實際移動位置爲IVT空間。

如果你想使用GDT,你必須首先跳轉到保護模式。 您可以在Brokenthorn.com上的well written tutorials中找到關於此主題的更多信息。

+0

好的,我再次檢查代碼,我確定沒有'hlt'指令。我使用'yasm'作爲具有'-f bin'標誌的彙編器,並且不使用鏈接器,所以我必須更改哪些設置?這是完整的代碼(是的,加載後不正確,但在它之前發生錯誤)[code,pastebin](http://pastebin.com/8dFk8MPx) – Vanzef

+0

刪除第28-31行(含)。 – user35443

+0

而你'jmp'重新啓動,所以'loaded'標籤將無法到達。 – user35443