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。

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章