Paging Structure in Linux
四層架構分別為:
- Page Global Directory
- Page Upper Directory
- Page Middle Directory
- Page Table
當處理器是 32bit 而且 PAE disabled 的情況下,PUD 和 PMD 是不使用的。
Paging Implementation in Linux Kernel
接下來要看 Linux Kernel 內部關於 Paging 的實作方式。
- Kernel Version: 2.6.17
- Arch: i386
首先,來看看 page 在Linux Kernel中的定義。
/linux/include/asm-i386/page.h:
#ifdef CONFIG_X86_PAE
typedef struct { unsigned long pte_low, pte_high; } pte_t;
typedef struct { unsigned long long pmd; } pmd_t;
typedef struct { unsigned long long pgd; } pgd_t;
typedef struct { unsigned long long pgprot; } pgprot_t;
#define HPAGE_SHIFT 21
#else
typedef struct { unsigned long pte_low; } pte_t;
typedef struct { unsigned long pgd; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
#define HPAGE_SHIFT 22
在這裡我們可以看到 page entry 和 page directory 的定義。特別要注意的是 pgprot_t,它所代表的含意是「the protection flags associated with a single entry」。至於HPAGE_SHIFT指的是當採用大 Page 時的 Page Size(在PAE enable的情況下,大 Page 的 Size 為 21 bits也就是每一個 Page 為 2MB)。
至於那些 Flag 所代表的意義,定義在 /linux/include/asm-i386/pgtable.h。(可以對照之前的文章「IA32 Paging Architecture」)
上面提到Linux內使用了 4-level 的 paging 架構,但從上面的程式碼,很容易發現就算啟用了PAE,也不過是 3-level 的架構,那要怎麼辦呢?事實上,Linux採用4-level的模型也不過是從 2.6.11才開始的(之前是3-level)。為了解決這個問題,在/linux/include/asm-generic的目錄底下,有4level-fixup.h 和 pgtable-nopud.h 這兩個檔案,可以幫助原有的程式碼相容於新版的核心(兩個檔案選一個用即可,不過對新的架構來說,如果本來在設計上就有使用 PUD 的話,那就不必要使用這兩個檔案了)。
留言
張貼留言