《一個操作系統的實現》(三):1.認識保護模式

進入第三章的學習~第三章開始每章內容變多了,所以以後每學習一節寫一篇文章~

順便注一句:書上“用來生成描述符的宏”只是節自光盤中的pm.inc文件的,我照書上敲了那短短一段發現編譯的時候報錯- -不過我相信大家的眼睛都比我雪亮

因爲引導扇區空間只有512個字節,解決這個問題有倆辦法:自己寫一個引導扇區or借用別人的引導扇區(從作者的話看起來以後會涉及自己寫引導扇區~期待),咱用第二種,借用一下別人的扇區。又要去Bochs官網下東西了(還是進不去。。),幸虧有好心人~freedos-img下載,把其中的a.img複製到目錄中,改名爲freedos.img。用第二章的方法再生成一個叫做pm.img的軟盤映像(bximage命令,然後fd -> 1.44 -> pm.img),也放到目錄中。然後修改bochsrc文件,把原先的floppy:…與boot: …刪掉,換成下面三行:

floppya: 1_44=freedos.img, status=inserted

floppyb: 1_44=pm.img, status=inserted

boot: a

啓動Bochs,會發現界面顯示出A:\>,這時我們輸入format b:,會提示Format operation complete.(這時不用關Bochs)

在pmtest1.asm中將org後面的07c00h改爲0100h,重新編譯(注意,這裏編譯成.com):

nasm pmtest1.asm -o pmtest1.com

將pmtest1.com複製到虛擬軟盤pm.img上:

sudo mount -o loop pm.img /mnt/floppy(如果沒有此目錄,則要先mkdir /mnt/floppy,不然會報“掛載點/mnt/floppy不存在”)

sudo cp pmtest1.com /mnt/floppy/

sudo umount /mnt/floppy

如果成功的話,在Bochs中輸入dir b:會出現Directory of B:\*.*,下面還有幾行,如果不成功,會出現File not found.這說明pmtest1.com複製失敗(有可能是因爲關了Bochs)

然後在Bochs中執行b:\pmtest1.com,會發現紅色的P出現在了屏幕最右端~


以上爲代碼操作部分,下面是理論部分——

“Intel 8086是16位的CPU,有16位的寄存器、16位數據總線、20位地址總線,1MB尋址能力。”

物理地址 = 段值 * 16 + 偏移  (其中段值和偏移均爲16位)

實模式和保護模式中的段的概念有着根本區別。實模式下,段值可看作是地址的一部分(比如說段值爲XXXXh表示以XXXX0h開始的一段內存)。但是保護模式下,段只是一個索引,指向GDT(即global descriptor table,全局描述符表)的一個表項(描述符)。描述符詳細定義了段的起始地址、界限、屬性等內容。GDT的作用是提供段式存儲機制(此機制通過段寄存器和GDT中的描述符共同提供)

一個講GDT描述符的文章見這裏(其中涉及到“一致碼段”,下面有表列出一致與非一致的比較),還有這篇文章講的很好:保護模式下如何尋址

SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT

這行代碼看起來是DESC_VIDEO這個描述符相對於GDT基址的偏移,其實它有一個專門名稱:選擇子,而且它也不是一個偏移。選擇子用來選擇描述符表中的一個描述符

在別的地方看到這樣一句話:“選擇子確定描述符,描述符確定段基地址,段基地址與偏移之和就是線性地址。”

“段:偏移”形式的邏輯地址經過段機制轉化成線性地址,而不是物理地址。不過暫時在這裏線性地址就是物理地址。

關於A20地址線:8086->80286尋址範圍擴大,但是8086只能尋到1MB,如果訪問超過1MB的地址,雖然不會發生異常,但是又從0開始尋址,所以爲了保證兼容,使用8042鍵盤控制器來控制第20個地址(從0開始數)。所以爲了訪問所有內存,需要把A20打開,默認是關閉的。

寄存器cr0的第0位是PE位,此位爲0時是實模式,爲1時是保護模式。

jmp dword SelectorCode32:0

這個jmp在16位的段中,目標地址卻是32位。不能去掉dword,去掉的話編譯出來只是16位的代碼,如果目標地址的偏移較大,則前半段會被截斷。其實dword是NASM提供的,在Linux內核代碼中,這個跳轉使用DB指令直接寫二進制代碼的方式來實現的。

一致與非一致
  特權級
低->高
特權級
高->低
相同特權
級之間
適用於何種代碼
一致代碼段 Yes No Yes 不訪問受保護的資源和某些類型
的異常處理的系統代碼
非一致代碼段 No No Yes 避免低特權級的程序訪問而被
保護起來的系統代碼
數據段(總是非一致) No Yes Yes  


幾個指令的含義:

equ——相當於賦值,可以將一個數值或者一個寄存器名賦給一個指定的符號名。

[gs:edi]——段寄存器名:段名,在這裏即代表段:偏移

lgdt——可以把GDT描述符表的大小和起始地址存入gdt寄存器中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章