Linux內存管理(一)

Linux內存管理之一:基本概念篇linux

物理地址、線性地址(虛擬地址)和邏輯地址;闡述段式管理和頁式管理基本概念;Linux操做系統內存管理和虛擬內存概念;爲內核開發作一個基礎鋪墊。編程

 

內存是linux內核所管理的最重要的資源之一,內存管理子系統是操做系統中最重要的部分之一。對與立志從事內核開發的工程師來講,熟悉linux的內存管理系統很是重要。架構

一、物理地址、線性地址(虛擬地址)和邏輯地址之間的關係框架

物理地址是指出如今cpu外部的地址總線上的尋址物理內存的地址信號,是地址變換的最終結果。spa

邏輯地址是程序代碼通過編譯後在彙編程序中使用的地址。操作系統

線性地址又名虛擬地址,在32位cpu框架下,能夠表示4G地址空間,用16進製表示就是0x00000000到0xffffffff。設計

地址轉換:cpu要將一個邏輯地址轉換爲物理地址,須要兩步:首先cpu利用段式內存管理單元,將邏輯地址轉換成線性地址,在利用頁式內存管理單元,把線性地址最終轉換爲物理地址。索引

2.段式管理與頁式管理進程

什麼是段式管理?內存

16位cpu內部擁有20位的地址線,它的尋址範圍就是2的20次方,也就是1M的內存空間。可是16位的菜譜用於存放地址的寄存器只有16位,所以只能訪問65536個存儲單元,64K。爲了可以訪問1M的內存空間,cpu就採用了內存分段的管理模式,並在cpu內部加入了段寄存器。16位cpu把1M內存空間分爲若個邏輯段,每一個邏輯段的要求以下:

一、 邏輯段的起始地址(段地址)必須是16的倍數,即最後4個二進制必須全爲0.

二、 邏輯段的最大容量爲64K

物理地址的造成方式:

因爲段地址必須是16的倍數,因此值的通常形式爲XXXX0H,即前16位二進制位是變化的,後4位是固定的0,鑑於段地址的這種特性,能夠只保存前16位二進制位來保存這個段基地址,因此每次使用時要用段寄存器左移4個0(乘以16)來獲得實際的段地址。在肯定了某個存儲單元所屬的段後,只是知道了該存儲單元所屬的範圍(段地址->段地址+65536),若是想肯定該存儲單元的具體位置,還必須知道該單元在段內的偏移。有了段地址和偏移量,就能夠惟一的肯定內存單元在存儲器中具體位置。

邏輯地址=段內偏移量

因爲邏輯地址獲得物理地址的公式爲:PA=段寄存器的值*16+邏輯地址

段寄存器是爲了對內存進行分段管理而增長的,16位cpu有四個段寄存器,程序可同時反問四個不一樣含義的段。

一、CS+IP:用於代碼段的訪問,CS指向存放程序的段基址,IP指向下條要執行的指令在CS段的偏移量,用這兩個寄存器就能夠獲得一個內存物理地址,該地址存放着一條要執行的指令。

二、SS+SP:用於堆棧段的訪問,SS指向堆棧段的基地址,SP指向棧頂,能夠經過SS和SP兩個寄存器直接訪問棧頂單元的內存物理位置。

三、DS+BX:用於數據段的訪問。DS中的值左移四位獲得數據段起始地址,再加上BX中的偏移量,獲得一個存儲單元的物理地址。

四、ES+BX:用於附加段的訪問。ES中的值左移四位獲得附加段起始地址,再加上BX中的偏移量,獲得一個存儲單元的物理地址。

32位pc的內存管理能然採用「分段」的管理模式,邏輯地址一樣由段地址和偏移量兩部分組成,32位pc的內存管理和16位pc的內存管理有相同之處,也有不一樣之處,由於32位pc採用了兩種不一樣的工做方式:實模式和保護模式。咱們通常使用在保護模式的。

 

一、 實模式

在實模式下,32位的cpu的內存管理與16位的cpu是一致的。

二、 保護模式

段基地址長達32位,每一個段的最大容量可達4G,段寄存器的值是段地址的「選擇器」(Selector),用該「選擇器」從內存中獲得一個32位的段地址,存儲單元的物理地址就是該段地址加上段內偏移量,這與32位cpu的物理地址計算方式徹底不一樣。

32位cpu內有6個段寄存器,其值在不一樣的模式下具備不一樣的含義:

一、 在實模式下:

段寄存器的值*16就是段地址

二、 在保護模式下:

段寄存器的值就是一個選擇器,間接指出一個32位的段地址

 

什麼是頁式管理?

從管理和效率的角度出發,線性地址被劃分爲固定長度的組,稱爲頁(page),例如32位的 ,線性地址最大可爲4G,若是用4KB爲一個也來劃分,這樣的這個線性地址就被劃分爲2的20次方個頁。

另外一類「頁」,也稱之爲「物理頁」,或者是頁框、頁幀。分頁單元把全部的物理內存也劃分爲固定長度的管理單位,它的長度通常與線性地址頁是相同的。

 

 

 

 

一、 分頁單元中,頁目錄的地址放在cpu的cr3寄存器中,是進行地址轉換的開始點。

二、 每一個進程,都有其獨立的虛擬地址空間,運行一個進程,首先須要在它的頁目錄地址放到cr3寄存器中,將其餘進程的保存下來。

三、 每一個32位的線性地址被劃分爲三個部分:頁目錄索引(10位),頁表索引(10位):偏移(12位即4k)。

依據一下步驟進行地址轉換:

一、 裝入進程的頁目錄地址(操做系統在調度進程時,把這個地址裝入cr3)

二、 根據現行線性地址的前10位,在頁目錄中找對應的索引項,頁目錄中的項是一個頁表的地址。

三、 根據線性地址的中間10位,在頁表中找到頁的起始地址。

四、 將頁的起始地址與線性地址的最後12位相加,獲得物理地址。

這樣的二級模式是能夠覆蓋4G的物理地址空間的,

頁目錄中共有:2^10項,也就是說有這麼多個頁表;頁表對應有:2^10頁;每一個頁可尋址:2^12個字節。即2^32=4GB。

3.Linux內存管理

Linux內核的設計並無所有采用Intel所提供的段機制,僅僅是有限度地使用了分段機制。這不只簡化了linux內核的設計,並且爲把linux移植到其餘平臺創造了條件,由於不少RISC處理器並不支持段機制。

在linux中,全部段的基地址均爲0,由此能夠得出,每一個段的邏輯地址空間範圍是0-4GB。由於每一個段的基地址爲0,所以邏輯地址與線性地址保持一致(即邏輯地址的偏移量字段的值與線性地址的值老是相同的),在linux中所提到的邏輯地址和線性地址(虛擬地址),能夠認爲是一致的。看來,linux巧妙地把段機制給繞過去了,而徹底利用了分頁機制。

前面介紹的是i386的二級管理架構,不過有的cpu使用的三級,甚至是四級架構,linux2.6.29內核爲每種cpu提供統一的界面,採用了四級頁面管理架構來兼容二級、三級、四級管理架構的cpu。

 

這四級分別爲:

一、 頁全局目錄(Page Global Directory):即pgd,是多級頁表的抽象最高層。

二、 頁上級目錄(Page Upper Directory):即pud。

三、 頁中間目錄(Page Middle Directory):即pmd,是頁表的中間層。

四、 頁表(Page Table Entry):即pte

 

4.虛擬內存

Linux操做系統採用虛擬內存管理技術,使得每一個進程都有一個獨立的進程地址空間,該空間是大小爲3G,用戶所看到和接觸的都是虛擬地址,沒法看到實際的物理地址。利用這種虛擬地址不但能起到保護操做系統的做用,並且更重要的是用戶程序可以使用比實際物理內存更大的地址空間。

Linux4G的虛擬地址空間劃分爲兩個部分---用戶空間和內核空間。用戶空間從00xbfffffff,內核空間從3G4G。用戶進程一般狀況下只能訪問用戶空間的虛擬地址,不能訪問內核空間。例外狀況是用戶進程經過系統調用訪問內核空間。

相關文章
相關標籤/搜索