頁表項的高20位指向記憶體頁基址,低12位設定頁面狀態和許可權。
如果頁表項的present位為1,表示對應的頁或者頁表已經載入到記憶體頁框。反之,如果為0,對此頁的訪問會觸發缺頁異常。而缺頁異常處理函數會產生配套的頁或者頁表,並重新整理present標記位為1。
typedef struct { unsigned long pte_low; } pte_t;typedef struct { unsigned long pgd; } pgd_t;typedef struct { unsigned long pgprot; } pgprot_t;//擷取寫標誌位;從字面理解以為是寫操作呢,囧static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; }#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))//深入理解linux核心p65裡面介紹的頁目錄項和頁表項裡面的欄位#define _PAGE_PRESENT 0x001#define _PAGE_RW 0x002#define _PAGE_USER 0x004#define _PAGE_PWT 0x008#define _PAGE_PCD 0x010#define _PAGE_ACCESSED 0x020#define _PAGE_DIRTY 0x040對於PAE模式來說,長度變成了64#ifdef CONFIG_X86_PAEtypedef 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;//擷取addr在頁全域目錄表的索引#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))//線性地址在pgd裡面的對應的線性地址#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))//核心頁全域目錄某個項的線性地址#define pgd_offset_k(address) pgd_offset(&init_mm, address)//找到頁描述符地址#define pgd_page(pgd) (pud_page((pud_t){ pgd })) =>#define pud_page(pud) (pmd_page((pmd_t){ pud })) =>#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) =>#define pfn_to_page __pfn_to_page =>#define __pfn_to_page(pfn) (mem_map + ((pfn) - ARCH_PFN_OFFSET))
Linux核心中的記憶體管理淺談 https://blog.csdn.net/acs713/article/details/8575421