Linux x86 64位內存管理

地址映射

64位地址採用4層地址映射,如下圖:


pgd、pud、pmd、pte各佔了9位,加上12位的頁內index,共用了48位。即可管理的地址空間爲2^48=256T。而在32位地址模式時,該值僅爲2^32=4G。

另外64位地址時支持的物理內存最大爲64T,見e820.c中MAX_ARCH_PFN的定義:

# define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT

其中MAXMEM爲2^46,PAGE_SHIFT爲12。

而在32位地址時最大支持的物理內存爲64G(開啓PAE選項)。

 

地址空間

32位與64位具體地址分佈如下圖:

64位地址時將0x0000,0000,0000,0000 – 0x0000,7fff,ffff,f000這128T地址用於用戶空間。參見定義:

#define TASK_SIZE_MAX   ((1UL << 47) - PAGE_SIZE),注意這裏還減去了一個頁面的大小做爲保護。

而0xffff,8000,0000,0000以上爲系統空間地址。注意:該地址前4個都是f,這是因爲目前實際上只用了64位地址中的48位(高16位是沒有用的),而從地址0x0000,7fff,ffff,ffff到0xffff,8000,0000,0000中間是一個巨大的空洞,是爲以後的擴展預留的。

而真正的系統空間的起始地址,是從0xffff,8800,0000,0000開始的,參見:

#define __PAGE_OFFSET     _AC(0xffff,8800,0000,0000, UL)

而32位地址時系統空間的起始地址爲0xC000,0000。

另外0xffff,8800,0000,0000 – 0xffff,c7ff,ffff,ffff這64T直接和物理內存進行映射,0xffff,c900,0000,0000 – 0xffff,e8ff,ffff,ffff這32T用於vmalloc/ioremap的地址空間。

而32位地址空間時,當物理內存大於896M時(Linux2.4內核是896M,3.x內核是884M,是個經驗值),由於地址空間的限制,內核只會將0~896M的地址進行映射,而896M以上的空間用做一些固定映射和vmalloc/ioremap。而64位地址時是將所有物理內存都進行映射。

另外注意:在文檔Documentation\x86_64\mm.txt中對系統空間中地址的描述,都比實際的(代碼中的)少了0x700,0000,0000的偏移量,應該是代碼修改時沒有同步修改文檔L,我用的是Linux-3.11.0內核。
 

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