上次說到了
將控制權交給核心,接下來的工作都由核心來完成。從這裡開始,就可以用c語言來寫了。(為什麼?我還是不明白)但並不是核心全用c寫,它依舊需要乙個用彙編寫得開頭,讓loader跳入進來。
跳進來後需要立即做一件事:切換堆疊。因為原來的堆疊在記憶體中的位置是在loader中,而將來loader是會被我們覆蓋的,所以必須切換。設好堆疊也是呼叫c函式的前提條件。這裡說一下,所謂的堆疊只是一段連續的記憶體,你分配好記憶體後,只要將這段記憶體的最高位址賦給esp(還有段暫存器ss也要相應處理),那這段記憶體就是當前所用的堆疊了。
接著要切換gdt,就是把就的gdt複製到自己希望的記憶體位址中,可以用c語言完成。注意! 在使用 c **的時候一定要保證 ds, es, ss 這幾個段暫存器的值是一樣的,因為編譯器預設它們是一樣的。(這裡又想到了平坦記憶體模型的問題。這種模型有什麼優勢或者好處?對於系統保護有什麼意義?問題還有好多)把gdt放在什麼位置也是需要考慮的,因為這張gdt在今後一直需要用到,不能被其他內容所覆蓋,所以需要考慮記憶體的布局。
接著是初始化中斷處理,包括設定8259a和idt。idt有256項,但並不需要全部都初始化。接著就是中斷處理函式(需要用彙編寫,中間可以呼叫c函式)。好了之後載入idt。這都挺簡單的。這些好了之後,如果因為**編寫出現問題而導致異常,系統就不會自動崩潰,而是呼叫相應中斷處理函式(我碰到的最多的就是#gp,主要是跳轉位址錯誤……尤其是中斷返回的時候)。
接下來講的是程序。感覺書中只是對程序在核心中的表現形式做了介紹。每個程序需要乙個ldt來支援,這很簡單,和gdt一樣,就不多說了。重點主要是程序的中斷和切換的原理。程序要能在被中斷後恢復,就需要把在程序中斷前一刻的所有暫存器值全儲存下來,在恢復時只要把全部暫存器值還原,程序就可以像什麼都沒發生過一樣繼續執行。
如何儲存?我們知道在中斷發生時,會把返回位址和標誌暫存器壓棧,同時由於特權級轉換,還會把原ss和esp壓棧,然後切換堆疊(tss)。所以需要模擬乙個堆疊的資料結構(程序表),來存放所有暫存器的值(cs和eip是不能用push壓棧的),然後在中斷產生前,設定好tss中的esp0值,指向該結構的頂端。中斷程式中則push相應暫存器(由於目前esp是取得tss中esp0的值,所以暫存器被壓進了程序表中儲存起來),然後切換到核心棧。
而切換程序則是在中斷結束前,重新設定好esp0(指向目標程序表的頂端,為下次中斷準備)和當前esp值(指向目標程序的程序表底端),然後恢復相應暫存器,中斷返回即可,這樣所有暫存器都被還原,esp也被切換到了目標程序執行時的堆疊。
這挺複雜的,需要多多體會。
有個問題是,上面的實現都必須要有特權級切換,才能切換堆疊,完成我們的任務。這是不是說不發生特權級切換的話就不能進 行程序切換的工作?還是有什麼別的方法?
編寫中斷程式也是一件很藝術的事,說不清,需要多看**,才能體會。其實對中斷,我還有許多的不了解,比如中斷重入。控制是否接收中斷的條件有,1:eflags中的中斷遮蔽標誌位,用sti和cli控制,2:8259a中的eoi,3:8259a中的遮蔽暫存器。3不是在中斷程式中控制的,不與討論。中斷發生後,我們需要重置eoi,才能使8259a繼續接受後面的中斷。8259a中還有乙個暫存器,儲存還未處理的中斷。我還沒看過詳細的資料,所以接下來的純屬猜測。當有中斷產生,8259a先看自己的中斷遮蔽暫存器,如果中斷沒有被遮蔽,則放入中斷服務暫存器。8259a會檢查eoi位,如果是1則表示cpu正在處理中斷,不做任何事情,如果為0且中斷服務暫存器中有中斷,則傳送中斷請求。而cpu會按照eflags的標誌予以處理和拋棄。
進入中斷後硬體會自動關閉中斷標誌,所以如果允許中斷重入,需要sti。我們還需要重置eoi。這時8259a則同時會重置中斷服務暫存器中相應的位,表示中斷結束(eoi只有一位,而中斷服務暫存器中有很多位,如何對應?猜測是自動復位最高優先順序位)。
至此,結束。
自己動手寫作業系統
virtual pc 5.2 下 dos7.1 中 執行.com檔案相關問題 2009 09 09 12 55 剛才在進入dos後,編譯.asm檔案獲得.com檔案,但系統會出現 emm386 unrecoverable privileged operation error n9.press ent...
自己動手寫作業系統
今天看了前兩章,現將重點記錄如下 作業系統的啟動,關鍵點時同bios的介面 這裡有兩個位址很重要,a,0x7c00 510 0x7dfe登記標誌位 兩個byte 0xaa55 b,0x7c00,作業系統載入的目標位址 系統啟動過程 1 bios清零cpu現場 傳送reset訊號 2 cpu從0xf ...
自己動手寫作業系統
2 自己動手寫作業系統 3自己動手寫作業系統 如何呼叫bios中斷 在一般的程式語言中,函式的呼叫是一件非常容易的事情。比如在c語言中,如果有乙個名為display的程式,它帶有兩個引數,其中引數 noofchar表示顯示的字元數,引數attr表示顯示字元的屬性。那麼要呼叫它,只需給出程式的名稱即可...