計算機為什麼要設置線性地址,從邏輯地址到線性地址再到物理地址?

線性地址還要分成GDT 和 LDT,對於IDTR和TR的選擇符和前面的有不相同,為什麼?


邏輯地址是給操作系統之上的軟體看的。他們不需要知道硬體是怎麼設計的,只需要一台理想的虛擬機就可以了。這樣是為了同樣的軟體應用於不同的硬體上。

線性地址是給CPU看的。CPU不需要知道有多少外設,什麼種類的外設,反正它都是用地址來訪問。印表機也好,硬碟也好,遊戲手柄也好,內存也好,任何亂七八糟的外設也好,它都是分配個地址來訪問。這叫做統一編址,也屬於線性編址。讓所有的外設,都可以像訪問內存一樣,線性訪問。目的是為了讓CPU可以接各種外設,不需要知道外設是怎麼實現的。比如說硬碟,根本就不是線性地址,其有多個扇面,扇面又被劃分成很多小塊,磁頭的移動絕對不是線性的。你不需要知道硬碟是怎麼樣的物理結構,你只需要把它想像成一排格子,每一格是一個sector。你甚至不需要知道硬碟只能以sector讀寫,你也可以只讀寫一位元組,硬碟控制器會幫你搞定你想要的。簡言之,線性地址能讓CPU把任何設備當成內存。

物理地址是給實際的硬體看的。光碟機控制器給讀寫頭的控制信號,硬碟控制器給磁頭髮出的讀寫地址,內存匯流排上的地址是物理地址。硬體只對這個地址做響應。

邏輯地址要經過操作系統轉換成線性地址給CPU,CPU發出線性地址給解碼器,解碼器根據線性地址找到合適的外設,外設自身的控制器再將線性地址進行解碼得到物理地址送給實際的設備。

當然,真正的IC裡面,地址比這個模型複雜多了。


不要把 Legacy x86 的行為當成「計算機」的普遍行為,其他MMU可沒有線性地址這個概念。


首先,並不是所有的CPU都有邏輯地址。邏輯地址是段式內存管理單元的輸入的,有些CPU的,比如說典型的ARM是沒有段式內存管理單元的。所以linux為了兼容所有CPU,只使用了頁式內存管理單元,對段式內存管理單元只是敷衍了一下,讓它的所有輸入與輸出相等。

然後,GDT, LDT的輸入是邏輯地址,輸出是線性地址,頁式內存管理單元的輸入是線性地址,輸出是系統匯流排地址(物理地址)。 GDT, LDT都是x86的概念,ARM上沒有。

再然後,IDTR, TR的選擇符在x86上是要通過邏輯地址去標記的,但如果像linux那樣把段式內存管理單元敷衍一下的話,IDTR, TR的輸入地址與線程地址是致的。

最後,對x86而言,段式內存管理單元出現在先,頁式內存管理單元出現再後,頁式內存管理顯然有先進性,段式內存管理單元更像是歷史遺留問題。

加個小尾巴,歡迎關注我的知乎專欄,

知乎專欄·「現代計算機」- https://zhuanlan.zhihu.com/modern-computing?utm_source=com.android.emailutm_medium=social


GDT和LDT還有段這些都是X86的特性,其實Linux操作系統都繞開了。其它的架構都沒這麼麻煩,題主完全可以認為它們沒什麼用。


保留邏輯地址是因為兼容性吧

從當年為了解決16位數據匯流排與20位地址匯流排的問題引入的分段。現在看起來更像累贅。大家都用全局一個段繞過分段了

所以把線性地址理解成虛擬地址更容易理解一點。或者說保護模式用線性地址和分頁代替了邏輯地址與分段。而為了兼容性,還把邏輯地址留了下來


看趙炯Linux書0.11書


就題目本身而言,設置邏輯地址到線性地址的轉換,一般稱為分段機制。在x86上面是基於這個做的內核態與用戶態的內存中的分離。而線性地址到物理地址的轉換,稱為分頁機制,x86-64是基於這個做的內核態與用戶態的內存中的分離(Linux).

然後分段和分頁的目的一般在操作系統教材上都有吧。


提高內存利用率


物理、邏輯、線性地址的區別,就是根據讀寫對象的不同,抽象出來的封裝地址概念。


簡單的說是為了兼容。


本質上還是抽象 封裝這些計算機領域經常用的思想


推薦閱讀:

如何看待AMD Ryzen 1700實測GTA V遊戲性能不如Intel Core i7 7700k?
如果CPU的cache(緩存)容量上GB或更高,會有哪些不同?

TAG:中央處理器CPU | 中央處理器CPU計算機體系架構 |