• 内存相关的宏


    #define PAGE_SHIFT        12                                         // 页偏移
    #define PAGE_SIZE        (_AC(1,UL) << PAGE_SHIFT)    //页大小
    #define PAGE_MASK        (~((1 << PAGE_SHIFT) - 1))   //取页

    还有PAGE_OFFSET,内核中通常为3G。
    这几个宏把无符号整数转换成对应的类型
       

       #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)

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

    #define __pa(x)                 ((unsigned long)(x)-PAGE_OFFSET)


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

    #define __va(x)                 ((void *)((unsigned long)(x)+PAGE_OFFSET))


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

    #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)


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

    #define pfn_to_page(pfn)        (mem_map + (pfn))


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

    #define page_to_pfn(page)       ((unsigned long)((page) - mem_map))


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

    #define virt_to_page(kaddr)     pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)


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

    #define 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得到对应的物理页描述符

    #define pte_page(x)             pfn_to_page(pte_pfn(x))


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

    #define pte_none(x)             (!(x).pte_low)


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

    #define 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))
  • 相关阅读:
    分部视图在ASP.NET MVC中的应用
    SVN、Git设置提交时忽略的文件
    TortoiseSVN使用步骤和trunk,Branch,Tag详细说明
    SQL Server系统表介绍与使用
    C#中Task的使用简单总结
    Auto Encoder用于异常检测
    mac bash 下使用vi 快捷方式——因为没有alt键 所以没有办法 用vi模式也非常方便的
    daal utils printNumericTable
    https 不会被中间人攻击——因为中间人即使拿到了数据,也是加密的
    Let's Encrypt 免费通配符 SSL 证书申请教程——但是也需要email,域名所有权等,如果是黑产用的话会这样用吗?会不会暴露自己身份???
  • 原文地址:https://www.cnblogs.com/chaozhu/p/6046902.html
Copyright © 2020-2023  润新知