www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號(hào)精選 > IOT物聯(lián)網(wǎng)小鎮(zhèn)
[導(dǎo)讀]作?者:道哥,10年嵌入式開發(fā)老兵,專注于:C/C、嵌入式、Linux。關(guān)注下方公眾號(hào),回復(fù)【書籍】,獲取Linux、嵌入式領(lǐng)域經(jīng)典書籍;回復(fù)【PDF】,獲取所有原創(chuàng)文章(PDF格式)。目錄問題描述CPU接收的是線性地址,不是物理地址對(duì)頁目錄進(jìn)行"自操作"一級(jí)查表:構(gòu)造線性地址的...

作  者:道哥,10 年嵌入式開發(fā)老兵,專注于:C/C 、嵌入式、Linux。


關(guān)注下方公眾號(hào),回復(fù)【書籍】,獲取 Linux、嵌入式領(lǐng)域經(jīng)典書籍;回復(fù)【PDF】,獲取所有原創(chuàng)文章( PDF 格式)。



目錄


  • 問題描述


    • CPU接收的是線性地址,不是物理地址


  • 對(duì)頁目錄進(jìn)行"自操作"


    • 一級(jí)查表:構(gòu)造線性地址的前十位


    • 二級(jí)查表:構(gòu)造線性地址的中間十位


    • 三級(jí)查表:構(gòu)造線性地址的最后十二位


    • 三個(gè)地址段合體


  • 對(duì)頁表進(jìn)行"自操作"


在x86系統(tǒng)中,內(nèi)存管理中的分頁機(jī)制是非常重要的,在Linux操作系統(tǒng)相關(guān)的各種書籍中,這部分內(nèi)容也是重筆濃彩。


如果你看過Linux內(nèi)核相關(guān)書籍,一定對(duì)下面這張圖又熟悉、又恐懼:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?這是Linux系統(tǒng)中,頁處理單元的多級(jí)頁表查詢方式。


其中黃色背景部分:頁上級(jí)目錄索引 和 頁中間目錄索引,是 Linux 系統(tǒng)自己擴(kuò)展的,在原本的x86處理器中是不存在的,這也是導(dǎo)致Linux中相關(guān)部分代碼更加復(fù)雜的原因。


在上一篇文章中,我們主要對(duì)x86中的頁目錄和頁表的“反向構(gòu)造”、“正向查找”這兩個(gè)過程進(jìn)行了圖文并茂的討論。文章鏈接在此:Linux從頭學(xué)15:【頁目錄和頁表】-理論 實(shí)例 圖文的最完全、最接地氣詳解!,但是其中有一個(gè)環(huán)節(jié)被特意忽略過去了。


那就是:在操作系統(tǒng)構(gòu)造頁目錄和頁表的時(shí)候,如何對(duì)它們自身進(jìn)行尋址和操作?


這部分內(nèi)容,也是內(nèi)存管理中比較復(fù)雜的地方,就好比一名醫(yī)生給病人做手術(shù),但是病人卻是“醫(yī)生自己”。


這篇文章,我們繼續(xù)通過圖片 實(shí)例的方式,一起來研究一下內(nèi)核代碼一般都是如何來進(jìn)行這些“自操作”的。


把這里面的操作機(jī)制研究透徹之后,再去看Linux內(nèi)核代碼時(shí),就不會(huì)暈頭轉(zhuǎn)向了。


問題描述

在上一篇文章中,我們舉了這樣一個(gè)示例:


  1. 假設(shè)實(shí)際的物理內(nèi)存是1 GB;


  2. 用戶程序文件在硬盤上的長(zhǎng)度是20 MB;


  3. 操作系統(tǒng)把用戶程序加載到內(nèi)存中時(shí),從 0x4000_0000 的虛擬內(nèi)存地址處開始存放;


  4. 操作系統(tǒng)讀取程序結(jié)束后,為所有的地址構(gòu)造好了頁目錄和頁表;


如下圖所示:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?頁目錄和頁表的每一個(gè)有效表項(xiàng)中,存儲(chǔ)的地址都是一個(gè)個(gè)實(shí)實(shí)在在的物理頁的前 20 位(因?yàn)橐粋€(gè)物理頁的長(zhǎng)度固定是4KB,在分配時(shí)都是對(duì)齊的,末尾的 12 位全部為 0)。


并且頁目錄和頁表“們”自身,都占用一個(gè)物理頁的空間,所以它們都有自己的物理地址。


當(dāng)頁目錄和頁表都構(gòu)造妥當(dāng)之后,處理器面對(duì)一個(gè)線性地址,例如:0x4100_1800,頁處理單元就會(huì)按照分級(jí)查表的方式,把這個(gè)線性地址轉(zhuǎn)換為一個(gè)物理地址:


  1. 拆分線性地址:0x4100_1800 = 0100_0001_0000_0000___0001_1000_0000_0000;


  2. 根據(jù)線性地址的前 10 位,找到頁目錄中的索引 260,從而確定頁表的物理地址是 0x0800_4000(表項(xiàng)中的值是 0x08004,還要補(bǔ)上低位的 12 個(gè) 0);


  3. 根據(jù)線性地址的中間 10 位,找到 0x0800_4000 這個(gè)頁表中的索引 1,從而確定普通物理頁的物理地址是 0x0210_1000(表項(xiàng)中的值是 0x02101,還要補(bǔ)上低位的 12 個(gè) 0);


  4. 根據(jù)線性地址的最后 12 位,確定普通頁內(nèi)的偏移量是 2048,普通頁的開始地址加上這個(gè)偏移量,就得到了最終的物理地址 0x0210_1800。


詳細(xì)的討論過程,請(qǐng)參考上一篇文章:Linux從頭學(xué)15:【頁目錄和頁表】-理論 實(shí)例 圖文的最完全、最接地氣詳解!。


那么,問題來了:


在頁處理單元開啟的情況下,處理器面對(duì)的是線性地址,那么操作系統(tǒng)在構(gòu)造頁目錄中的每一個(gè)表項(xiàng)的時(shí)候,如何對(duì)這個(gè)表項(xiàng)進(jìn)行尋址?


具體到上圖來說就是:操作系統(tǒng)想把第一個(gè)頁表的物理地址0x0800_0000,填寫到頁目錄的第256個(gè)表項(xiàng)中時(shí),那么CPU就需要找到這個(gè)表項(xiàng),這個(gè)表項(xiàng)肯定有物理地址的。


但是,我們不能把這個(gè)表項(xiàng)的物理地址直接告訴CPU,因?yàn)镃PU只接收線性地址,它會(huì)自動(dòng)經(jīng)過分頁單元的處理來得到對(duì)應(yīng)的物理地址。


那么,這個(gè)線性地址的值應(yīng)該是多少呢?


繼續(xù)用實(shí)例來說明,這樣容易理解。


假設(shè)頁目錄所處的物理頁開始地址是0x0100_0000,那么第256個(gè)表項(xiàng)的物理地址就是0x0100_0400。


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?有些小伙伴可能會(huì)說:直接把物理地址0x0100_0400告訴處理器,不就可以了嗎?


這是不對(duì)的!


處理器接收的是線性地址,不是物理地址

因?yàn)楝F(xiàn)在已經(jīng)開啟了分頁處理單元,0x0100_0400是我們最后想得到的物理地址,而處理器只接受線性地址,雖然我們知道這是一個(gè)物理地址,但是處理器不知道?。?


當(dāng)我們給處理器一個(gè)地址的時(shí)候,處理器會(huì)按部就班的對(duì)這個(gè)地址進(jìn)行[段轉(zhuǎn)換],再進(jìn)行[頁轉(zhuǎn)換],這時(shí)才得到它認(rèn)為的物理地址。


由于使用的是“平坦型”的段結(jié)構(gòu),所以這里就忽略了段處理過程,直接討論頁處理過程。


所以,我們應(yīng)該使用某些方法,構(gòu)造出一個(gè)線性地址 addr,讓這個(gè)地址經(jīng)過頁處理單元之后,得到0x0100_0400這個(gè)物理地址:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?這里有點(diǎn)遞歸的味道,又有點(diǎn)像一個(gè)醫(yī)生給他自己做一個(gè)外科手術(shù)!


現(xiàn)在,應(yīng)該明白面對(duì)的問題了吧?


目標(biāo)就是:通過某種方法,構(gòu)造出一個(gè)線性地址addr,并且通過頁處理單元轉(zhuǎn)換之后,得到物理地址0x0100_0400。


對(duì)頁目錄進(jìn)行操作

重新梳理一下思路:如果對(duì)一個(gè)普通物理頁(下文簡(jiǎn)稱為:普通頁)里的一個(gè)地址處的數(shù)據(jù)進(jìn)行操作,需要經(jīng)過3次查表操作:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?從頁表的某個(gè)表項(xiàng)中,找到的那個(gè)物理地址,就是最后要操作的普通物理頁。


現(xiàn)在我們的問題是:需要把頁目錄作為最終的操作對(duì)象。


也就是說,從頁表中找到的“普通頁”的物理地址,應(yīng)該等于頁目錄的物理地址!


作為一名軟件開發(fā)人員,遞歸思想都是有的。


我們就來構(gòu)造一個(gè)線性地址 addr,讓它經(jīng)過3次查表操作之后,能夠指向頁目錄的物理地址。


一級(jí)查表:構(gòu)造線性地址的前 10 位,來確定頁表的物理地址

一級(jí)查表:查找的對(duì)象是頁目錄。


線性地址addr的前10位,決定了頁目錄內(nèi)的索引。


很顯然,需要讓這個(gè)索引對(duì)應(yīng)的那個(gè)表項(xiàng)中所登記的地址,必須是指向頁目錄自己才可以。


常用的解決方案是:利用頁目錄中的最后一個(gè)表項(xiàng),讓這個(gè)表項(xiàng)中記錄的地址,指向頁目錄自己,如下圖所示:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?也就是說,預(yù)先在頁目錄的最后一個(gè)表項(xiàng)中,填入頁目錄自己的物理地址,然后只要線性地址addr前10位的值為1023,就能夠得到這個(gè)表項(xiàng)。


很容易就能得到addr的前10位應(yīng)該是:0x3FF(二進(jìn)制:1111_1111_11)。


由于這個(gè)表項(xiàng)中存儲(chǔ)的地址是頁目錄自己的開始地址(0x0100_0000, 最后的12個(gè)0是自動(dòng)補(bǔ)上的),這樣就相當(dāng)于:下面進(jìn)入第二級(jí)查找時(shí),頁目錄即將被當(dāng)做“頁表”來使用。


如下圖所示:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?這里紅色虛線的“頁表”其實(shí)就是頁目錄自己,只是一個(gè)影子而已。


二級(jí)查表:構(gòu)造線性地址的中間 10 位,來確定“普通頁”的物理地址

二級(jí)查表:查找的對(duì)象是頁表,也就是一級(jí)查表得到的那個(gè)“頁表”。


雖然一級(jí)查表的結(jié)果是頁目錄自己,但是處理器不管這些,它會(huì)把這個(gè)表當(dāng)做頁表來使用。


現(xiàn)在,來考慮線性地址addr的中間10位,它決定了頁表中的索引號(hào)。


很顯然,需要繼續(xù)讓這個(gè)索引號(hào)對(duì)應(yīng)的那個(gè)表項(xiàng)中,記錄的地址必須繼續(xù)指向頁目錄自己。


那就繼續(xù)利用這個(gè)“頁表”(其實(shí)它是頁目錄)中的最后一個(gè)表項(xiàng)唄,就是index = 1023的這個(gè)表項(xiàng)。


這個(gè)表項(xiàng)中存儲(chǔ)的物理地址,即將是最終查表得到的“普通頁”的物理地址了。


由于這個(gè)表項(xiàng)中,被預(yù)先填寫了0x01000,補(bǔ)上尾部的12個(gè)0之后就是0x0100_0000,仍然指向頁目錄自己,完美!


于是,就得到了中間10位的結(jié)果:0x3FF(二進(jìn)制:11_1111_1111)。


如下圖所示:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?最右面紅色虛線的“物理頁”,就是二級(jí)查找的結(jié)果,它本質(zhì)上仍然是頁目錄本身,只不過它即將被當(dāng)做一個(gè)普通物理頁來使用。


三級(jí)查表:構(gòu)造線性地址的最后 12 位,來確定“普通頁”的頁內(nèi)偏移量

現(xiàn)在,已經(jīng)構(gòu)造出了線性地址addr(這是我們的最終目標(biāo))的前20位,并且經(jīng)過頁表的前兩級(jí)查表,成功的定位到了頁目錄自己!


就差最后一步了!


我們知道,從線性地址到物理地址的轉(zhuǎn)換過程中,最后的12位表示頁內(nèi)偏移,是直接從線性地址中取過來的。


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?也就是說:線性地址 與 物理地址 的最后12位偏移量,值是一樣的!


所以,我們就反過來倒推一下:


我們最終想操作的是頁目錄中第256個(gè)表項(xiàng),它的物理地址是0x0100_0400,這個(gè)物理地址距離這個(gè)頁目錄開始位地址的偏移量是:0x400(0x0100_0400減去0x0100_0000)。


因此,線性地址addr中的最后12位的值也應(yīng)該是0x400。


三個(gè)地址段合體

把上面三個(gè)步驟中,得到的地址聚合在一起:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?0xFFFF_F400就是最終想得到的線性地址!


也就是說,我們只要把這個(gè)線性地址0xFFFF_F400告訴處理器,它就會(huì)經(jīng)過頁處理單元的轉(zhuǎn)換,最終查找到頁目錄這個(gè)物理頁中的第256個(gè)表項(xiàng),也就是物理地址 0x0100_0400。


例如:mov [0xFFFF_4000], xxxx


以上就是操作系統(tǒng)在操作頁目錄自身時(shí),所采取的策略。


具體到每個(gè)操作系統(tǒng)來說,可能稍微有差別,但是其中的道理都是差不多的。


例如本文開頭的第一張圖中,Linux使用了4級(jí)表格來查找,并且中間的兩個(gè)表格還可以省略不用。


如何跨過中間的這兩個(gè)表格,Linux內(nèi)核代碼中的代碼更復(fù)雜一些,但是策略都是一樣的。


對(duì)頁表進(jìn)行尋址

既然已經(jīng)弄明白了操作系統(tǒng)是如何操作頁目錄的,那么對(duì)頁表的操作就不是什么大問題了。


比如下面這張圖:


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?目標(biāo):把最右面的普通物理頁地址0x0200_0000,放入0x0800_0000這個(gè)頁表的第一個(gè)表項(xiàng)中(只需要存儲(chǔ)前20位),那么應(yīng)該傳遞什么樣的線性地址給處理器?


思路是完全一樣的。


一級(jí)查表

按照正常的分頁查找流程,從頁目錄的某個(gè)表項(xiàng)中,查找我們想操作的那個(gè)頁表


頁目錄中的這個(gè)表項(xiàng)位于索引值256的地方,因此可以構(gòu)造出線性地址的前10位是:0100_0000_00(0x100)。


所以,經(jīng)過一級(jí)查表得到的這個(gè)頁表的物理地址是0x0800_0000。


二級(jí)查表

利用這個(gè)頁表的最后一個(gè)表項(xiàng)(index = 1023),預(yù)先填寫一個(gè)地址(0x08000),讓它指向這個(gè)頁表自己的開始物理地址。


于是,可以構(gòu)造出線性地址的中間10位是:11_1111_1111(0x3FF)。


由于這個(gè)表項(xiàng)中存儲(chǔ)的地址是0x0800_0000,指向的正是頁表自己,只不過馬上它就被當(dāng)作普通物理頁被使用。


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?

三級(jí)查表

此時(shí),已經(jīng)找到最后的普通物理頁了(其實(shí)它是一個(gè)頁表,被當(dāng)作普通物理頁使用)。


線性地址的最后12位,可以直接從最后想操作的那個(gè)目標(biāo)物理地址中最后12位直接拿過來。


我們的目標(biāo)是:操作頁表中的第 0 個(gè)表項(xiàng),這個(gè)表項(xiàng)的物理地址是0x0800_0000,最后的12位偏移量是0000_0000_0000。


把以上3個(gè)地址段合體,即可得到正確的線性地址


Linux從頭學(xué)16:操作系統(tǒng)-如何把【頁目錄和頁表】當(dāng)做普通物理頁進(jìn)行操作的?
------ End ------


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉