保护模式
之前的程序都是在實模式下面的程序,只能訪問1M的地址,2^20
intel退出32位cpu完全兼容16位cpu,重要的一點是可以繼續使用16模式下的尋址方法。
32位cpu地址線為32根,最大內存為4G,如何利用原來的seg:offset表示方式,來表示32根地址線。
把32位的物理內存寫入一個表中,每個表項記錄內存的開始地址和大小,邊界,
16位的寄存器用來表示表的索引。比如:當16bit段寄存器中存放的數值為2,則表示內存放在表的第二個表項中。
事先分好的內存段信息存入一張表格中,讓后段寄存器中表村你要訪問的內存段所在的這張表的索引。
這張表包含的內容,如何通過這張表找到所需的內存塊。
段選擇子16位(段寄存器16bit)其中高13bit用來表示描述符的索引,低三位用來表示段描述符
表中所指向的段描述符的屬性。(所以段描述符有2^13=8096個索引項)
15??????????????????????3???2??? 0
??描述符索引?????????????TI?? RPL
TI表示從全局描述符表讀取描述符還是從局部描述符中讀取描述符。(進程的私密空間或者一些通用庫的內存地址)
RPL,用于特權檢查
沒有開啟分頁機制,線性地址空間等于物理地址。(有了分頁機制,比如ARM中的mmu,可以將多塊線性地址映射到同一塊物理地址,這個時候,線性地址遠遠大于物理地址,換入換出機制)
段寄存器存放了段描述符表中的索引號,通過該索引可以知道該索引號的段描述符
因為段描述符內記錄了段在32位內存的開始地址和段的長度(段界限)那么就能定位
到實際的物理內存地址。
段描述符有8個字節,每個字節的具體含義。
第七個字節的第四位存放段界限剩余的4位。
段屬性
段屬性位于段描述符第六和第七個字節,用來描述該段是數據段還是代碼段或者是堆棧段,對于數據段或者堆棧段來說是否可讀或者可寫(RW),對于代碼段來說是否可執行||以及段描述符所指定的內存段在物理內存中是否存在。
type:4bit,描述該段是數據還是代碼段,可讀還是可寫還是可執行??
DT:我們代碼中一般式存儲段?DPL:特權級別指的是os中應用程序訪問內存,時,規定哪些內存有權利去訪問,8086cpu中,0~3,現在編寫的是os,所以DPL為0
P:
AVL:intel保留,不管,都置為0
D:0表示16bitcode段,1是32bit code段,如果是數據段,0表示16bit地址,1表示32bit地址
G:這里是保護模式,G=1
?
由于我們在裸機上編寫程序,因此我們必須在4G的內存空間中自己分配代碼段和數據段。也就是說這個過程中沒有操作系統的干涉,完全是我們自己搞定,想咋整就咋整。
在4G的內存范圍內進行分配:
怎么把8M的數據填充到數據段描述符和代碼段描述符
由于8M等于2^23(800000H),沒有辦法吧23bit的地址填充到20bit的界限中,通過段界限公式來轉化:
段界限=limit*4k+0fffh,當limit=8M的時候,limit等于7ffh,limit=(800000H-0FFFH)/4k= 7FFh,4k這里轉化為十六進制,為1000h,將7ffh這個數據填充到段描述符的20bit界限位中,不足的添零。
DPL表示內存段的權限,表示有一定權限的進程才能訪問,0為最高級別,內核程序最高。
avl:intel保留位,設為0.不管
D:數據段,表示邊界是4g還是64k,代碼段:0表示16位代碼,1表示32位代碼
G:保護模式下為1,實模式下面為0
總共有64bit8byte,段基址為32位,4byte,分成兩個部分,段屬性為4byte,段界限為byte0,1,按位填充即可。
代碼段描述符和數據段描述符類似,只是段的基址不一樣,為800001H,第七個字節的屬性不一樣。
數據段全貌
?
代碼段全貌
其中綠色部分是代碼段和數據段不同的地方,第一個是byte5低四位為1010,表示的意思是,當s=1即bit44表示為數據段和代碼段描述符時,byte5第四位為代碼段,表示代碼段可執行,可讀,詳細見自己動手寫操作系統p48.第二個變化是段基址從800001h開始,因為數據段大小為8M=800000h,byte0還是不變。
上面就構造好了數據描述符和代碼描述符。
總結
- 上一篇: 初识保护模式
- 下一篇: 引导程序为什么要org 07c00h