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
系统的二级页表(对应
ARM
的
TLB
,
Linux
中叫
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
如有错误,欢迎指正!