Paging Structure in Linux

為了符合各種架構的處理器(包含 64bit 處理器),Linux 所採用的架構是 4-level paging architecture。架構圖如下:


四層架構分別為:
  • 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 的話,那就不必要使用這兩個檔案了)。

留言

這個網誌中的熱門文章

如何將Linux打造成OpenFlow Switch:Openvswitch

我弟家的新居感恩禮拜分享:善頌善禱

Linux Virtual Interface: TUN/TAP