最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

重拾保護(hù)模式----整理一下筆記

2020-03-29 10:25 作者:土衛(wèi)十三official  | 我要投稿

標(biāo)題可能起的有點(diǎn)大了。總之本文是對進(jìn)入保護(hù)模式過程的一些針對性復(fù)習(xí),主要是為了寫代碼做的準(zhǔn)備。

實(shí)模式的一些特點(diǎn)

  • 16?位數(shù)據(jù)總線、20?位地址總線,1MB?尋址能力。

  • 尋址方式:Physical?Address?=?Segment *?16?+?Offset

實(shí)模式的進(jìn)化

  • 原因:自?80386?時(shí)代開始,Intel?的?CPU?進(jìn)化到?32?位。尋址能力上升到?4GB。

  • 解決方法:保護(hù)模式下的地址依然使用Segment:Offset的形式來表示,但其中段的含義發(fā)生了變化:段值的含義由原來的地址的一部分(這么稱呼是因?yàn)閷?shí)模式的段值直接參與了地址的計(jì)算)變?yōu)橐粋€數(shù)據(jù)結(jié)構(gòu)表(GDT)的其中一個表項(xiàng)(描述符)的指針。該結(jié)構(gòu)包含一些屬性,用于描述段的一些性質(zhì)。

GDT?相關(guān)

  • 每個?GDT?描述符占?8?字節(jié),包括了段屬性、段基地址、段界限三個部分。其中基址和界限根據(jù)名字就可理解,屬性一共使用了?2?字節(jié)(里面有?4bit?是段界限的內(nèi)容。由于歷史原因,GDT?描述符的結(jié)構(gòu)很混亂)來表示段的一些特征。(用電視分割線來標(biāo)注代碼了)

;從上到下對應(yīng)地址從低到高

%macro?Descriptor?3

????dw??%2?&?0FFFFh?????????????;?段界限1

????dw??%1?&?0FFFFh?????????????;?段基址1

????db??(%1?>>?16)?&?0FFh???????;?段基址2

????dw??((%2?>>?8)?&?0F00h)?|?(%3?&?0F0FFh);?屬性1?+?段界限2?+?屬性2

????db??(%1?>>?24)?&?0FFh???????;?段基址3

%endmacro?;?共?8?字節(jié)

上述代碼利用?NASM?的宏定義了一個描述符的數(shù)據(jù)結(jié)構(gòu)。

這里提一下?NASM?的語法,Descriptor?3中的?3?表示數(shù)據(jù)結(jié)構(gòu)里有三個變量需要傳入?yún)?shù)(用%1,%2,%3?來表示)。使用時(shí),按照下列代碼的格式就可以傳入?yún)?shù)完整構(gòu)造一個實(shí)例化的描述符結(jié)構(gòu)。

LABEL_GDT:??????????Descriptor???????0,????????????????0,????????????0

LABEL_DESC_CODE32:??Descriptor???????0,?SegCode32Len?-?1,?DA_C?+?DA_32

;B8000h處為顯存基地址

LABEL_DESC_VIDEO:???Descriptor?0B8000h,???????????0ffffh,???????DA_DRW


上面的代碼創(chuàng)建了三個描述符,對應(yīng)定義了三個段。

mov?ax,?SelectorVideo

mov?gs,?ax??????????;?視頻段選擇子(目的)

============分割線======================

SelectorVideo???????equ?LABEL_DESC_VIDEO?-?LABEL_GDT

============分割線======================

mov?[gs:edi],???ax

前兩行將SelectorVideo移動到了?gs?中,最下面那一行代碼的`[gs:edi]`實(shí)際上就等于[SelectorVideo:edi]。

一個選擇子結(jié)構(gòu)的?3-15?位是描述符的索引,根據(jù)定義可以看到是相對于一個描述符相對于?LABEL_GDT?的偏移量。選擇子指向一個段描述符,正如上節(jié)“實(shí)模式的進(jìn)化”中提到的那樣。

上述的尋址計(jì)算過程結(jié)束后將得到一個線性地址。總體尋址過程可以描述為:`SEG:OFFSET?<=>?GDT.BASE?+?OFFSET`,其中`GDT.BASE`正是由`SEG`索引得到。

[SECTION?.s16]

[BITS???16]

LABEL_BEGIN:

????mov?ax,?cs

????mov?ds,?ax

????mov?es,?ax

????mov?ss,?ax

????mov?sp,?0100h

????;?初始化?32?位代碼段描述符

????xor?eax,?eax

????mov?ax,?cs

????shl?eax,?4??????????;左移4位,代碼段首地址

????add?eax,?LABEL_SEG_CODE32???????;eax保存描述符地址

????mov?word?[LABEL_DESC_CODE32?+?2],?ax

????shr?eax,?16

????mov?byte?[LABEL_DESC_CODE32?+?4],?al

????mov?byte?[LABEL_DESC_CODE32?+?7],?ah????;使用32位存放描述符地址

????;?為加載?GDTR?作準(zhǔn)備

????xor?eax,?eax

????mov?ax,?ds

????shl?eax,?4

????add?eax,?LABEL_GDT??????;?eax?<-?gdt?基地址

????mov?dword?[GdtPtr?+?2],?eax?;?[GdtPtr?+?2]?<-?gdt?基地址

????;?加載?GDTR

????lgdt????[GdtPtr]

????;?關(guān)中斷

????cli

????;?打開地址線A20

????in??al,?92h

????or??al,?00000010b

????out?92h,?al

????;?準(zhǔn)備切換到保護(hù)模式

????mov?eax,?cr0

????or??eax,?1

????mov?cr0,?eax

????;?真正進(jìn)入保護(hù)模式

????jmp?dword?SelectorCode32:0??;?執(zhí)行這一句會把?SelectorCode32?裝入?cs,

????????????????????????????????;?并跳轉(zhuǎn)到?Code32Selector:0??處

;?END?of?[SECTION?.s16]


上面一段代碼為進(jìn)入保護(hù)模式做了一些準(zhǔn)備工作:

  • 初始化保護(hù)模式代碼段:首先把.s32代碼段的物理地址存入eax,接著將這個地址拆分存入32位代碼段描述符,這里只操作了DESC_CODE32的段基址,段界限和屬性在前面已經(jīng)定義過。后面的`xor?eax,?eax`意味著DESC_CODE32已經(jīng)完成了賦值,現(xiàn)在該描述符已經(jīng)可以描述保護(hù)模式下的地址了。

  • 接下來是將GDT基地址復(fù)制到gdtptr這個結(jié)構(gòu)中(gdtptr的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)和gdtr寄存器的訪問方式是完全一致的),然后使用lgdt指令將指針?biāo)腿雊dtr寄存器,這步結(jié)束后,就可以通過寄存器很方便地訪問GDT了。


A20

關(guān)于這部分的詳細(xì)介紹在ucore第一章的筆記里。(https://bwonsamdi.github.io 專欄投稿貌似不能加站外鏈接)

  • 對于實(shí)模式的地址,其最大尋址空間為1MB,但可表示的最大地址為FFFF:FFFF(即0x10ffef),比1MB多了0xffef,實(shí)模式在遇到這種情況時(shí)會采取回滾機(jī)制。

  • 隨著計(jì)算機(jī)的發(fā)展,地址線位數(shù)增加后,既要允許更大的地址空間訪問,又要保證對原20根地址線的兼容,因此IBM使用鍵盤控制器來控制第20根地址線,具體控制過程不再描述。

進(jìn)入保護(hù)模式

  • 首先把CR0寄存器第0位置1,表示CPU切換到保護(hù)模式,此時(shí)cs的值仍為實(shí)模式的地址。

  • 接下來將事先初始化后的32位代碼段選擇子復(fù)制到CS中,這個過程借助jmp指令實(shí)現(xiàn)。這條指令本身處于16位的代碼段,但是跳轉(zhuǎn)目的地是32位的地址,因此諸如SelectorCode32:0x11112222會被截?cái)喔呶?,只剩?x2222。

  • 在Linux中,對于上述問題的解決方案,采用了使用DB直接寫入機(jī)器碼強(qiáng)制執(zhí)行的方法,在NASM中,支持利用jmp???dword?SelectorCode32:0的方式(加上dw)來解決。

特權(quán)級


Current?Privilege?Level

  • CPL是當(dāng)前執(zhí)行的程序或任務(wù)的特權(quán)級,存儲在CS和SS的0位和1位上,通常情況下CPL等于代碼所在段的特權(quán)級。當(dāng)程序轉(zhuǎn)移到不同特權(quán)級的代碼段時(shí),CPL將會改變。

  • 一致代碼段可以被相同或更低級的代碼訪問。訪問與CPL不同的一致代碼段時(shí),CPL不會改變。

Descriptor?Privilege?Level

DPL表示段或門的特權(quán)級,存儲在段描述符或門描述符的DPL字段中。當(dāng)前代碼段訪問段或門時(shí),DPL會與CPL、段或門選擇子的RPL進(jìn)行比較,根據(jù)段或門的類型,DPL會被區(qū)別對待

  • 數(shù)據(jù)段:DPL規(guī)定了可以訪問該段的最低特權(quán)級。若數(shù)據(jù)段的DPL為1,則CPL為0或1的程序可以訪問此段。

  • 沒有調(diào)用門的非一致代碼段:DPL規(guī)定了可以訪問該段的特權(quán)級。

  • 調(diào)用門:與數(shù)據(jù)段一致。

  • 一致代碼段/通過調(diào)用門訪問的非一致代碼段:DPL規(guī)定了可以訪問該段的最高特權(quán)級。若段DPL為1,則CPL為2或3的低特權(quán)代碼段可以訪問該段。

  • TSS:和數(shù)據(jù)段一致。


Requested?Privilege?Level

RPL是段選擇子的0位和1位,表示當(dāng)前進(jìn)程想要的請求權(quán)限。通過RPL和CPL可以確認(rèn)訪問請求的合法性。即便段的特權(quán)級足夠,也要考慮RPL的級別,即訪問合法性的判斷取決于CPL和RPL中特權(quán)級最低的那個(數(shù)字最大)。

操作系統(tǒng)使用RPL避免低特權(quán)級應(yīng)用程序訪問高特權(quán)級段數(shù)據(jù)。當(dāng)被調(diào)用過程(操作系統(tǒng)過程)從調(diào)用過程(應(yīng)用程序)接收到選擇子時(shí),會把選擇子的RPL設(shè)置成調(diào)用者的特權(quán)級,當(dāng)操作系統(tǒng)使用該選擇子訪問對應(yīng)段時(shí),處理器會用已經(jīng)被存到RPL的調(diào)用過程的特權(quán)級,而不是CPL進(jìn)行檢驗(yàn)。

特權(quán)級總結(jié)

  1. 調(diào)用門本質(zhì)上是一個描述符,長8字節(jié)。一個門描述了由一個選擇子和一個偏移指定的線性地址。

  2. 一般通過call/jmp加上遠(yuǎn)指針的方式訪問調(diào)用門。這個遠(yuǎn)指針的段選擇子用于指定調(diào)用門。

  3. 通過調(diào)用門進(jìn)行程序控制流的段轉(zhuǎn)移時(shí),CPU會按以下順序檢查:

    1. ?? 當(dāng)前代碼段的CPL

    2. ?? 調(diào)用門描述符的DPL

    3. ?? 調(diào)用門描述符的RPL

    4. ?? 目的代碼段描述符的DPL

    5. ?? 目的代碼段描述符的一致性標(biāo)志C

  • ?? 同時(shí),對于call和jmp,優(yōu)先級檢查規(guī)則也不同:

    • 對于call指令

      • CPL<=調(diào)用門描述符DPL

      • RPL<=調(diào)用門描述符DPL

      • CPL>=目的代碼段描述符DPL

    • 對于jmp指令

      • CPL<=調(diào)用門描述符DPL

      • RPL<=調(diào)用門描述符DPL

      • 如果目的代碼段為一致代碼段:CPL>=目的代碼段描述符DPL

      • 如果目的代碼段為非一致代碼段:CPL=目的代碼段描述符DPL

4.?調(diào)用門的作用是使得一個代碼段被不同特權(quán)級的程序訪問。

5.?一致代碼段:屬于內(nèi)核,允許用戶訪問的代碼段。對于一致性代碼來說,特權(quán)級高的程序不允許訪問特權(quán)級低的數(shù)據(jù)(內(nèi)核不能訪問用戶數(shù)據(jù)),特權(quán)級低的代碼可以訪問到特權(quán)級高的數(shù)據(jù),但訪問中**特權(quán)級不會改變**,訪問內(nèi)核的程序依然屬于用戶態(tài)。

6.?非一致性代碼段:僅允許同級訪問,內(nèi)核態(tài)只能訪問內(nèi)核代碼,用戶態(tài)只能訪問用戶代碼。

7.?通常低特權(quán)代碼必須通過門來實(shí)現(xiàn)對高特權(quán)代碼的訪問。

8.?RPL說明的是進(jìn)程對段訪問的請求權(quán)限,意思是當(dāng)前進(jìn)程想要的請求權(quán)限。RPL的值由程序員自己來自由的設(shè)置,并不一定RPL>=CPL,

9.?當(dāng)RPL?<?CPL時(shí),實(shí)際起作用的就是CPL了。當(dāng)選擇子成功裝入CS寄存器后,相應(yīng)的選擇子中的RPL就變成了CPL。

10.?在call調(diào)用門時(shí),需要進(jìn)行堆棧轉(zhuǎn)移,堆棧轉(zhuǎn)移需要借助TSS實(shí)現(xiàn)。

11.?TSS是一個包含了多個字段的數(shù)據(jù)結(jié)構(gòu),其中包括了ring0-ring3的棧區(qū)指針,利用這個結(jié)構(gòu),可以將棧參數(shù)復(fù)制。

后記

關(guān)于特權(quán)級的部分,看得不是很詳細(xì),以后需要再特別寫一篇文章來按位解析GDT、選擇子、調(diào)用門、TSS這些數(shù)據(jù)結(jié)構(gòu),否則在理解一些機(jī)制的時(shí)候常常會暈頭轉(zhuǎn)向。這一部分的一些細(xì)節(jié)的地方就暫時(shí)擱置起來,目前距離脫離匯編進(jìn)入C編程還有很長一段路要走。

參考

  • 《自己動手寫操作系統(tǒng)》

  • https://www.cnblogs.com/bamboos/archive/2009/03/26/1422041.html

專欄投稿屬實(shí)難用,什么時(shí)候可以支持markdown啊......

另外github求一波關(guān)注......最近在做xv6的實(shí)驗(yàn),不過暫時(shí)還沒有放到遠(yuǎn)程倉庫里。

近期的目標(biāo)是xv6實(shí)驗(yàn)和linux kernel的實(shí)驗(yàn)

五月份開始學(xué)校就沒課了,那個時(shí)候該專門琢磨考研了。要是大家能多投幾個幣,說不定我就有動力把實(shí)驗(yàn)都做完了呢


要是看到這里了,就投個票吧

這類文章該不該繼續(xù)發(fā)?



重拾保護(hù)模式----整理一下筆記的評論 (共 條)

分享到微博請遵守國家法律
吉隆县| 洪洞县| 滦平县| 融水| 临沂市| 庄浪县| 澳门| 丰顺县| 高安市| 南充市| 阿鲁科尔沁旗| 遂川县| 乌兰浩特市| 肥西县| 阳新县| 富平县| 兴安县| 乌审旗| 峨边| 兴城市| 朝阳县| 军事| 芜湖县| 德保县| 绥芬河市| 曲松县| 寿光市| 大英县| 万州区| 新源县| 壶关县| 珠海市| 广汉市| 阳高县| 房产| 涟源市| 浏阳市| 邢台县| 静乐县| 偃师市| 金华市|