動手製作作業系統 一點分析問題的經驗

2021-07-11 22:02:52 字數 1238 閱讀 7367

書中講解ldt部分的例子和**很簡單,本以為抄完執行一下馬上就能結束這章。但是很尷尬,在抄完書中的**後,編譯執行,實際執行的結果和書中的結果並不一樣,程式只執行了一半就導致系統崩潰了,乾瞪眼看**看了半天,和書中的**明明寫的一樣,那麼為什麼會出現這個問題呢?

書中程式執行在freedos上,大致意思如下:

在程式開頭部分建立gdt,ldt和gdt選擇子,ldt選擇子等,等程式載入至記憶體後,

1、跳至乙個在實模式下執行的**段,這段**負責初始化gdt,ldt中的描述符和進入保護模式的準備工作(記做a**段);

2、跳至保護模式,乙個32位的**段(記做b**段),在這裡顯示一串字串;

3、進入ldt中的乙個描述符所表示的**段(記做c**段),這裡顯示乙個字元l;

4、回到實模式,程式結束。

而我的程式寫完後,只輸出了字串,c**段中的'l'並未顯示,系統就崩潰了

首先粗略分析問題,b中的字串已經顯示成功,c中的'l'未顯示,那麼問題大致的位置就定位在a或者a之前

第乙個問題來了,由於這個示例程式是執行在freedos上的,我們的程式被dos載入到記憶體中什麼地方我是不知道的,而bochsdbg想要設定斷點就必須要知道程式的執行位址,我應該怎麼設定斷點?。

在網上找到了乙個方法:

1、在程式開頭處建立乙個標記label_begin;

2、向400h:0處(也可以別的未被占用的記憶體位址)寫入代表跳轉至label begin 處(jmp far)的16進製制機器碼;

3、跳至400h;0處

然後在作業系統執行前在400h:0處設定斷點,就可以除錯程式了。

解決無法除錯的問題後單步執行程式,執行完跳轉至c**段的指令後。程式跳轉到了乙個奇怪的位址,不是c**段所在的位址,顯然,問題出在建立或者初始化gdt,ldt,選擇子的部分上

那麼單步執行程式至載入完ldt處,用info ldt命令檢視gdt和ldt,gdt中的ldt描述符的段基址和段界限中沒有問題,而ldt中唯一的描述符基址出現了錯誤,為0x00002600,與應該得到的結果0x00032600不符,至此,問題的位置已經找到了,就在a中 初始化ldt中的描述符(記做d)處。

繼續除錯d處的**,明明應該右移的資料卻左移了,我將我抄寫完的**中的d處和書中的**的d處對比了一下,發現,原來只是因為我把書中的shr抄成了shl。只因為乙個字元,指令的含義完全改變了。整個程式就因為這乙個字元而崩潰。

問題雖小但是解決這個問題的過程也收穫很多經驗,遇到bug的大致思路就是:大致定位問題,找出問題發生的具體位置,解決問題。

動手製作作業系統 認識實模式與保護模式

因為計算機啟動後按照實模式定址,cpu只能訪問1m的記憶體,所以為了訪問1m記憶體後更大的空間,就需要進入到保護模式,保護模式不僅有更大的位址空間,還將程式分成了4個特權級 0 4 數字越小特權級越高,在涉及特權級的操作時,處理器將會對特權級進行比較,最終允許訪問或者拒絕訪問。描述符 乙個特殊的資料...

自己動手寫作業系統(一)

從去年就想好好的讀一下這本書,跟著書上做一下,但是給耽擱了,現在就好好的開始探索這麼書吧!雖然我很想在這裡吹一段這本書有多麼的厲害,但是!我第一章都沒有看完,吹不了!等我讀的個七七八八再回來吹吧。我是在搜尋嵌入式的學習路線中發現的這本書,當時他們說這本書很有趣,操作能力強,對作業系統的理解很有幫助,...

自己動手寫作業系統(一)

好了,廢話不多說,我們開始第一章,開發準備。我這裡使用的是ubuntu作業系統,模擬器採用的是bochs,編譯器使用的是gcc和nasm。bochs安裝 sudo apt get install bochs.gcc用來編譯c檔案。ubunt自帶,無需安裝 nasm用來編譯彙編,安裝命令 sudo a...