linux 記憶體定址總結

2021-04-29 23:06:41 字數 2082 閱讀 7436

邏輯位址到實體地址的轉換過程:

邏 輯位址經過記憶體控制單元(mmu)的分段單元硬體電路之後轉換成線性位址,線性位址經過分頁單元的硬體電路轉換成實體地址。在mp中,多個cpu通過記憶體 仲裁器對ram進行併發的訪問(每個ram有乙個仲裁器),在up中也是有記憶體仲裁器的,因為cpu和dma控制器要併發的對ram進行訪問

2 段選擇符和段暫存器

乙個邏輯位址由兩部分組成:段選擇符和段內的偏移量,段選擇符是乙個16位的字段,偏移量則是乙個32位的字段。

(1) 為了減少位址轉換的時間和**的複雜度,處理器提供了6個段暫存器。當程式執行的時候,段選擇符必須事先載入到段暫存器中,下面我們來看一下段暫存器的圖示:

它 由可見部分和不可見部分組成,可見部分即上面講的段描述符的16位。不可見部分按照intel手冊上講可以用做descriptor cache,即在載入段選擇符的時候,會同時從段選擇符指向的段描述符中載入段基址,段限和其他一些訪問許可權資訊如s g等。這麼做的目的是在進行位址轉換的時候不用訪問gdt表,而直接就可以轉換了。但是我感覺linux的實現中不是這麼做的,首先我們來想,假設在32 位的系統中,段暫存器是32位的,段描述符就占去了16位,剩下只有16,不可能裝下20位的段限,32位的段基址和其他一些東西等等。intel的設計 可能只是一廂情願而已,但是也有文章提到,為了加速邏輯位址到線性位址的轉換,80x86提供了一種附加的非程式設計的暫存器(程式設計師不可見),每個可程式設計的 暫存器含有8個位元組的段描述符,由相應的段選擇符來指定,即:當乙個段選擇符被載入時,有段選擇符指定的段描述符就有記憶體載入到非程式設計暫存器中,那麼這個 邏輯位址的轉換就不需要訪問gdt和ldt了(段暫存器和非程式設計暫存器的對應關係應該是上圖講的差不多)。

(2) 下面我們再來看看段描述符:(以**段描述符為例)

每個段描述符佔8個位元組,放在gdt或ldt中,通常只定義乙個gdt,如果每個程序除了放在gdt中的段之外還需要建立附加的段的話,就可以定義自己的ldt。至於段描述符中每個欄位的意思,我就不詳細介紹了,詳細可見《深入理解linux核心》。

(3)下面我們再來看下gdt表:

gdt表的基址存放在gdtr中,需要注意的是,gdt表的第一項總是為0,這就確保了空的段選擇符的邏輯位址被認為是無效的,所以gdt表也就共有8191 = 2^13 - 1 項

系 統中每個cpu都有乙個gdt表,除少數幾種情況外,gdt中的大部分表項都是相同的。但是,每個處理器都應該有他自己的tss,其次,ldt和tls也 於當前程序有關,所以也是不同的。這裡有個ldt表是因為大多數情況下,linux並不使用區域性描述符表,所以就在gdt中定義了乙個公共的ldt,而不 是每個程序都維護乙個ldt。

根據段選擇符中的index和gdtr中的位址計算出段描述符的位址(gdtr + index * 8),然後從段描述符中取得段基址base,與offset相加即得到線性位址,在這個過程中包括了段限的檢查等一些安全性檢查。

3 如何把線性位址轉換成實體地址

前面提到,分頁單元把線性位址轉換成了實體地址。分頁單元把所有的ram分成固定長度的頁框(也叫物理頁),每乙個頁框包含乙個頁。頁指的是乙個資料塊,也框指的是一塊實際的物理記憶體。

頁目錄項和頁表項有相同的結構,我們現在來看一下linux中的四級分頁模型(linux2.6.11開始)

主要分為:

(1)頁全域性目錄

(2)頁上級目錄

(3)頁中級目錄

(4)頁表

這裡主要分幾種情況:

(1)未啟用實體地址擴充套件的32位系統,兩極頁表已經足夠了,linux通過把也上級目錄和頁中級目錄的項數設定為1,並把這兩個也目錄對映到也全域性目錄的某個適當的目錄項而實現。

(2)啟用了實體地址擴充套件的32位系統使用的是**頁表。

這裡bits31-30對應的是也全域性目錄,bits29-21對應的是頁中級目錄,bits20-12對應的是頁表。

下面我們來總結一下,就一句話:線性位址到實體地址的轉換是有硬體按照頁表的不同的組織形式來自動轉換的,對使用者來說是透明的。

4 物理記憶體的布局

我們首先來看一下前3m的物理記憶體布局:

首先說明,上圖是錯誤的,我省勁就不自己畫了。途中的_text應該和0x100是重合的,指的是乙個位置。

核心從0x100開始存放,到_etext結束,然後_etext到_edata是初始化資料區,之後到_end是未初始化資料區。

linux 記憶體定址總結

邏輯位址到實體地址的轉換過程 邏 輯位址經過記憶體控制單元 mmu 的分段單元硬體電路之後轉換成線性位址,線性位址經過分頁單元的硬體電路轉換成實體地址。在mp中,多個cpu通過記憶體 仲裁器對ram進行併發的訪問 每個ram有乙個仲裁器 在up中也是有記憶體仲裁器的,因為cpu和dma控制器要併發的...

linux 記憶體定址總結

邏輯位址經過記憶體控制單元 mmu 的分段單元硬體電路之後轉換成線性位址,線性位址經過分頁單元的硬體電路轉換成實體地址。在mp中,多個cpu通過記憶體仲裁器對ram進行併發的訪問 每個ram有乙個仲裁器 在up中也是有記憶體仲裁器的,因為cpu和dma控制器要併發的對ram進行訪問 2 段選擇符和段...

linux 記憶體定址

1 實體地址 虛擬位址及線性位址 2 虛擬位址到實體地址的過程 記憶體定址的過程可以簡單理解為虛擬位址到實體地址的轉換過程。程式設計師所使用的虛擬位址,並不是直接送到記憶體匯流排,而是被送到記憶體管理單元 mmu,由乙個或一組晶元組成是一種硬體電路,實現虛擬位址到實體地址的轉換 mmu包括分段機制和...