国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
I386的體系結(jié)構(gòu)(上) - CSDN_document的專欄 - CSDNBlog
本期上半部分將和網(wǎng)友一起聊聊I386體系結(jié)構(gòu),認(rèn)識(shí)一下Intel系統(tǒng)中的內(nèi)存尋址和虛擬內(nèi)存的來(lái)龍去脈。下半部分將實(shí)現(xiàn)一個(gè)最最短小的可啟動(dòng)內(nèi)核,一是加深對(duì)i386體系的了解,再就是演示系統(tǒng)開(kāi)發(fā)的原始過(guò)程。作為實(shí)例我們將分析計(jì)算機(jī)的啟動(dòng)流程,然后著手學(xué)習(xí)開(kāi)發(fā)一個(gè)基于I386體系的可啟動(dòng)系統(tǒng)

 

 

內(nèi)存尋址

 

 

曾經(jīng)有一個(gè)叫阿蘭.圖靈的天才,它設(shè)想出了一種簡(jiǎn)單但運(yùn)算能力幾乎無(wú)限發(fā)達(dá)的理想機(jī)器——這可不是一個(gè)具體的機(jī)械玩藝,而是一個(gè)思想模型——用來(lái)計(jì)算能想象得到的所有可計(jì)算函數(shù)。這個(gè)有趣的機(jī)器由一個(gè)控制器,一個(gè)讀寫(xiě)頭和一條假設(shè)兩端無(wú)限長(zhǎng)的帶子組成。工作帶好比存儲(chǔ)器,被劃分成大小相同的格子,每格上可寫(xiě)一個(gè)字母,讀寫(xiě)頭可以在工作帶上隨意移動(dòng),而控制器可以要求讀寫(xiě)頭讀取下方工作帶上的字母。

 

 

你可千萬(wàn)別覺(jué)得這個(gè)機(jī)器傻可愛(ài),它可是當(dāng)代.諾依曼體系計(jì)算機(jī)的理論鼻祖。它帶來(lái)的數(shù)據(jù)連續(xù)存儲(chǔ)和選擇讀取思想可是目前我們使用的幾乎所有機(jī)器運(yùn)行背后的靈魂。計(jì)算機(jī)體系結(jié)構(gòu)中的核心問(wèn)題之一就是如何有效地進(jìn)行內(nèi)存尋址,因?yàn)樗羞\(yùn)算的前提都是先要從內(nèi)存中取得數(shù)據(jù),所以內(nèi)存尋址技術(shù)從某種程度上代表了了計(jì)算機(jī)技術(shù)。

 

 

下面就開(kāi)始一起聊聊關(guān)于尋址的故事。

 

 

.諾依曼體系計(jì)算機(jī)系統(tǒng)由運(yùn)算器、存儲(chǔ)器、控制器、輸入設(shè)備、輸出設(shè)備五大部件組成。運(yùn)算器就是我們熟知的CPU中的AUL(算術(shù)邏輯單元),存儲(chǔ)器是內(nèi)存,控制器是CPU中的控制單元;輸入設(shè)備就是我們的鼠標(biāo)鍵盤等;輸出設(shè)備就是顯示器,打印機(jī)等。

 

 

歷史回顧

 

計(jì)算機(jī)的內(nèi)存尋址技術(shù)和世界上的其它事物一樣都經(jīng)歷了由簡(jiǎn)單到復(fù)雜,由笨拙到優(yōu)雅的過(guò)程。自我聽(tīng)說(shuō)計(jì)算機(jī)到今天,內(nèi)存尋址方法發(fā)生了幾次決定性的變革(史前的內(nèi)存尋址方法我連資料都沒(méi)由找到,真是無(wú)據(jù)可查了),而每次變革都帶來(lái)了軟件技術(shù)的發(fā)展注入了新鮮血液。

讓我們沿著Intel公司的腳步來(lái)回顧一下歷史吧!(我實(shí)在沒(méi)機(jī)會(huì)接觸除Intel以外的處理器!!!

 

 

石器時(shí)代

 

    20年前intel推出了一款8位處理器——8080,它有1個(gè)主累加器(寄存器A)和6個(gè)次累加器(寄存器B,C,D,E,HL,幾個(gè)次累加器可以配對(duì)(如組成BC, DEHL)使用來(lái)訪問(wèn)16位的內(nèi)存地址,也就是說(shuō)8080可訪問(wèn)到64K內(nèi)的地址空間。另外那時(shí)還沒(méi)有段的概念,訪問(wèn)內(nèi)存都要通過(guò)絕對(duì)地址,因此程序中的地址必須進(jìn)行硬編碼,而且也難以重定位,因此當(dāng)時(shí)的軟件都是可控性弱,結(jié)構(gòu)簡(jiǎn)陋,數(shù)據(jù)處理量小的工控程序。

 

 

人類從來(lái)都是不斷前進(jìn)的,很快幾年后intel就開(kāi)發(fā)出了16位的新處理器——8086,這便是內(nèi)存尋址的第一次飛躍。

 

 

青銅時(shí)代

 

8086處理器引入了一個(gè)重要概念——。段描述了一塊有限的內(nèi)存區(qū)域,區(qū)域的起始位置存在專門的寄存器(段寄存器)中。另外8086處理器可以尋址1M大的內(nèi)存空間,因?yàn)樗牡刂肪€擴(kuò)展到了20位。可是制造20位的寄存器來(lái)存放內(nèi)存地址在當(dāng)時(shí)顯然要比制造20位的地址線難得多。為了克服困難,intel的工程師們想出了個(gè)好辦法:將內(nèi)存分為數(shù)個(gè)64k大小的段,然后利用兩個(gè)16位值——一個(gè)是段地址,另一個(gè)是段內(nèi)偏移量——巧妙組合產(chǎn)生20位的內(nèi)存地址。換句話說(shuō)就是把1M大的空間分成數(shù)個(gè)64k的段來(lái)管理(化整為零了)。

 

 

系統(tǒng)所需要作的僅僅是:16位的段地址左移動(dòng)4位后,再與16位的偏移量相加便可獲得一個(gè)20位的內(nèi)存地址,見(jiàn)圖1

摘要:本期上半部分將和網(wǎng)友一起聊聊I386體系結(jié)構(gòu),認(rèn)識(shí)一下Intel系統(tǒng)中的內(nèi)存尋址和虛擬內(nèi)存的來(lái)龍去脈。下半部分將實(shí)現(xiàn)一個(gè)最最短小的可啟動(dòng)內(nèi)核,一是加深對(duì)i386體系的了解,再就是演示系統(tǒng)開(kāi)發(fā)的原始過(guò)程。作為實(shí)例我們將分析計(jì)算機(jī)的啟動(dòng)流程,然后著手學(xué)習(xí)開(kāi)發(fā)一個(gè)基于I386體系的可啟動(dòng)系統(tǒng)
 
內(nèi)存尋址
曾經(jīng)有一個(gè)叫“阿蘭.圖靈”的天才,它設(shè)想出了一種簡(jiǎn)單但運(yùn)算能力幾乎無(wú)限發(fā)達(dá)的理想機(jī)器——這可不是一個(gè)具體的機(jī)械玩藝,而是一個(gè)思想模型——用來(lái)計(jì)算能想象得到的所有可計(jì)算函數(shù)。這個(gè)有趣的機(jī)器由一個(gè)控制器,一個(gè)讀寫(xiě)頭和一條假設(shè)兩端無(wú)限長(zhǎng)的帶子組成。工作帶好比存儲(chǔ)器,被劃分成大小相同的格子,每格上可寫(xiě)一個(gè)字母,讀寫(xiě)頭可以在工作帶上隨意移動(dòng),而控制器可以要求讀寫(xiě)頭讀取其下方工作帶上的字母。
你可千萬(wàn)別覺(jué)得這個(gè)機(jī)器傻得可愛(ài),它可是當(dāng)代馮.諾依曼體系計(jì)算機(jī)的理論鼻祖。它帶來(lái)的“數(shù)據(jù)連續(xù)存儲(chǔ)和選擇讀取思想”可是目前我們使用的幾乎所有機(jī)器運(yùn)行背后的靈魂。計(jì)算機(jī)體系結(jié)構(gòu)中的核心問(wèn)題之一就是如何有效地進(jìn)行內(nèi)存尋址,因?yàn)樗羞\(yùn)算的前提都是先要從內(nèi)存中取得數(shù)據(jù),所以內(nèi)存尋址技術(shù)從某種程度上代表了了計(jì)算機(jī)技術(shù)。
下面就開(kāi)始一起聊聊關(guān)于尋址的故事。
馮.諾依曼體系計(jì)算機(jī)系統(tǒng)由運(yùn)算器、存儲(chǔ)器、控制器、輸入設(shè)備、輸出設(shè)備五大部件組成。運(yùn)算器就是我們熟知的CPU中的AUL(算術(shù)邏輯單元),存儲(chǔ)器是內(nèi)存,控制器是CPU中的控制單元;輸入設(shè)備就是我們的鼠標(biāo)鍵盤等;輸出設(shè)備就是顯示器,打印機(jī)等。

歷史回顧

計(jì)算機(jī)的內(nèi)存尋址技術(shù)和世界上的其它事物一樣都經(jīng)歷了由簡(jiǎn)單到復(fù)雜,由笨拙到優(yōu)雅的過(guò)程。自我聽(tīng)說(shuō)計(jì)算機(jī)到今天,內(nèi)存尋址方法發(fā)生了幾次決定性的變革(“史前”的內(nèi)存尋址方法我連資料都沒(méi)由找到,真是無(wú)據(jù)可查了?。看巫兏锒紟?lái)了軟件技術(shù)的發(fā)展注入了新鮮血液。
讓我們沿著Intel公司的腳步來(lái)回顧一下歷史吧!(我實(shí)在沒(méi)機(jī)會(huì)接觸除Intel以外的處理器!!!)

石器時(shí)代

    20年前intel推出了一款8位處理器——8080,它有1個(gè)主累加器(寄存器A)和6個(gè)次累加器(寄存器B,C,D,E,H和L),幾個(gè)次累加器可以配對(duì)(如組成BC, DE或HL)使用來(lái)訪問(wèn)16位的內(nèi)存地址,也就是說(shuō)8080可訪問(wèn)到64K內(nèi)的地址空間。另外那時(shí)還沒(méi)有段的概念,訪問(wèn)內(nèi)存都要通過(guò)絕對(duì)地址,因此程序中的地址必須進(jìn)行硬編碼,而且也難以重定位,因此當(dāng)時(shí)的軟件大都是些可控性弱,結(jié)構(gòu)簡(jiǎn)陋,數(shù)據(jù)處理量小的工控程序。
人類從來(lái)都是不斷前進(jìn)的,很快幾年后intel就開(kāi)發(fā)出了16位的新處理器——8086,這便是內(nèi)存尋址的第一次飛躍。

青銅時(shí)代

8086處理器引入了一個(gè)重要概念——。段描述了一塊有限的內(nèi)存區(qū)域,區(qū)域的起始位置存在專門的寄存器(段寄存器)中。另外8086處理器可以尋址到1M大的內(nèi)存空間,因?yàn)樗牡刂肪€擴(kuò)展到了20位??墒侵圃?0位的寄存器來(lái)存放內(nèi)存地址在當(dāng)時(shí)顯然要比制造20位的地址線難得多。為了克服困難,intel的工程師們想出了個(gè)好辦法:將內(nèi)存分為數(shù)個(gè)64k大小的段,然后利用兩個(gè)16位值——一個(gè)是段地址,另一個(gè)是段內(nèi)偏移量——巧妙組合產(chǎn)生20位的內(nèi)存地址。換句話說(shuō)就是把1M大的空間分成數(shù)個(gè)64k的段來(lái)管理(化整為零了)。
系統(tǒng)所需要作的僅僅是:把16位的段地址左移動(dòng)4位后,再與16位的偏移量相加便可獲得一個(gè)20位的內(nèi)存地址,見(jiàn)圖1

   1

 

 

Intel內(nèi)存地址的描述形式也很貼近上圖,采用了段地址:偏移量的形式來(lái)描述內(nèi)存地址,比如A815:CF2D就代表段首地址在A815,段內(nèi)偏移位CF2D

 

 

為了支持段機(jī)制,8086為程序使用的代碼段,數(shù)據(jù)段,堆棧段分別提供了專門的16位寄存器CS,DSSS,此外還給內(nèi)存和字符串拷貝操作留下了一個(gè)目的段寄存器ES。

 

 

段式內(nèi)存管理帶來(lái)了顯而易見(jiàn)的優(yōu)勢(shì)——程序的地址不再需要硬編碼了,調(diào)試錯(cuò)誤也更容易定位了,更可貴的是支持更大的內(nèi)存地址。程序員開(kāi)始獲得了自由。

 

 

白銀時(shí)代

 

     人們的欲望在繼續(xù)膨脹。intel80286處理器于1982年問(wèn)世了,它的地址總線位數(shù)增加到了24位,因此可以訪問(wèn)到16M的內(nèi)存空間。更重要的是從此開(kāi)始引進(jìn)了一個(gè)新理念——保護(hù)模式。這種模式下內(nèi)存段的訪問(wèn)受到了限制。訪問(wèn)內(nèi)存時(shí)不能直接從段寄存器中獲得段的起始地址了,而需要經(jīng)過(guò)額外轉(zhuǎn)換和檢查(從此你不能在隨意執(zhí)行數(shù)據(jù)段,或向代碼段里寫(xiě)東西了,具體保護(hù)和實(shí)現(xiàn)我們后面講述)。

 

 

為了和過(guò)去兼容,80286內(nèi)存尋址可以以兩種方式進(jìn)行,一種是先進(jìn)的保護(hù)模式,另一種是老式的8086方式,被成為實(shí)模式。啟動(dòng)時(shí)候處理器處于實(shí)模式只能訪問(wèn)1M空間,經(jīng)過(guò)處理可進(jìn)入保護(hù)模式訪問(wèn)空間擴(kuò)大到16M,但是要想想從保護(hù)模式返回到實(shí)模式,你只有重新啟動(dòng)機(jī)器。還有一個(gè)致命的缺陷是80286雖然擴(kuò)大了訪問(wèn)空間,但實(shí)每個(gè)段的大小還是64k,這太糟糕了,程序規(guī)模仍受到壓制。因此這個(gè)先天低能兒注定命不久也。很快它久被它天資卓越的兄弟——80386代替了。

 

 

黃金時(shí)代

 

      真正的第二次內(nèi)存尋址飛躍發(fā)生在80386身上,它近乎完美的設(shè)計(jì)將計(jì)算機(jī)技術(shù)推向了一個(gè)新高度.

 

 

      80386的地址總線擴(kuò)展到了32,可尋址空間一下擴(kuò)充為4G,更為先進(jìn)的是在保護(hù)模式下,它的段范圍不再受限于可憐的64K,可以達(dá)到4k-4G。這一下可真正解放了軟件工程師,他們不必在費(fèi)心思去壓縮程序規(guī)模,軟件功能也因此迅速提升,一切都走向了繁榮.

 

 

 

 

保護(hù)模式

 

        保護(hù)模式真得是太精妙了,我恨不得用專門用一本書(shū)來(lái)討論它,但即使那樣我也擔(dān)心不能真正觸其。不過(guò)還是借用那句老話簡(jiǎn)單就是美麗”,我爭(zhēng)取用最小的篇幅揭示保護(hù)模式的真實(shí)面目。

 

 

實(shí)模式和保護(hù)模式

    保護(hù)模式和實(shí)模式好比一對(duì)孿生兄弟,它們外貌很,從程序角度來(lái)看幾乎看不出什么區(qū)別,它們都是通過(guò)段寄存器去訪問(wèn)內(nèi)存地址,都通過(guò)中斷和設(shè)備驅(qū)動(dòng)程序來(lái)操作硬件,表面上能感覺(jué)得到的差異就是保護(hù)模式能訪問(wèn)的空間是4G,而實(shí)模式只能訪問(wèn)到1M的地址空間。

 

 

    但實(shí)際上保護(hù)模式和實(shí)模式采用了兩種截然不同的思路,保護(hù)模式帶來(lái)的最可貴的優(yōu)點(diǎn)不是單純的擴(kuò)大了內(nèi)存尋址范圍,而是對(duì)內(nèi)存尋址從機(jī)制上提供了保護(hù),將系統(tǒng)的執(zhí)行空間按權(quán)限進(jìn)行了化分。

 

 

    這種劃分到底會(huì)帶來(lái)那些好處啦? 我們來(lái)推敲一下吧

 

 

為什么需要保護(hù)?

如果你的機(jī)器只允許一個(gè)任務(wù)使用系統(tǒng)資源,比如說(shuō)系統(tǒng)內(nèi)存,那么你完全不需要保護(hù)資源,因?yàn)橄到y(tǒng)中再?zèng)]有什么值得你去偷窺的東西了,更別說(shuō)去破壞什么了。

 

 

可惜那樣的時(shí)代已經(jīng)一去不復(fù)返了,如今的系統(tǒng)需要支持多個(gè)用戶同時(shí)運(yùn)行多個(gè)任務(wù)。為了防止你去偷看別人的任務(wù),或惡意或由于你的荒唐行為而破壞別人的任務(wù),系統(tǒng)有責(zé)任將每個(gè)任務(wù)隔離開(kāi)來(lái),讓大家各自運(yùn)行在不同的空間,免收干擾。這就是保護(hù)的第一個(gè)方面——任務(wù)間保護(hù),要做到任務(wù)間保護(hù)需要借助虛擬內(nèi)存技術(shù)(我們后面分析它),其基礎(chǔ)之一就是保護(hù)模式。

 

 

除了任務(wù)間保護(hù)外,另一個(gè)必須保護(hù)的東西就是操作系統(tǒng)本身,它可是資源調(diào)配的首腦呀!決不能讓你有機(jī)可承,擅自進(jìn)入。必須有一道鐵絲網(wǎng),將你和操作系統(tǒng)隔離開(kāi),使你不得越雷池一步。要想拉起這道鐵絲網(wǎng),就需要借助保護(hù)模式中的特權(quán)級(jí)機(jī)制。操作系統(tǒng)放在高特權(quán)級(jí)里,你的任務(wù)被放在特權(quán)級(jí)里。你沒(méi)有權(quán)利去偷看操作系統(tǒng)的內(nèi)容。有什么要求只能請(qǐng)示領(lǐng)導(dǎo)(就是保護(hù)機(jī)制),獲得拼準(zhǔn)后才能給你提供服務(wù)。這點(diǎn)可謂是保護(hù)模式的最直接應(yīng)用。

 

 

誰(shuí)賦予它保護(hù)能力?

80386之所以能有變化多端的保護(hù)手段,追其根本源自保護(hù)模式下內(nèi)存尋址方式發(fā)生革命。傳統(tǒng)上我們知道段方式尋址時(shí),是直接從段寄存器中取得的段的首地址,但是在保護(hù)模式中是要多經(jīng)過(guò)一次檢查手續(xù)才能獲得想要的段地址。

 

 

這里可千萬(wàn)別說(shuō)簡(jiǎn)單就是美了,多了這一次中間倒手過(guò)程可是保護(hù)模式下尋址的關(guān)鍵技術(shù)所在。倒手的原因我想大概是因?yàn)?,雖然80386有的通用寄存器(EAX,EDI等等)被擴(kuò)充倒了32位,但是其中的段寄存器(DS,ES等)仍然只有16位,顯然不可能再用16位的段寄存器直接存放4G空間需要的32位地址了,所以必須引入了一種間接辦法——將段寄存器種存放的地址換成一個(gè)索引指針,尋址時(shí)不再從段寄存器種去地址,而是先取指針,再通過(guò)該指針?biāo)阉饕粋€(gè)系統(tǒng)維護(hù)的查找表讀出所需段的具體信息。剩下的動(dòng)作和傳統(tǒng)行為沒(méi)什么區(qū)別,將剛剛?cè)〉玫亩蔚幕刂芳由掀屏?/font>便構(gòu)成了一個(gè)32地址(即,線性地址)。

線性地址屬于中間地址,它還需要一次轉(zhuǎn)換才能映射到實(shí)際的物理地址上(下面會(huì)看到)。線性地址長(zhǎng)成的空間稱為線性空間,它和物理地址空間結(jié)構(gòu)想同,都為32位,最大可達(dá)4G。

 

 

 

 

這個(gè)索引指針被稱作是段選擇子(見(jiàn)圖2),它共有16位,其中14位用來(lái)作為索引,另外2位(RPL)用來(lái)作描述請(qǐng)求特權(quán)級(jí)。通過(guò)索引從表中獲得的信息,被稱為段描述符,它含有段的相關(guān)地址信息等。

 

 

改變尋址方法的另一個(gè)原因主要是為了完成保護(hù)使命。多用戶多任務(wù)環(huán)境下,內(nèi)存尋地工作不再是簡(jiǎn)單地取得32位的內(nèi)存地址就可以直接不假思索地放到地址總線上去了讀寫(xiě)內(nèi)存了,此刻必須先要對(duì)需訪問(wèn)的地址進(jìn)行合法性檢查,看看訪問(wèn)者是不是有權(quán)利去訪問(wèn)它要求的地址。如果發(fā)現(xiàn)有非法訪問(wèn)企圖,則立刻阻止(CPU會(huì)產(chǎn)生一個(gè)一異常)這種危險(xiǎn)行為。讀到這里,多數(shù)的朋友一定要問(wèn),靠什么進(jìn)行檢查請(qǐng)求的合法性呢?更細(xì)心的朋友還會(huì)繼續(xù)問(wèn),檢查需要什么信息?這些信息放在那里?

 

 

考慮到尋址過(guò)程和合法性檢測(cè)過(guò)程需要在同一現(xiàn)場(chǎng)一進(jìn)行,所以最理想是能把段地址信息和檢測(cè)合法性用到的屬性信息能放在一起(需要的空間更大了),于是系統(tǒng)設(shè)計(jì)師門便把屬性信息和段的基地址和界限都柔和在了一起,形成了一個(gè)新的信息單元——段描述符號(hào),它整整占用了8個(gè)字節(jié)。顯然寄存器太小,不夠存放段描述符,所以段描述符都被統(tǒng)一存在專門的系統(tǒng)段描述符號(hào)表中(GTDLDT)保存。

 

 

說(shuō)到這里,聰明的朋友可能已經(jīng)能大概猜出段描述符表中的內(nèi)容是什么了。內(nèi)容里一定包含了段基地址、短的大小信息、段的屬性信系,而且在屬性信息里包含了還有和訪問(wèn)權(quán)限有關(guān)的信息。的確如此,下面圖示描述了段描述符的詳細(xì)信息,其中和保護(hù)關(guān)心最大的信息要數(shù)DPL(見(jiàn)圖3)。

 

 

這種間接尋址方式不僅體現(xiàn)在普通任務(wù)尋址上,而且對(duì)于中斷處理同樣適用。傳統(tǒng)上中斷處理查詢方法是在中斷產(chǎn)生后,CPU會(huì)在中斷向量表中搜索中斷服務(wù)例程(ISR)的地址,地址形式還是段+偏移量。在保護(hù)模式中中斷產(chǎn)生后,CPU會(huì)從中斷描述符表(IDT)中根據(jù)中斷號(hào)取得中斷服務(wù)例程的段選擇子和偏移量,然后通過(guò)段選擇子從段描述附表(GDT)中獲得ISR的段信息再結(jié)合偏移量得到需要的實(shí)際物理地址。

 

 

中斷尋址過(guò)程如圖4

特權(quán)等級(jí)

       計(jì)算機(jī)世界和人類世界一樣最初是沒(méi)有等級(jí)之分的,但當(dāng)人類社會(huì)物質(zhì)文明逐步發(fā)達(dá)后,等級(jí)也隨之而來(lái)了;同樣當(dāng)計(jì)算機(jī)上的應(yīng)用軟件越來(lái)月豐富后,這個(gè)虛擬世界也逐漸形成了級(jí)別等級(jí)。我們不去評(píng)價(jià)人類社會(huì)等級(jí)制度,我們只來(lái)看看計(jì)算機(jī)世界中的等級(jí)制度,而且只陷于保護(hù)模式中的等級(jí)制度。

 

 

    80386中共規(guī)定有4個(gè)特權(quán)級(jí),由03。0級(jí)別權(quán)限最高,3級(jí)最小。標(biāo)準(zhǔn)的作法是將操作系統(tǒng)核心運(yùn)行在0級(jí),應(yīng)用程序運(yùn)行其它幾個(gè)低級(jí)別。不過(guò)為了簡(jiǎn)化操作,往往只會(huì)用到03兩個(gè)級(jí)別。80386中的每個(gè)段描述符號(hào)中都有DPL字段,它規(guī)定了訪問(wèn)該段的最低特權(quán)級(jí),只用高于次特權(quán)級(jí)別的程序能有權(quán)訪問(wèn)它。所以在訪問(wèn)內(nèi)存地址時(shí)要將當(dāng)前特權(quán)級(jí)(CPL,一般來(lái)說(shuō)就是當(dāng)前代碼段的特權(quán)級(jí)別)和被訪問(wèn)段的特權(quán)級(jí)別比較,如果大于等于才允許訪問(wèn)。

 

 

    處理當(dāng)前特權(quán)級(jí)別和段的特權(quán)級(jí)別外,有時(shí)還需要使用請(qǐng)求特權(quán)級(jí)別(RPL),這個(gè)子段出自段選擇字,主要用來(lái)輔助特權(quán)保護(hù)。比如可以在訪問(wèn)某個(gè)段時(shí),指定其請(qǐng)求特權(quán)級(jí),那么特權(quán)檢查時(shí),規(guī)則變?yōu)閷?span lang="EN-US" twffan="done">RPLCPL中特權(quán)更高的那個(gè)和被訪問(wèn)段的DPL比較。例如,操作系統(tǒng)中的某個(gè)例程會(huì)把一些資料寫(xiě)到用戶段中。若沒(méi)有特別檢查,那么用戶可以把一個(gè) DPL 0 的 段(用戶程序不能存取它)傳到操作系統(tǒng)處理例程中,因?yàn)橄到y(tǒng)例程有全權(quán)寫(xiě)入DPL0的段,因此用戶程序就可以破壞該段中的資料了。為了避免這個(gè)問(wèn)題,系統(tǒng) API 在存取用戶傳入的段時(shí),可以先把該段選擇子的 RPL設(shè)定成和用戶程序的 CPL 相同,就不會(huì)意外寫(xiě)入原先用戶無(wú)權(quán)存取的段了。 (RPLlinux好像沒(méi)被怎么)

 

 

 

 

虛擬內(nèi)存

 

     虛擬內(nèi)存可是個(gè)怎么強(qiáng)調(diào)也不過(guò)分的概念,它的存在極大方便了程序設(shè)計(jì)任務(wù),徹底解放了程序員的手腳。下面我們就看看虛擬內(nèi)存的作用以及如何在存儲(chǔ)管理機(jī)制的基礎(chǔ)上實(shí)現(xiàn)它

 

 

什么是虛存?為什么需要它?

    我們知道程序代碼和數(shù)據(jù)必須駐留在內(nèi)存中才能得以運(yùn)行,然而系統(tǒng)內(nèi)存數(shù)量很有限,往往不能容納一個(gè)完整程序的所有代碼和數(shù)據(jù),更何況在多任務(wù)系統(tǒng)中,可能需要同時(shí)開(kāi)子處理程序,畫(huà)圖程序,瀏覽器等很多任務(wù),想讓內(nèi)存駐留所有這些程序顯然不大可能。因此我們能首先能想到的就是將程序分割成小分,只讓當(dāng)前系統(tǒng)運(yùn)行它所有需要的那部分留在內(nèi)存,其它部分都留在硬盤。當(dāng)系統(tǒng)處理當(dāng)前任務(wù)片段后,再?gòu)耐獯嬷姓{(diào)入下一個(gè)待運(yùn)行的任務(wù)片段。的確老式系統(tǒng)的確這樣處理大任務(wù),而且這個(gè)工作是由程序員自行完成。但是隨之程序語(yǔ)源越來(lái)越高級(jí),程序員對(duì)系統(tǒng)體系的依賴程度降低了,很少有程序員能非常清楚的駕馭系統(tǒng)體系了,因此放手讓程序員負(fù)責(zé)將程序片段化和按需調(diào)入輕則降低效率,重則使得機(jī)器崩潰;再一個(gè)原因是隨程序越來(lái)越豐富,程序行為幾乎無(wú)法準(zhǔn)確預(yù)測(cè),程序員自己都很判斷下一步需要載入那段程序。因此很難再靠預(yù)見(jiàn)性靜態(tài)分配固定大小的內(nèi)存,然后再機(jī)械地輪換程序片進(jìn)內(nèi)存執(zhí)行。系統(tǒng)必須采取一種能按需分配,不要程序員干預(yù)地新技術(shù)。

 

 

    虛擬內(nèi)存[1]技術(shù)就是一種由操作系統(tǒng)接管的按需動(dòng)態(tài)內(nèi)存分配方法,它允許程序覺(jué)種使用大于實(shí)際物理的存儲(chǔ)空間(其實(shí)是將程序需要的存儲(chǔ)空間以頁(yè)的形式分散存儲(chǔ)在物理內(nèi)存和磁盤上),所以說(shuō)虛擬內(nèi)存徹底解放了程序員,從此程序員不用過(guò)分關(guān)心程序大小和載入,可以自由編寫(xiě)程序繁瑣的事情交給操作系統(tǒng)去作吧。

 

 

 

 

實(shí)現(xiàn)虛擬內(nèi)存

    虛擬內(nèi)存是將系統(tǒng)硬盤空間和系統(tǒng)實(shí)際內(nèi)存聯(lián)合在一起為進(jìn)程使用,給進(jìn)程提供了一個(gè)內(nèi)存大的多的虛擬空間。在程序運(yùn)行時(shí),只把虛擬地址空間的一小部分映射到內(nèi)存,其余都存儲(chǔ)在硬盤上(也就是說(shuō)程序虛擬空間就等于實(shí)際物理內(nèi)存加部分硬盤空間)。當(dāng)訪問(wèn)被訪問(wèn)的虛擬地址的不在內(nèi)存時(shí),則說(shuō)明該地址未被映射到內(nèi)存,而是被存貯在硬盤中,因此需要的虛擬存儲(chǔ)地址被隨即調(diào)入到內(nèi)存;同時(shí)當(dāng)系統(tǒng)內(nèi)存緊張時(shí),也可以把當(dāng)前不用的虛擬存儲(chǔ)空間換出到硬盤,來(lái)騰出物理內(nèi)存空間。系統(tǒng)如此周而復(fù)地運(yùn)轉(zhuǎn)——換入、換出,而用戶幾乎無(wú)法查覺(jué),這都是拜虛擬內(nèi)存機(jī)制所賜。

 

 

    Linuxswap分區(qū)就是硬盤專門為虛擬存儲(chǔ)空間預(yù)留的空間。經(jīng)驗(yàn)大小應(yīng)該是內(nèi)存的兩倍左右。有興趣的話可以使用 swapon -s 查看交換分區(qū)大小,還可以用vmstat 查看當(dāng)前每秒換入換出的數(shù)據(jù)大小(si/so字段)

 

 

    大道理很好理解,無(wú)非是用內(nèi)存和硬盤空間合成為虛擬內(nèi)存空間。但是這一過(guò)程中反復(fù)運(yùn)行的地址映射(虛擬地址映射到物理地址)和虛擬地址換入換出卻值得仔細(xì)推敲。系統(tǒng)到底是怎么樣吧虛擬地址映射到物理地址上的呢??jī)?nèi)存又如何能不斷的和硬盤之間換入換出虛擬地址呢?

 

 

    利用段機(jī)制能否回答上述問(wèn)題呢?我們上面提到過(guò)邏輯地址通過(guò)段機(jī)制后變?yōu)橐粋€(gè)32位的地址,足以覆蓋4G的內(nèi)存空間,而系統(tǒng)內(nèi)存一般也就幾百M吧,所以當(dāng)程序需要的虛擬地址不在內(nèi)存時(shí),只依靠段機(jī)制很難進(jìn)行虛擬空間地換入換出,因?yàn)?/span>大方便整段大小的虛擬空間在內(nèi)存和硬盤之間調(diào)來(lái)調(diào)去(老式系統(tǒng)中,會(huì)笨拙地?fù)Q出整段內(nèi)存甚至整個(gè)進(jìn)程,想想這樣作會(huì)有那些惡果吧?。?。所以很有必要尋找一個(gè)更小更靈活的存儲(chǔ)表示單位,這樣才方便虛擬地址在硬盤和內(nèi)存之間調(diào)入調(diào)出。這個(gè)更小的存儲(chǔ)管理單位便是頁(yè)(4K大?。?/font>。管理頁(yè)換入換入的機(jī)制別稱為頁(yè)機(jī)制

 

 

     因?yàn)槭褂?/span>頁(yè)機(jī)制的原因,通過(guò)段機(jī)制轉(zhuǎn)換得到的地址僅僅是作為一個(gè)中間地址——線性地址了,該地址不代表實(shí)際物理地址,而是代表整個(gè)進(jìn)程虛擬空間地址。在線性地址的基礎(chǔ)上,頁(yè)機(jī)制接著會(huì)處理線性地址映射:當(dāng)需要的線性地址(虛擬空間地址)不在內(nèi)存時(shí),便以頁(yè)為單位從磁盤中調(diào)入需要的虛擬內(nèi)存;當(dāng)內(nèi)存不夠時(shí),又會(huì)以頁(yè)為單位把內(nèi)存中虛擬空間的換出到磁盤上。可見(jiàn)利用頁(yè)來(lái)管理內(nèi)存和磁盤(虛擬內(nèi)存)大大方便了內(nèi)存管理的工作。毫無(wú)疑問(wèn)頁(yè)機(jī)制是虛擬內(nèi)存管理簡(jiǎn)直是“天配”

 

 

     使用頁(yè)機(jī)制,4G空間被分成220次方個(gè)4K大小的頁(yè)面(頁(yè)面也可定為4M大小),因此定位頁(yè)面需要的索引表(頁(yè)表)中每個(gè)索引項(xiàng)至少需要20位,但是在頁(yè)表項(xiàng)中往往還需要附加一些頁(yè)屬性,所以頁(yè)表項(xiàng)實(shí)際為32位,其中12位用來(lái)存放諸如頁(yè)是否存在內(nèi)存”或“頁(yè)的權(quán)限等信息。

 

 

     前面我們提到了線性地址32。它其中高20對(duì)頁(yè)表的索引,低12位則給出了頁(yè)面中的偏移。線性地址經(jīng)過(guò)頁(yè)表找到頁(yè)框基地址后和12偏移相加就形成了最終需要的物理地址。

 

 

     在實(shí)際使用中,并非所有頁(yè)表項(xiàng)都是被存放在一個(gè)大頁(yè)表里,因?yàn)槊總€(gè)頁(yè)表項(xiàng)4字節(jié),如果要在一個(gè)表中存放220次方個(gè)頁(yè)表項(xiàng),就需要4M的連續(xù)存儲(chǔ)空間。這么大的連續(xù)空間可不好找,因此往往會(huì)把頁(yè)表分級(jí)存儲(chǔ),比如分兩級(jí),那么每級(jí)頁(yè)表只需要4k連續(xù)空間了。

 

 

     兩級(jí)頁(yè)表搜索如同看章回小說(shuō),先找到在那一章里,然后在找在該章下那一節(jié)。具體過(guò)程看看下圖5。

 

 



[1] .之所以稱為虛擬內(nèi)存是和系統(tǒng)中的邏輯內(nèi)存和物理內(nèi)存而言的,邏輯內(nèi)存是站在進(jìn)程角度看到的內(nèi)存,因此是程序員關(guān)心的內(nèi)容。而物理內(nèi)存是站在處理器角度看到的內(nèi)存,由操作系統(tǒng)負(fù)責(zé)管理。虛擬內(nèi)存可以說(shuō)是這映射這兩種同視角內(nèi)存的一個(gè)技術(shù)手段。

 

 

 

 

綜上所述。地址轉(zhuǎn)換工作需要兩種技術(shù),一是段機(jī)制,二是頁(yè)機(jī)制。段機(jī)制處理邏輯地址向線性地址映;頁(yè)機(jī)制則負(fù)責(zé)把線性地址映射為物理地址。兩級(jí)映射一同完成了從程序員看到的邏輯地址轉(zhuǎn)換到處理器看到的物理地址這一艱巨任務(wù)。

 

 

   你可以將這兩種機(jī)制分別比作一個(gè)地址轉(zhuǎn)換函數(shù),段機(jī)制的變量是邏輯地址,函數(shù)值是線性地址;頁(yè)機(jī)制的變量是線性地址,函數(shù)值是物理地址。地址轉(zhuǎn)換過(guò)程如下所示。

 

 

 

 

    邏輯地址——(段函數(shù))——>線性地址——(頁(yè)函數(shù))——>物理地址。

 

 

 

 

    雖然段機(jī)制和頁(yè)機(jī)制都參與映射,但它們分工不同,而且相互獨(dú)立互不干擾,彼此之間不必知道對(duì)方是否存在。

 

 

說(shuō)了這么多道理,下面我們結(jié)合Linux實(shí)例簡(jiǎn)要地看看段頁(yè)機(jī)制如何使用。

 

 

Linux分段段策略

 

     段機(jī)制在Linux里用得有限,并沒(méi)有被完全利用。每個(gè)任務(wù)并未分別安排各自獨(dú)立的數(shù)據(jù)段,代碼段,而是僅僅最低限度的利用段機(jī)制來(lái)隔離用戶數(shù)據(jù)和系統(tǒng)數(shù)據(jù)——Linux只安排了四個(gè)范圍一樣的段,內(nèi)核數(shù)據(jù)段,內(nèi)核代碼段,用戶數(shù)據(jù)段,用戶代碼段,它們都覆蓋0-4G的空間所不同的是各段屬性不同,內(nèi)核段特權(quán)級(jí)為0,用戶段特權(quán)級(jí)為3。這樣分段,避免了邏輯地址到線性地址轉(zhuǎn)換步驟(邏輯地址就等于線性地址),但仍然保留了段的等級(jí)這層最基本保護(hù)

 

 

     每個(gè)用戶進(jìn)程都可以看到4G大小的線性空間,其中0-3G是用戶空間,用戶態(tài)進(jìn)程可以直接訪問(wèn);從3G-4G空間為內(nèi)核空間,存放內(nèi)核代碼和數(shù)據(jù),只有內(nèi)核態(tài)進(jìn)程能夠直接訪問(wèn),用戶態(tài)進(jìn)程不能直接訪問(wèn),只能通過(guò)系統(tǒng)調(diào)用和中斷進(jìn)入內(nèi)核空間,而這是就要進(jìn)行特權(quán)切換。

 

 

     說(shuō)到特權(quán)切換,就離不開(kāi)任務(wù)門,陷阱門/中斷門等概念。陷阱門和中斷門是在發(fā)生陷阱和中斷時(shí),進(jìn)入內(nèi)核空間的通道。調(diào)用門是用戶空間程序相互訪問(wèn)時(shí)所需要的通道,任務(wù)門比較特殊,它不含如何地址,而是服務(wù)于任務(wù)切換linux任務(wù)切換時(shí)并未真正采用它,它太麻煩了)。

 

 

     對(duì)于各種門系統(tǒng)都會(huì)有對(duì)應(yīng)的門描述符,和段描述符結(jié)構(gòu)類似,門描述符也是由對(duì)應(yīng)的門選擇字索引,并且最終會(huì)產(chǎn)生一個(gè)指向特定段內(nèi)偏移地址的指針。這個(gè)指針就指向的是將要進(jìn)入的入口。利用門的目的就是保證入口可控,不至于進(jìn)入到內(nèi)核中不該訪問(wèn)的位置(回憶前面講到的中斷服務(wù)程序?qū)ぶ罚渲袕闹袛嗝枋龇?hào)表中獲得的就是中斷門的描述符,而描述符則制定了具體的入口位置)。

 

 

 

 

 

Linux中的分頁(yè)

 

我們前面大概談了談為什么要使用分頁(yè),這里看看linux中如何使用分頁(yè)。

 

 

Linux中每個(gè)進(jìn)程都會(huì)有個(gè)自的不同的頁(yè)表,也就是說(shuō)進(jìn)程的映射函數(shù)互不相同,保證每個(gè)進(jìn)程虛擬地址不會(huì)映射到相同的物理地址上。這是因?yàn)檫M(jìn)程之間必須相互獨(dú)立,各自的數(shù)據(jù)必須隔離,防止信息泄漏。

 

 

另外需要注意的是,內(nèi)核作為必須保護(hù)的單獨(dú)部分,有自己獨(dú)立的頁(yè)表來(lái)映射內(nèi)核空間(并非全部空間,僅僅是物理內(nèi)存大小空間),頁(yè)表(swapper_pg_dir)被靜態(tài)分配,它只來(lái)映射內(nèi)核空間(swapper_pg_dir只用到768項(xiàng)以后的項(xiàng)——768個(gè)頁(yè)目錄可映射3G空間)。這個(gè)獨(dú)立頁(yè)表保證了內(nèi)核虛擬空間獨(dú)立于其他用戶程序空間,也就是說(shuō)其他進(jìn)程通常狀態(tài)和內(nèi)核是沒(méi)有聯(lián)系(在編譯內(nèi)核的時(shí)候,內(nèi)核代碼被制定鏈接到3G以上空間),因而內(nèi)核數(shù)據(jù)也就自然被保護(hù)起來(lái)了

 

 

那么在用戶進(jìn)程需要訪問(wèn)內(nèi)核空間時(shí)如何作呢?

 

 

Linux采用了個(gè)巧妙的方法:用戶進(jìn)程頁(yè)表的前768項(xiàng)映射進(jìn)程空間(<3G,因?yàn)?/span>LDT 中只指定基地址為0,范圍只0xc0000000),如果進(jìn)程要訪問(wèn)內(nèi)核空間,如調(diào)用系統(tǒng)調(diào)用,則進(jìn)程的頁(yè)目錄中768項(xiàng)后的項(xiàng)指向swapper_pg_dir768項(xiàng)后的項(xiàng),所以一旦用戶陷入內(nèi)核,開(kāi)始使用內(nèi)核的頁(yè)表swapper_pg_dir了,也就是說(shuō)可以訪問(wèn)內(nèi)核空間了。頁(yè)機(jī)制就說(shuō)到這里,許多地方時(shí)需要網(wǎng)友們自己感悟的。

 

 

 

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
操作系統(tǒng)內(nèi)存
Linux內(nèi)核空間內(nèi)存管理(一):內(nèi)存尋址、內(nèi)存管理機(jī)制綜述
內(nèi)存邏輯地址到物理地址轉(zhuǎn)化
PAE真的能提升虛擬地址空間嗎
實(shí)模式和保護(hù)模式
操作系統(tǒng)的內(nèi)存與空間
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服