本文討論的linux版本是linux-2.6.26.5,體系結構是smdk2410,採用arm s3c2410。
在該版本中虛擬位址是32位位址,採用四級頁表結構,依次是
| pgd | pud | pmd | pte | offset |
|page_shift|
| pmd_shift |
| pud_shift |
| pgdir_shift |
在arm中只用到了兩級頁表,如下所示,其中pmd的值即為pgd的值:
0000 0000 000 | 0 0000 0000 | 0000 0000 0000
11位9位12位
pgd pte 頁內偏移
#define pmd_shift 21
#define pgdir_shift 21
#define ptrs_per_pte 512 //pte頁表數9位,共有512個項
#define ptrs_per_pmd 1 //1
#define ptrs_per_pgd 2048 //pgd頁表數11位,共有2048個項
#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, int write_access)
static inline int handle_pte_fault(struct mm_struct *mm,
struct vm_area_struct *vma, unsigned long address,
pte_t *pte, pmd_t *pmd, int write_access)
//傳入的引數pte, 即為虛擬位址轉化中的pte頁表項,在do_anonymous_page函式中要實現的功能是分配乙個空閒的頁描述符,然後轉化成實體地址,即為頁框的實體地址,將該位址左移page_shift(12位),再賦給pte 項,所以可以將虛擬位址與實際的實體地址聯絡起來。
static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, pte_t *page_table, pmd_t *pmd,
int write_access)
while (0)
// #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
// #define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext) }
接上文的
#define pte_offset_map_lock(mm, pmd, address, ptlp) \ ()
#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
#define __pte_index(addr) (((addr) >> page_shift) & (ptrs_per_pte - 1))
//虛擬位址對應的pte項
Linux記憶體對映
使用記憶體對映處理大檔案很方便,在windows系統中,實現了這樣的藉口。在linux中我們也可以通過mmap函式來實現。以下內容完全參考自 如有冒犯,請諒解 mmap函式實現把乙個檔案對映到乙個記憶體區域,從而我們可以像讀寫記憶體一樣讀寫檔案,他比單純呼叫read write也要快上許多。在某些時...
linux記憶體對映
記憶體管理分為對連續物理記憶體區管理和非連續記憶體區管理,本文主要講解連續的物理記憶體區管理的技術中所涉及到的核心線性位址空間對映的相關知識。涉及到的東西有 頁框,管理區 高階記憶體,低端記憶體 高階記憶體對映等,這些知識是掌握夥伴系統演算法和slab分配器的基礎。一 頁框 頁框為物理記憶體分配的基...
linux記憶體對映
記憶體管理分為對連續物理記憶體區管理和非連續記憶體區管理,本文主要講解連續的物理記憶體區管理的技術中所涉及到的核心線性位址空間對映的相關知識。涉及到的東西有 頁框,管理區 高階記憶體,低端記憶體 高階記憶體對映等,這些知識是掌握夥伴系統演算法和slab分配器的基礎。一 頁框 頁框為物理記憶體分配的基...