天天看点

与内存管理相关的几个宏

这几个宏把无符号整数转换成对应的类型

#define __pte(x) ((pte_t) { (x) } )

   #define __pmd(x) ((pmd_t) {

(x) } )

   #define __pgd(x) ((pgd_t) { (x) } )

#define __pgprot(x)     ((pgprot_t) { (x) }

)

   根据x把它转换成对应的无符号整数

#define pte_val(x)      ((x).pte_low)

#define pmd_val(x)      ((x).pmd)

#define pgd_val(x)      ((x).pgd)

#define pgprot_val(x)   ((x).pgprot)

与下一个页框对齐

   #define

PAGE_ALIGN(addr)       

(((addr)+PAGE_SIZE-1)&PAGE_MASK)

把内核空间的线性地址转换为物理地址

__pa(x)                

((unsigned long)(x)-PAGE_OFFSET)

把物理地址转化为线性地址

__va(x)                

((void *)((unsigned long)(x)+PAGE_OFFSET))

首先把pfn页框号转化为内核线性地址, 然后左移12位, 得到对应的内核线性地址

pfn_to_kaddr(pfn)      __va((pfn) <<

PAGE_SHIFT)

   根据页框号得到对应的物理页描述符

pfn_to_page(pfn)        (mem_map +

(pfn))

   根据物理描述符得到对应的页框号

page_to_pfn(page)       ((unsigned long)((page) -

mem_map))

根据内核线性地址得到其对应的物理页描述符

virt_to_page(kaddr)     pfn_to_page(__pa(kaddr) >>

   清除一个页表项并返回前一个值

ptep_get_and_clear(xp) __pte(xchg(&(xp)->pte_low, 0))

判断一个页表项是否指向同一页并且访问优先级相同

   #define pte_same(a,

b)          ((a).pte_low ==

(b).pte_low)

   x是页表项值, 通过pte_pfn得到其对应的物理页框号,

最后通过pfn_to_page得到对应的物理页描述符

pte_page(x)            

pfn_to_page(pte_pfn(x))

   如果对应的表项值为0, 返回1

#define

pte_none(x)            

(!(x).pte_low)

   x是页表项值, 右移12位后得到其对应的物理页框号

pte_pfn(x)             

((unsigned long)(((x).pte_low >> PAGE_SHIFT)))

根据页框号和页表项的属性值合并成一个页表项值

   #define pfn_pte(pfn,

prot)      __pte(((pfn) << PAGE_SHIFT) |

pgprot_val(prot))

   根据页框号和页表项的属性值合并成一个中间表项值

#define pfn_pmd(pfn, prot)      __pmd(((pfn) <<

PAGE_SHIFT) | pgprot_val(prot))

向一个表项中写入指定的值

   #define set_pte(pteptr, pteval) (*(pteptr) =

pteval)

   #define set_pte_atomic(pteptr, pteval)

set_pte(pteptr,pteval)

   #define set_pmd(pmdptr, pmdval)

(*(pmdptr) = pmdval)

   #define set_pgd(pgdptr, pgdval) (*(pgdptr)

= pgdval)

   根据线性地址得到高10位值,

也就是在目录表中的索引

   #define pgd_index(address) (((address) >>

PGDIR_SHIFT) & (PTRS_PER_PGD-1))

根据mm和线性地址address得到目录项值

   #define pgd_offset(mm, address)

((mm)->pgd+pgd_index(address))

根据线性地址address提取在页表中的索引

   #define pte_index(address)

\

(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))

根据页描述符和属性得到一个页表项值

   #define mk_pte(page, pgprot)   

pfn_pte(page_to_pfn(page), (pgprot))