日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

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

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


關注下方公眾號,回復【書籍】,獲取 Linux、嵌入式領域經典書籍;回復【PDF】,獲取所有原創(chuàng)文章( PDF 格式)。



目錄


  • 問題描述


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


  • 對頁目錄進行"自操作"


    • 一級查表:構造線性地址的前十位


    • 二級查表:構造線性地址的中間十位


    • 三級查表:構造線性地址的最后十二位


    • 三個地址段合體


  • 對頁表進行"自操作"


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


如果你看過Linux內核相關書籍,一定對下面這張圖又熟悉、又恐懼:


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


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


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


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


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


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


把這里面的操作機制研究透徹之后,再去看Linux內核代碼時,就不會暈頭轉向了。


問題描述

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


  1. 假設實際的物理內存是1 GB;


  2. 用戶程序文件在硬盤上的長度是20 MB;


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


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


如下圖所示:


Linux從頭學16:操作系統(tǒng)-如何把【頁目錄和頁表】當做普通物理頁進行操作的?頁目錄和頁表的每一個有效表項中,存儲的地址都是一個個實實在在的物理頁的前 20 位(因為一個物理頁的長度固定是4KB,在分配時都是對齊的,末尾的 12 位全部為 0)。


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


當頁目錄和頁表都構造妥當之后,處理器面對一個線性地址,例如:0x4100_1800,頁處理單元就會按照分級查表的方式,把這個線性地址轉換為一個物理地址:


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


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


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


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


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


那么,問題來了:


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


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


但是,我們不能把這個表項的物理地址直接告訴CPU,因為CPU只接收線性地址,它會自動經過分頁單元的處理來得到對應的物理地址。


那么,這個線性地址的值應該是多少呢?


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


假設頁目錄所處的物理頁開始地址是0x0100_0000,那么第256個表項的物理地址就是0x0100_0400。


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


這是不對的!


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

因為現在已經開啟了分頁處理單元,0x0100_0400是我們最后想得到的物理地址,而處理器只接受線性地址,雖然我們知道這是一個物理地址,但是處理器不知道?。?


當我們給處理器一個地址的時候,處理器會按部就班的對這個地址進行[段轉換],再進行[頁轉換],這時才得到它認為的物理地址。


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


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


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


現在,應該明白面對的問題了吧?


目標就是:通過某種方法,構造出一個線性地址addr,并且通過頁處理單元轉換之后,得到物理地址0x0100_0400。


對頁目錄進行操作

重新梳理一下思路:如果對一個普通物理頁(下文簡稱為:普通頁)里的一個地址處的數據進行操作,需要經過3次查表操作:


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


現在我們的問題是:需要把頁目錄作為最終的操作對象。


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


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


我們就來構造一個線性地址 addr,讓它經過3次查表操作之后,能夠指向頁目錄的物理地址


一級查表:構造線性地址的前 10 位,來確定頁表的物理地址

一級查表:查找的對象是頁目錄。


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


很顯然,需要讓這個索引對應的那個表項中所登記的地址,必須是指向頁目錄自己才可以。


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


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


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


由于這個表項中存儲的地址是頁目錄自己的開始地址(0x0100_0000, 最后的12個0是自動補上的),這樣就相當于:下面進入第二級查找時,頁目錄即將被當做“頁表”來使用。


如下圖所示:


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


二級查表:構造線性地址的中間 10 位,來確定“普通頁”的物理地址

二級查表:查找的對象是頁表,也就是一級查表得到的那個“頁表”


雖然一級查表的結果是頁目錄自己,但是處理器不管這些,它會把這個表當做頁表來使用。


現在,來考慮線性地址addr的中間10位,它決定了頁表中的索引號。


很顯然,需要繼續(xù)讓這個索引號對應的那個表項中,記錄的地址必須繼續(xù)指向頁目錄自己。


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


這個表項中存儲的物理地址,即將是最終查表得到的“普通頁”的物理地址了。


由于這個表項中,被預先填寫了0x01000,補上尾部的12個0之后就是0x0100_0000,仍然指向頁目錄自己,完美!


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


如下圖所示:


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


三級查表:構造線性地址的最后 12 位,來確定“普通頁”的頁內偏移量

現在,已經構造出了線性地址addr(這是我們的最終目標)的前20位,并且經過頁表的前兩級查表,成功的定位到了頁目錄自己!


就差最后一步了!


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


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


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


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


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


三個地址段合體

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


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


也就是說,我們只要把這個線性地址0xFFFF_F400告訴處理器,它就會經過頁處理單元的轉換,最終查找到頁目錄這個物理頁中的第256個表項,也就是物理地址 0x0100_0400。


例如:mov [0xFFFF_4000], xxxx


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


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


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


如何跨過中間的這兩個表格,Linux內核代碼中的代碼更復雜一些,但是策略都是一樣的。


對頁表進行尋址

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


比如下面這張圖:


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


思路是完全一樣的。


一級查表

按照正常的分頁查找流程,從頁目錄的某個表項中,查找我們想操作的那個頁表。


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


所以,經過一級查表得到的這個頁表的物理地址是0x0800_0000。


二級查表

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


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


由于這個表項中存儲的地址是0x0800_0000,指向的正是頁表自己,只不過馬上它就被當作普通物理頁被使用。


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

三級查表

此時,已經找到最后的普通物理頁了(其實它是一個頁表,被當作普通物理頁使用)。


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


我們的目標是:操作頁表中的第 0 個表項,這個表項的物理地址是0x0800_0000,最后的12位偏移量是0000_0000_0000。


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


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


本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀

北京2026年3月27日 /美通社/ -- 當第十五屆全國運動會辦公系統(tǒng)全程穩(wěn)定運行時,當銀行柜員輕點鼠標實現業(yè)務秒級響應時,當大學生刷一卡通順暢進出宿舍、食堂、圖書館時,當新能源汽車充電樁智能調度、巨災預警系統(tǒng)精準響應...

關鍵字: CPU 指令集 芯片 操作系統(tǒng)

與阿里巴巴深化合作,推動先進工業(yè)仿真能力上云 發(fā)布26款全新邊緣、自動化與控制技術,以執(zhí)行工業(yè)領域人工智能驅動的決策 推出新一代電氣化與AI賦能制冷技術,響應高密度智算中心與AI基礎設施需求 北京2...

關鍵字: 操作系統(tǒng) 西門子 AI 阿里云

AUTOSAR CP (Classic Platform)平臺雖在提升車輛軟件的模塊化、可重用性、可擴展性以及跨系統(tǒng)集成方面成效顯著,有效縮短了開發(fā)周期、提升了軟件質量、降低了成本,但面對軟件定義汽車的巨浪,其仍面臨軟件...

關鍵字: 汽車電子 操作系統(tǒng) 實時操作系統(tǒng)

在高并發(fā)服務器開發(fā)中,線程池(ThreadPool)已成為解決多任務調度的核心方案。其設計并非偶然,而是針對傳統(tǒng)線程管理痛點的系統(tǒng)性優(yōu)化。

關鍵字: 線程 操作系統(tǒng)

深圳2026年2月6日 /美通社/ -- 近日,匯頂科技eSIM方案成功獲得GSMA eUICC Security Assurance(eSA)及COS SOGIS CC EAL5+兩項國際安全認證,成為國內首家在操作系...

關鍵字: ESIM BSP 操作系統(tǒng) 智能終端

在嵌入式系統(tǒng)開發(fā)中,實時操作系統(tǒng)(RTOS)已成為提升效率、簡化復雜任務管理的核心工具。隨著技術演進,免費開源的RTOS選項日益豐富,為開發(fā)者提供了靈活性和成本優(yōu)勢。然而,面對眾多選擇,如何挑選最適合項目的RTOS?本文...

關鍵字: RTOS 操作系統(tǒng)

在計算機科學中,文件系統(tǒng)是操作系統(tǒng)最關鍵的組件之一,它如同數字世界的"圖書館管理員",負責組織、存儲和檢索海量數據。從智能手機的照片存儲到超級計算機的并行計算,文件系統(tǒng)無處不在卻又鮮為人知。

關鍵字: 文件系統(tǒng) 操作系統(tǒng)

北京2025年12月22日 /美通社/ -- 近日,軟通動力在自主創(chuàng)新產品發(fā)布會上正式發(fā)布"軟通天鴻操作系統(tǒng)6"。該操作系統(tǒng)由軟通動力子公司鴻湖萬聯基于OpenHarmony社區(qū)版深度定制而成,是一款...

關鍵字: 開源 操作系統(tǒng) 全棧 鴻蒙

北京2025年12月22日 /美通社/ -- 12月20日晚,中央廣播電視總臺與廣東省人民政府聯合主辦,深圳市人民政府、央視頻、總臺廣東總站共同承辦的《鴻蒙星光盛典》,正式在CCTV-2、CCTV-3、央視頻、央視新聞、...

關鍵字: 鴻蒙 開源 操作系統(tǒng) HARMONY

香港2025年12月11日 /美通社/ -- 諾亞控股有限公司(Noah Holdings Limited,以下簡稱"諾亞"或"公司",紐交所代碼:NOAH,港交所代碼:6686)...

關鍵字: AI 代碼 AN 操作系統(tǒng)
關閉