内核接口函数

内存管理相关的

1.1 p

1.1 pte_offset_kernel

pte = pte_offset_kernel(pmd, vaddr);
//页目录项的某一项的线性地址,
//
//
//


 #define pte_offset_kernel(dir, address) \                                       
         ((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
//  dir就是页目录项其中一项的线性地址。*(dir)就是页目录项中存储的页表物理地址加上12位属性值
//  ((pte_t *) pmd_page_kernel(*(dir)) 就是这个页目录项指向的页表的基地址(线性地址)加上address在页中偏移量。
//  这个函数的作用就是 找出address所属的页地址。
//  比如address=0xffff4000    dir=0xc03cbffc    *dir=0x44a007
//  pte_index(address)=0x3f4  pmd_page_kernel(*dir)=0xC044 a000
//  pte_offset_kernel(dir, address)=0xC044 a000+0x3f4*sizeof(unsigned long)=0xC044 afd0
//  这个函数,就是根据address所属的页目录项的地址,以及address,找出存储address所属的页的基地址
//  在使用这个函数前需要,找出address所属的页目录项的地址。

 #define pmd_page_kernel(pmd) \                                                                                                                                                                                
       ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
//pmd也就是页目录存的,页表的物理的前20位,加上12位的属性
//这个函数就是把页目录项中,存的页表地址,先去掉12位属性,然后通过__va转换成线性地址


335 #define pte_index(address) \                                                                                                                                                                                  
336                 (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
找出地址所属的页地址,在页表中的偏移量。

例子

284         pgd = swapper_pg_dir + pgd_index(vaddr);                                
285         pud = pud_offset(pgd, vaddr);                                           
286         pmd = pmd_offset(pud, vaddr);                                           
287         pte = pte_offset_kernel(pmd, vaddr); 

pgd_index

#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) 

就是取去虚拟地址的高10位(i386)

pgd_offset/pud_offset/pmd_offset

#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))

取出结构体中pgd指针,然后加上偏移量。
例子:
如果:
mm->pgd=0xc03cb000 address=0xffff4000
则:
pgd_index(address)=0x3ff
pgd_offset(mm, address)=0xc03cb000+0x3ff*4=0xc03cbffc
因为pgd是unsigned long指针,所以结果要乘以4

 36 static inline pud_t * pud_offset(pgd_t * pgd, unsigned long address)                                                                                                                                          
 37 {                                                                               
 38         return (pud_t *)pgd;                                                    
 39 }  

说明:直接返回参数

 39 static inline pmd_t * pmd_offset(pud_t * pud, unsigned long address)                                                                                                                                          
 40 {                                                                               
 41         return (pmd_t *)pud;                                                    
 42 } 

说明:直接返回参数。

你可能感兴趣的:(内存管理)