Chinaunix首页 | 论坛 | 博客
  • 博客访问: 622006
  • 博文数量: 69
  • 博客积分: 1891
  • 博客等级: 上尉
  • 技术积分: 1359
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-20 23:38
文章分类

全部博文(69)

文章存档

2012年(46)

2011年(23)

分类: LINUX

2012-03-20 00:31:46

上文介绍了页表项和内存之间的映射,这里介绍操作页表项的函数
1、将pte_t等类型转换为unsigned long 的函数
 pgd_val,pud_val,pmd_val,pte_val,pgprot_val

以下是ptd_val的代码:

点击(此处)折叠或打开

  1. static inline pteval_t pte_val(pte_t pte)
  2. {
  3.         pteval_t ret;

  4.         if (sizeof(pteval_t) > sizeof(long))
  5.                 ret = PVOP_CALLEE2(pteval_t, pv_mmu_ops.pte_val,
  6.                                    pte.pte, (u64)pte.pte >> 32);
  7.         else
  8.                 ret = PVOP_CALLEE1(pteval_t, pv_mmu_ops.pte_val,
  9.                                    pte.pte);

  10.         return ret;
  11. }
这里有个诡异的POVP_CALLEE2和PVOP_CALLE1,按照下面的定义貌似是一段汇编代码,感觉这个功能不是很负责,内核为什么要这么做呢,网上资料很少,只找到下面链接的一条信息,貌似和寄存器有关系,后面再看看。

点击(此处)折叠或打开

  1. #define PVOP_CALLEE2(rettype, op, arg1, arg2) \
  2. __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \
  3. PVOP_CALL_ARG2(arg2))


2、以上的逆转换,将unsigned long转为pgd_t,pud_t,pmd_t,pte_t,pgprot_t

点击(此处)折叠或打开

  1. static inline pgd_t __pgd(pgdval_t val)
  2. {
  3.         pgdval_t ret;
  4.         
  5.         if (sizeof(pgdval_t) > sizeof(long))
  6.                 ret = PVOP_CALLEE2(pgdval_t, pv_mmu_ops.make_pgd,
  7.                                    val, (u64)val >> 32);
  8.         else
  9.                 ret = PVOP_CALLEE1(pgdval_t, pv_mmu_ops.make_pgd,
  10.                                    val);

  11.         return (pgd_t) { ret };
  12. }
这里也用到了那个神奇的调用


阅读(2084) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~