[OS_0x01]實(shí)模式 --> 保護(hù)模式(段式-->段頁式)

``本文的一些截圖來自于<IntelDEV卷3>和<x86匯編從實(shí)模式到保護(hù)模式>`

最近復(fù)習(xí)一些操作系統(tǒng)的知識,首先遇到了個(gè)坑便是計(jì)算機(jī)尋址問題.
本文是一些偏理論的東西(匯編可能在工作中用不到氮帐,需要的時(shí)候再深入研究吧- -!)

本文參考的一些博客和書本:

<a href=http://blog.csdn.net/trochiluses/article/details/8954527>[實(shí)模式與保護(hù)模式解惑之(一)——二者的起源與區(qū)別]</a>
匯編相關(guān)-從匯編研究局部變量機(jī)制
我看保護(hù)模式
x86匯編語言:從實(shí)模式到保護(hù)模式

實(shí)模式

  • 是什么

INTEL 8086CPU的尋址方式.

具體利用分段機(jī)制訪問內(nèi)存,訪問時(shí)給出一個(gè)段基地址和一個(gè)段內(nèi)偏移檩奠;(如DS:AX宋舷,其中DS和AX在這里的字長為16),訪問的地址為實(shí)實(shí)在在的物理地址.

  • 為什么

    一個(gè)原因是8086特點(diǎn) - 數(shù)據(jù)總線16位(字長為16)闲询、地址總線卻有20位(準(zhǔn)確地說是CPU的尋址能力需要被設(shè)計(jì)成20位).

    這樣程序員在沒有特殊機(jī)制的引入時(shí)涤浇,只能訪存2^16 B = 64 KB的空間(16位字長),達(dá)不到產(chǎn)品經(jīng)理的需求(20位地址空間 = 2^20 B = 1 MB

    于是宙拉,這里設(shè)計(jì)成了使用段基地址 + 段內(nèi)偏移的方式: 物理地址 = 段基地址<<16 + 段內(nèi)偏移
    有個(gè)小問題就是這種方式實(shí)際上可訪問的空間大于1M笨触,即最大可以訪問到0xFFFF*16 + 0xFFFF = 0x10FFEF > 0xFFFFF懦傍,多出的這些地址將從0開始(即對1M取模).

  • 實(shí)模式的段的特點(diǎn) -

    • 每個(gè)段基地址都是16的倍數(shù);

    • 每個(gè)段的最小長度是16 Bytes芦劣,最大是64 KB粗俱;<----------更新: 段的大小從1B到64KB都可以.見wiki:

      1. WIKIPEDIA.png

    • 訪問的每個(gè)地址都是實(shí)際的物理地址.

  • 遺留的問題

系統(tǒng)程序與用戶程序訪問的地址共存于同一地址空間,并且一視同仁:

  • 沒有權(quán)限保護(hù)(用戶可以隨意訪問1M的全部內(nèi)存地址空間)
  • 不支持多任務(wù).

保護(hù)模式

保護(hù)模式之所以叫“保護(hù)模式”,因?yàn)樗麑Χ嗳蝿?wù)提供了保護(hù)虚吟,并加入了權(quán)限.
瑪?shù)挛蚁肫饋砹舜蠖R編時(shí)保護(hù)模式這一章跳過了因?yàn)槠谀┎豢嘉秩?

  • 是什么
    80386及后續(xù)系列CPU所資磁的內(nèi)存尋址方式.

  • 為什么
    引入保護(hù)模式的目的有:

    • 保護(hù) - 權(quán)限管理
    • 多任務(wù)隔離
    • 向下兼容 - ...
  • 怎么做
    這里簡要介紹一下保護(hù)模式.

    • 尋址方式的改變:

    • 實(shí)模式下 - 可以直接訪問段基地址(段寄存器16_bit)<<16 + 段內(nèi)偏移并做一些單字長操作(訪存/賦值) .

    • 保護(hù)模式下 -
      先來點(diǎn)廢話:
      由于需要引入權(quán)限管理, 需要:訪存時(shí)指出當(dāng)前執(zhí)行指令的人有沒有權(quán)限訪問這個(gè)地址寸认;
      這句話至少包括了2點(diǎn):

      • 當(dāng)前指令的權(quán)限描述签财;
      • 目標(biāo)地址的權(quán)限描述.

      所以當(dāng)前的解決方案已經(jīng)呼之欲出了:需要一個(gè)數(shù)據(jù)結(jié)構(gòu)來描述內(nèi)存地址.

保護(hù)模式下的尋址_part1段式(1MB --> 4GB 32Bit)

  • 機(jī)器啟動(dòng)流程 - 一個(gè)PC啟動(dòng)時(shí)都會(huì)先進(jìn)入實(shí)模式,接著由某指令轉(zhuǎn)入保護(hù)模式.

  • 段描述符表 - 是一堆段描述符的集合偏塞,有GDT和LDT.其中GDT是全局描述符表Global Descriptor Table,該表是為整個(gè)OS服務(wù)的唱蒸,在進(jìn)入保護(hù)模式之前定義好(由bootloader). LDT,相對應(yīng)地烛愧,則是局部段描述表油宜,是每個(gè)進(jìn)程自己獨(dú)有的?.

    GDTR寄存器存放著GDT的地址.
    理論上說GDT可以位于4GB中的任何一個(gè)位置怜姿,但因?yàn)樾枰獜膶?shí)模式轉(zhuǎn)保護(hù)模式慎冤,所以一般只在1M以內(nèi)的位置...(參見<x86從實(shí)模式到保護(hù)模式>)

    2. GDTR,48bit的寄存器

  • 描述符表項(xiàng) - 無論是全局還是局部的描述符表沧卢,表項(xiàng)字段都如下圖所示:(it‘s a fucking Data Structure!)

    3. 描述符表項(xiàng)

    里面記錄了這個(gè)段的:

    • 段基地址BASE(32位一共蚁堤,被分割成了3部分)
    • 段界限LIMIT(20位)
    • 段界限Granularity (Seg.LIMIT字段)的單位(0 - 1B/1 - 4KB).

段界限及其單位表示 段內(nèi)偏移的最值(對于向上增長的段而言表示了最大值,而向下增長的段如堆棧段則是表示段內(nèi)偏移的最小值哦)<------why但狭?舉個(gè)例子如下:(如有錯(cuò)誤請指出)

0xFFFFFFFF |********|
                     ... 
0x00A01001 |********|<-----SS:EBP (指向棧底) }
0x00A00FFF |********|<-----SS:ESP (指向棧頂) }EBP,ESP兩個(gè)的值可能都是段內(nèi)偏移
                     ...
0x00A00002 |        |
0x00A00000 |********|<-----SS:<段界限*粒度+1> Suppose a MIN_VAL's linear addr
                     ...
                     |
0x0000FF00 |********|
                     ...
0x00000002 |        |(每次存進(jìn)來一個(gè)字2 bytes披诗,所以地址上相差2)
0x00000000 |********|<-----SS:0
0.假設(shè)某程序運(yùn)行時(shí)調(diào)用了一個(gè)函數(shù),這時(shí)該程序的動(dòng)作包括`保存現(xiàn)場`立磁,`聲明堆棧段`呈队;我們關(guān)心的是聲明堆棧段(用來存儲(chǔ)函數(shù)參數(shù)、局部變量等).
1.這個(gè)段也有基址(我們假設(shè)為0x0唱歧,后面你就知道其實(shí)這個(gè)假設(shè)是ok的)
2.聲明時(shí)要做的事是指定EBP宪摧、ESP(有點(diǎn)欽定的感覺),接著ESP減2颅崩,push進(jìn)來函數(shù)參數(shù)之類的几于,每次push,ESP會(huì)自動(dòng)減2(別問我為什么自動(dòng))沿后,每次pop沿彭,ESP會(huì)自動(dòng)加2
3.上面所說的段內(nèi)偏移的最小值,指的就是當(dāng)ESP一直減尖滚,最多只能減到<段界限*粒度> 喉刘,再減就提示堆棧溢出了.

<a href=http://www.360doc.com/content/16/0223/12/28062682_536641957.shtml>匯編相關(guān)-從匯編研究局部變量機(jī)制</a>

所以現(xiàn)在一個(gè)段最大可以是4G,最小可以是1B.

理論上訪問4G內(nèi)存不再需要什么段啥的,一個(gè)段足矣(這種情況便是所謂的平坦模式):


4. flat mode
  • 段選擇子 - 段寄存器CS/DS/SS/etc...此時(shí)不再是被用來左移并相加的對象漆弄,而是存放一個(gè)索引+標(biāo)記+權(quán)限饱搏,這個(gè)索引指向了需要訪問的段所在描述符.這些存放的內(nèi)容被稱為段選擇子.

    5. 段選擇子

    由段選擇子的索引量可以看出一個(gè)表最多有2^13=8192個(gè)表項(xiàng)
    (實(shí)際上32位處理器如80386,他們的段寄存器的長度為32位置逻,只不過后面16位我們不可見,是處理器用作描述符高速緩存的)

  • 整體描述 (from high level)


    6. 線性地址如何得到-此圖來自<a href=http://bbs.chinaunix.net/thread-2083672-1-1.html>thread</a>('8'是表示立即數(shù)填充Index字段)
  • 權(quán)限 :
    權(quán)限字 0 - 3(高 - 低)备绽,如下:


    7. 特權(quán)級別
  • 權(quán)限的判斷機(jī)制:

    • 代碼段CS寄存器里的CPL為當(dāng)前執(zhí)行權(quán)限券坞,稱其為CPL(current)鬓催;
    • 數(shù)據(jù)段DS(或SS等,發(fā)出尋址請求指令所在寄存器)里的CPL為請求權(quán)限恨锚,稱其為RPL(request)宇驾;
    • 段描述符中的段權(quán)限D(zhuǎn)PL;

3者進(jìn)行一個(gè)判斷,如果合法(比較復(fù)雜的判斷猴伶,例如滿足DPL>=CPL课舍,DPL >= RPL,且CPL <= RPL等)他挎,則進(jìn)行地址轉(zhuǎn)換(此時(shí)得出的是虛擬地址筝尾,需要轉(zhuǎn)為物理地址,轉(zhuǎn)換又跟此時(shí)的另一些東西相關(guān)办桨,見part2)筹淫,轉(zhuǎn)換后最終尋址到所需地址.

總之,在保護(hù)模式下做什么事都得先進(jìn)行權(quán)限檢查.

PS: 這里的ring 0也就是所謂的內(nèi)核態(tài)呢撞,而linux中的用戶態(tài)是ring 3.

參考:<a href=http://blog.csdn.net/xiao_0429/article/details/47165169>我看保護(hù)模式</a>
(具體如何做的不深入了损姜,涉及太多匯編相關(guān)的東西,知道就好)<-------fuck that!既然有興趣讀到這些知識,最好搞懂, 不然辜負(fù)這些知識.

保護(hù)模式下的尋址_part2段頁式(更復(fù)雜的機(jī)制來了)

  • 整理一下目前為止接觸到的東西:
    1. 機(jī)器啟動(dòng)階段先進(jìn)入的是實(shí)模式(1M內(nèi)存尋址空間殊霞,20Bit地址 + 16Bit數(shù)據(jù)), 然后由某指令轉(zhuǎn)入保護(hù)模式.
    2. 保護(hù)模式_段式 - 最主要是為了解決權(quán)限問題摧阅,比如數(shù)據(jù)段不能被拿來當(dāng)代碼段運(yùn)行,當(dāng)前權(quán)限低的不能訪問權(quán)限高的段等.
      2.1 保護(hù)模式_段式 - GDT 和LDT(本來該設(shè)計(jì)是整個(gè)OS有一個(gè)GDT绷蹲,每個(gè)進(jìn)程有自己的LDT棒卷,而linux的進(jìn)程極少使用LDT,基本上GDT和LDT起始為止都是0x00000000
      2.2 GDT的地址和長度存放于GDTR(Global Descriptor Table Register)瘸右,其中0~15為GDT長度,16~47為GDT所在地址.
  1. 保護(hù)模式_段式 - the entry of GDT(or LDT)娇跟,每個(gè)表項(xiàng)描述了一個(gè)段.
  2. 段選擇子 - 段寄存器(如CS,SS等)存放的內(nèi)容包括INDEX太颤、TI苞俘、RPL.
  3. 權(quán)限4個(gè)等級(特權(quán)0 - 內(nèi)核態(tài), 特權(quán)3 - 用戶態(tài))- also known as ring 0 ~ 3.不管做什么都需要進(jìn)行權(quán)限判斷龄章。
  • 目前為止吃谣,訪問內(nèi)存是這樣訪問的:
用戶提供段選擇子(Index,TI,RPL)和段內(nèi)偏移(offset)  |
GDTR/LDTR提供了GDT和LDT的地址和長度                |-->權(quán)限檢查(結(jié)合代碼段CS中的權(quán)限字,段選擇子中的權(quán)限字和GDT/LDT表項(xiàng)中的權(quán)限字DPL進(jìn)行檢查)
                                                        -->找到Index所在段做裙,取出其段基地址
                                                            -->把用戶提供的段內(nèi)偏移與段基地址結(jié)合構(gòu)成一個(gè)完整的地址(這里稱為**線性地址**)

也就是上面的圖6表示的.
在單純只有分段的情形下岗憋,這個(gè)線性地址就是物理地址.

  • 目前為止,基于段的內(nèi)存替換是這樣進(jìn)行的:
  • 分段的缺點(diǎn) - 內(nèi)存外部碎片.(段大小不確定锚贱,使用一段時(shí)間之后仔戈,內(nèi)存可能會(huì)有很多微小的空洞,不足以提供分配)===>因此分頁機(jī)制就來了.

分頁機(jī)制

  • 大致描述:
    • 4GB物理內(nèi)存以4KB大小分為 4GB / 4KB = 1048576(1M)個(gè)頁,頁也稱為頁框(page frame).
    • 引入虛擬內(nèi)存的概念.對于每個(gè)進(jìn)程而言监徘,大家都有自己的4GB內(nèi)存空間,并且通過一定的手段(后面解釋), 按頁為單位映射到實(shí)際的物理內(nèi)存上.
    • 映射表晋修,上一點(diǎn)提到的虛擬內(nèi)存中的頁面與實(shí)際內(nèi)存物理頁面間通過映射表來聯(lián)系,甚至每個(gè)進(jìn)程都有自己的映射表, 另外這個(gè)映射表也很可能是分級的以解決空間利用效率.
    • 頁面的管理和頁面的分配沒有關(guān)系凰盔,線性地址(也就是段管理單元得到的地址)也與頁面的分配沒有關(guān)系.
8. 段--線性地址---頁映射表(簡稱頁表)---物理頁
  • 詳細(xì)深入:
  • MMU(Memory Management Unit)是CPU中的內(nèi)存管理單元.
  • 頁目錄:分頁機(jī)制實(shí)際上更復(fù)雜一些墓卦,上面說的"頁表"一共有1M個(gè),每個(gè)表項(xiàng)有4Bytes户敬,那么整個(gè)表有4MB這么大. 每個(gè)進(jìn)程有自己的頁表落剪,并且一般不會(huì)用到這么大,每次換入換出RAM是不是TM很煩尿庐?頁目錄就是解決這個(gè)的.(也就是上文里提到的頁映射表分級問題)
  • 4GB內(nèi)存中一共有1M個(gè)頁 --> 現(xiàn)在把這1M分成2個(gè)層次忠怖,即 1K * 1K,給第一個(gè)1K一個(gè)新的名字——頁目錄表(Page Dir. Tbl.)屁倔,第二個(gè)1K是真正的頁表. 頁表的規(guī)模變小了但相應(yīng)地?cái)?shù)目變?yōu)?K個(gè)脑又,所謂頁目錄表,就是存放這1K個(gè)頁表的頁.這里需要注意兩種表的表項(xiàng)大小都是4B锐借,所以兩種表的大小正好都是4K即一個(gè)頁的大小.
    還是有點(diǎn)亂问麸,見下面一系列的圖.(退后 我要開始裝逼了!)
    Powered By Processon.com
  • Naive的頁表:


    Naive頁表
  • 分層次的頁表:


    分層次的頁表
  • 分段/分頁的關(guān)系:


    分段/分頁的關(guān)系
  • 段頁式物理地址的獲取:


    段頁式物理地址的獲取

一些其他問題:

  • 吐槽 - 為什么經(jīng)常弄不懂呢钞翔?一部分原因是自己太懶严卖,另一部分書確實(shí)也有些沒講清楚或者考試不考尼瑪就跳過了.(歸根到底還是自己的問題,別怪別人...)


    9.-1 教科書中出現(xiàn)的地址轉(zhuǎn)換還是不夠精確布轿,沒有說明段選擇子也沒有設(shè)計(jì)頁的分層
  • 目前關(guān)注的這些應(yīng)該還算是尋址方式的一些東西哮笆,而上面有提到需要給進(jìn)程分配頁面,以及在該頁面不怎么使用時(shí)換出汰扭,那么這些動(dòng)作是怎么做的呢稠肘?
    9. 有錯(cuò)請指出,該圖來自<a href = http://www.cnblogs.com/bizhu/archive/2012/10/09/2717303.html>cnblog</a>

上面最后幾個(gè)圖如果看不清請猛戳<a href = https://www.processon.com/view/link/578a274ce4b0701cc02852c6> 我的文件</a>
歡迎大家糾錯(cuò)萝毛,共同進(jìn)步.


寫這篇的時(shí)候聯(lián)想到的一些問題:(亟待深入)

  • 快表? - ok.

  • 缺頁中斷 ?

  • dirty ?

  • 伙伴系統(tǒng) ?

  • slab/slub ?

  • malloc ?

  • page cache / buffer cache 又是什么呢 ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末施掏,一起剝皮案震驚了整個(gè)濱河市贴硫,隨后出現(xiàn)的幾起案子兽狭,更是在濱河造成了極大的恐慌腊尚,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庵佣,死亡現(xiàn)場離奇詭異歉胶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)巴粪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門通今,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粥谬,“玉大人,你說我怎么就攤上這事衡创〉畚耍” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵璃氢,是天一觀的道長。 經(jīng)常有香客問我狮辽,道長一也,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任喉脖,我火速辦了婚禮椰苟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘树叽。我一直安慰自己舆蝴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布题诵。 她就那樣靜靜地躺著洁仗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪性锭。 梳的紋絲不亂的頭發(fā)上赠潦,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機(jī)與錄音草冈,去河邊找鬼她奥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛怎棱,可吹牛的內(nèi)容都是我干的哩俭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼拳恋,長吁一口氣:“原來是場噩夢啊……” “哼凡资!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起诅岩,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤讳苦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后吩谦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸳谜,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年式廷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咐扭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蝗肪,靈堂內(nèi)的尸體忽然破棺而出袜爪,到底是詐尸還是另有隱情,我是刑警寧澤薛闪,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布辛馆,位于F島的核電站,受9級特大地震影響豁延,放射性物質(zhì)發(fā)生泄漏昙篙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一诱咏、第九天 我趴在偏房一處隱蔽的房頂上張望苔可。 院中可真熱鬧,春花似錦袋狞、人聲如沸焚辅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽同蜻。三九已至,卻和暖如春倔毙,著一層夾襖步出監(jiān)牢的瞬間埃仪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工陕赃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卵蛉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓么库,卻偏偏與公主長得像傻丝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子诉儒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 本文試圖用有限的篇幅來闡述80386保護(hù)模式重要知識點(diǎn)葡缰。本文不是一個(gè)系統(tǒng)全面的知識介紹,您可能需要了解相關(guān)的803...
    JeffreyLi閱讀 2,097評論 0 10
  • 最近開始想稍微深入一點(diǎn)地學(xué)習(xí)Linux內(nèi)核忱反,主要參考內(nèi)容是《深入理解Linux內(nèi)核》和《深入理解Linux內(nèi)核架構(gòu)...
    ice_camel閱讀 1,779評論 0 2
  • 1 內(nèi)存尋址 1.1 物理地址泛释、虛擬地址以及線性地址 物理地址: 物理內(nèi)存的內(nèi)存單元地址 虛擬地址: 程序員看到的...
    瘋狂小王子閱讀 2,793評論 3 21
  • 但是我早早的起來了卻在玩手機(jī)。持續(xù)性一事無成温算。這不是搬起石頭砸自己腳嗎怜校? 解決拖延癥的方法最好就是硬剛 在學(xué)習(xí)上一...
    Charging99閱讀 127評論 0 0
  • 照片加上水中倒影之后,感覺整個(gè)世界都不一樣了注竿。
    小輯輕渡閱讀 311評論 0 0