Linux用户进程内存分配及二级页表PTE的二三事

Linux 用户进程内存分配及二级页表 PTE 的二三事

我们在用调试器看 Linux 用户进程代码时,发现了一件很有意思的事情,在一段内存空间中,有一整页( 4K )都是 data abort ,如下:

第一页 4011c 000 数据正常

... ...

4011cfec [0xe28dd014]   add      r13,r13,#0x14

4011cff0 [0xe8bd40f0]   ldmfd    r13!,{r4-r7,r14}

4011cff4 [0xe12fff1e]   bx       r14

4011cff8 [0xe92d41f0]   stmfd    r13!,{r4-r8,r14}

4011cffc [0xe59f4064]   ldr      r4,0x4011d068

 

第二页 4011d000 都是 Data abort

4011d000       *** Data abort ***

4011d004       *** Data abort ***

4011d008       *** Data abort ***

4011d00c       *** Data abort ***

... ...

 

第三页 4011e000 数据正常

4011e000        数据正常

 

由于当时并不知道 Linux 是如何处理用户进程的内存分配,所以认为这是一个“错误”。既然有错误,我们决定找到这个问题发生的根源。

在追踪这个问题的过程中, leeming 同学做了一个很 BT 的实验。我简单说两句,详细大家可以去看他的文章( http://blog.chinaunix.net/u3/99423/showart_2096904.html )。大概的方法就是将物理内存全部 dump 出来,通过第一页的代码,比如 0xe59f4064 ,查找其在内存中的物理地址,再通过提取物理地址的前 20 位,就可以查找 Linux 系统的二级页表(对应 ARMTLBLinux 中叫 PTE )。这个实验虽然看上去很不可思议,但实现起来并不复杂。最终得到了 Linux 存放在内存中的 TLB 数据。

每个表项是 32bit

虚拟页地址     对应表项的内容

4011c 000              3156caae

4011d000              00000000

4011e000        3156faae

 

       很有意思, Data abort 的数据段,对应的 PTE 也是空的,这难道是一个系统错误?

       NO !经过进一步的学习后发现,在 Linux 系统中,这是一个很正常的现象。 Linux 在用户进程执行时并没有建立所有内存页面的映射,而是需要用到的时候再建立映射关系。当 Linux 用户进程访问到没有建立映射的页表(此时 PTE 指针为 0 ),会调用相应的函数进行处理,或建立、或换出,具体执行这个操作的函数叫 handle_pte_fault (),位于内核的 mm/memory.c 中。

       但是, Linux 是如何进入缺页处理的呢?

有两种情况,都是利用了 ARM 处理器的异常中断进行相应的处理。

       第一种是程序顺序执行,正常页面的最后一条指令执行完后进入空页面,当空页面的第一条指令进入 ARM 处理器流水线的执行周期时, ARM 处理器会报告一个指令预取异常中断,并跳转到地址 0x0c ,在 Linux 系统中由于使用了高地址向量表,所以会跳转到 0xffff000c 。此时 ARM 处理器进入 ABORT 状态,执行一系列代码保存现场(代码位于 /arch/arm/kernel/entry-armv.s ),然后进入 SVC 状态执行 arch/arm/mm/fault.c 中的 do_PrefetchAbort (),最后会调用 handle_pte_fault ()处理缺页异常。

       第二种情况,页面中的程序执行时需要使用未分配页面的数据,比如“ ldr r0, 未分配页地址”。遇到这种情况,就不是指令预取异常了,而是数据访问异常( Data abort )。此时处理器依然会进入 ABORT 状态,跳转到 0xffff0010 执行相应的 vector_dabt 代码( entry_armv.s )保存状态,进入 SVC 态,执行 do_DataAbort ()函数,最后同样调用 handle_pte_fault ()处理缺页异常。

       因此,最开始遇到的情况:三个 PTE ,中间是空的,这是一个很正常的情况。因为第三页很可能由于前面的调用而已经建立,第二页却还没有建立。

       至于 handle_pte_fault ()如何处理缺页异常,我还没有看完,就不在本文讨论了。已知至少有 do_no_page()do_swap_page()do_wp_page 等多种方式,此为后话。

       通过跟踪用户程序,发现 Linux 用户进程基本所有的页面都是这样处理,因此处理器会很频繁的进出 Abort 状态,执行页面处理函数,这是会不会效率有点低了呢?待研究。

      

阿虚( Rockie Cheng

       2009-11-21

 

本文为原创,转载请注明出处http://hi.baidu.com/aokikyon

如有错误,欢迎指正!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值