Linux核心採用頁式儲存管理。虛擬位址空間劃分成固定大小的“頁面”,由CPU的MMU在運行時講虛擬位址“映射”成某個實體記憶體頁面的地址。
由於i386 CPU對地址先進行段式映射(必須的),然後才能進行頁式映射(可選的)。
Linux讓段式映射前後的地址一樣。
對於使用者空間內的虛擬位址0x08048368為例,進行說明。
第一. i386 CPU使用程式碼片段寄存器CS的當前值來作為段式映射的“選擇碼”,也就是它在段描述表中的下標。
#define __KERNEL_CS 0x10
#define __KERNEL_DS 0x18
#define __USER_CS 0x23
#define __USER_DS 0x2B
我們的地址在進程的使用者空間運行,核心在調度該進程進入運行時,把CS設定成__USER_CS,即0x23。index=4,GDT[4]中儲存的是其對應的段描述項。
ENTRY(gdt_table)
.quad 0x0000000000000000 /* NULL descriptor */
.quad 0x0000000000000000 /* not used */
.quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */
.quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */
.quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */
.quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */
.quad 0x0000000000000000 /* not used */
.quad 0x0000000000000000 /* not used */
GDT表項下標為4的值是0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */
將各項展開
可以看到段基址相同,虛地址到線性地址的映射保持不變。段式映射機制把地址0x08048368映射到了其自身,作為線性地址。
下面進行頁式映射的過程
線性地址0x08048368按二進位展開
0000 1000 0000 0100 1000 0011 0110 1000