Linux 核心中邏輯地址/虛擬位址/線性地址三者的區別

來源:互聯網
上載者:User

標籤:linux核心   記憶體管理   線性地址   邏輯地址   虛擬位址   

本博文引自我的知乎回答:Linux 線性地址,邏輯地址和虛擬位址的關係?

為了防止歧義,以下術語都用英文。部分術語不做解釋了,不然答案就太長了。

以下講解都是以程式碼片段為例

在 Intel 平台下,邏輯地址(logical address)是 selector:offset 這種形式,selector 是 CS 寄存器的值,offset 是 EIP 寄存器的值。如果用 selector 去 GDT( 通用描述元表 ) 裡拿到 segment base address(段基址) 然後加上 offset(段內位移),這就得到了 linear address。我們把這個過程稱作段式記憶體管理。

如果再把 linear address 切成四段,用前三段分別作為索引去PGD、PMD、Page Table裡查表,最終就會得到一個頁表項(Page Table Entry),那裡面的值就是一頁實體記憶體的起始地址,把它加上 linear address 切分之後第四段的內容(又叫頁內位移)就得到了最終的 physical address。我們把這個過程稱作頁式記憶體管理。

問題來了,為什麼沒提到 virtual address,這是個什麼東西?其實在 Intel IA-32 手冊裡並沒有提到這個術語,但是在核心的確是用到了這個概念,比如__va和__pa這兩個宏定義。看似神秘的 virtual address 究其本質就是程式裡面使用的地址比如一個指標值,指標的本質就是 EIP 寄存器裡的值,說直白點,virtual address 就是 EIP 寄存器的值。你會發現我們上面說過,logical address 由 selector 和 offset 兩部分組成,offset 也是 EIP 寄存器的值,所以結論為:logical address 的 offset 正是 virtual address,它倆是一個東西。

既然搞明白了 logical address 和 virtual address 的關係,那麼我們再來看下,linear address 和 virtual address 是什麼關係。在上面講到的段式記憶體管理中,Linux 核心會將 segment base address(段基址)設成 0,於是就有 linear address = 0+offset,又因為 virtual address 就是 offset,所以算出的 linear address在數值上等於 virtual address,注意,是數值上等於,它們之間是差了段基址的,只不過段基址為 0 罷了。

網上很多資料認為邏輯地址是虛擬位址的別名,其實它們不是一個東西。還有很多資料把線性地址當作虛擬位址的別名,其實它們也不是一個東西,只是Linux在x86下將它們搞得數值相等而已,雖然值相等但是本質不同。

---------------------------------我是分割線-------------------------------------------

講到這裡,三者之間的關係就講明白了,最後說下為什麼這三個概念會如此混亂。

按照 Intel 的設計,段式記憶體管理中的段類型分為三種:程式碼片段(上面講了)、資料區段、系統段(TSS之類的),實在是太麻煩了。我們只靠頁式記憶體管理就已經可以完成Linux核心需要的所有功能,根本不需要段映射,但是段映射這玩意兒又關不掉,那就只能上點手段了。於是,Linux核心將所有類型的段的 segment base address 都設成0,段限長都設成最大(具體數值不展開講了,涉及到段描述符結構,很麻煩,這裡理解成地址匯流排的最大定址限度即可),那麼這樣一來所有段都重合了,也就是不分段了,此外由於段限長是地址匯流排的定址限度,所以這也相當於所有段跟整個線性空間重合了。虛擬位址本來是在段內的位移量,現在段就是整個線性空間,所以虛擬位址就成了在整個線性空間內的位移量,這和線性地址的概念一樣,所以核心開發人員都已經將虛擬位址和線性地址當作一個東西了。像是 Understand The Linux Kernel 這本書裡面為了避免混淆,除了在開頭和術語表中引用了  virtual address 這個片語之外,其他地方全是用的 linear address。

看完這個答案,你會發現我們繞了一圈回來,雖然邏輯地址的概念很清晰,但是虛擬位址和線性地址依然可以不作區分,因為區分了也沒什麼用,核心裡這倆概念是通用的。不過,知道點區別還是不至於在某些時候把自己搞暈,尤其是有些書和教程裡面這兩個詞不說緣由就混著用,這很蛋疼。好了,最後結論就是,這兩個概念區分開來的確更加清晰,但如果不作區分而直接把虛擬位址看作線性地址的別名,對你理解核心也不會產生任何影響。


本文出自 “Linux Kernel Developer” 部落格,請務必保留此出處http://mirage1993.blog.51cto.com/2709744/1921773

Linux 核心中邏輯地址/虛擬位址/線性地址三者的區別

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.