linux的記憶體定址(段)

2021-06-05 13:04:04 字數 1724 閱讀 5173

前一段時間看linux的起始**時,對linux的記憶體定址總是似懂非懂。最近認真看了下《深入理解linux核心》,覺得裡面對記憶體定址講述的比較清晰,稍微總結一下。

邏輯位址-----|分段單元|--->線性位址----|分頁單元|--->實體地址

即我們應用程式的位址需要經過分段和分頁兩個轉換才能得到實際的實體地址。

分段和分頁有什麼作用呢,最重要的乙個功能是實現保護。因為我們可以人為的給某個段規定乙個許可權值,只有特定許可權的程序才能訪問該段。這樣,我們可以將儲存系統**和資料的段規定為特權級0,只有作業系統的**(0特權級)才有許可權對它進行修改,防止使用者程式對系統造成破壞。還有另外乙個作用是便於記憶體管理和申請,具體就不詳細展開了。

假設我們現在的系統對記憶體是分段管理的,那麼我們需要知道什麼才能知道這個位址段是幹什麼的,並且找到對應的實體地址呢?顯然,我們需要乙個段描述符知道這個段的一些資訊,段選擇符知道這個段的位置。

每乙個段由乙個8位元組的描述符來表示,描述符放在全域性描述符表(gdt)或區域性描述符表(ldt)

描述符的格式如下:

描述符規定了特定段的特性,如特權級,段限長,基位址等。可以看出段描述符內容比較多,而且系統可能有比較多的段,因此gdt或ldt的資料是比較大的。顯然這些資料不可能直接儲存在暫存器上,那麼cpu是如何得知這些設定的呢?答案是通過gdt和ldt的位址。gdt和ldt的位址分別存在gdtr和ldtr。除了gdt的線性位址以外,gdtr暫存器還儲存了16位的表長度。

段選擇符:由cs,ss,ds等暫存器指定。注意,在沒開啟保護模式之前段暫存器只是存著段的基位址,開啟保護模式後段暫存器不僅儲存有基位址,還有一些段資訊,以cs為例

15~3位為index(索引),起著在gdt或ldt查詢相應段描述符的作用,找到相應的段描述符也就知道了該段的屬性和起始位址了。2位為ti位,決定是查詢gdt還是ldt,1~0位為許可權位,00為系統許可權,11為使用者許可權。

直接舉個例子:

比如此時我們的段選擇符cs=8=0b0000 1000,cpu首先檢查到ti=0,於是使用gdtr暫存器找到gdt的基位址(ti=1則使用ldtr找到ldt位址),然後利用cs中index=1,求得對應的段描述符的位址=gdt基位址+8*1。

為什麼要乘以8呢?因為乙個段的段描述符需要64位,即8位元組,如前面figure2-3所示。同時因為cs的rpl許可權位為00,即為系統許可權,普通使用者的程序(3許可權)是無法訪問該段的,起到了保護作用。

通過以上的操作,我們通過cs順利找到了段描述符,得到了段的基位址。只需再加上乙個offset偏移值就能找到對應的線性位址了(如果沒有分頁,該位址也是實體地址),而這個偏移值offset就是我們在程式中經常使用的位址。如

...一些**...

proc:

....一些**...

proc標號指代的不是乙個絕對位址,而是這個位址相對於程式所在原始檔起始位址的偏移值。比如說這個偏移值為10,而這個原始檔的**在記憶體0x1000 0000處,則proc對應的絕對位址為0x1000 0000+10,偏移位址仍然為10。所以在處理位址時要十分小心cs,ds等段選擇符是不是指向了正確的地方。

在cpu中有專門的指令lgdt lldt處理載入gdtr和ldtr的操作。

linux 記憶體定址

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

linux 記憶體定址總結

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

linux 記憶體定址總結

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