Linux用户进程内存分配及二级页表PTE的二三事
来源:互联网 发布:nba2k17流川枫捏脸数据 编辑:程序博客网 时间:2024/04/29 14:30
Linux用户进程内存分配及二级页表PTE的二三事
我们在用调试器看Linux用户进程代码时,发现了一件很有意思的事情,在一段内存空间中,有一整页(4K)都是data abort,如下:
第一页4011c000数据正常
... ...
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
虚拟页地址 对应表项的内容
4011c000 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
如有错误,欢迎指正!
- Linux用户进程内存分配及二级页表PTE的二三事
- Linux用户进程内存分配及二级页表PTE的二三事
- NT内核的内存分配(PDE与PTE)
- 《Linux内核编程》第十三章:Linux对进程内存的二级页式管理
- 进程的内存分配
- linux c进程内存分配
- 进程的内存分配情况
- C查看分配给用户的内存及分配给系统的内存大小
- 操作系统:模拟进程及内存分配
- [原创]我写的一个观察系统进程特定虚拟地址页PTE的工具
- Linux用户进程内存泄露
- linux 用户空间内存分配详解
- Linux操作系统中进程内存分配解析
- Linux系统如何为进程分配内存
- linux内存分配及内存管理
- 二级指针动态内存分配
- Linux进程使用内存的基本流程---Linux用户进程是如何释放内存的
- 子函数中的内存分配(二级指针的应用)
- capwap学习笔记——初识capwap(二)
- asp.net传大附件 webconfig设置
- UE/UI/UCD/UED是什么意思 有什么区别 - 附一些UED团队网站链接(转)
- 怎样学习C语言
- Junit 4
- Linux用户进程内存分配及二级页表PTE的二三事
- 指针
- 说不清的Brooks法则
- C语言函数
- hacmp failover 测试
- Linux 基础
- 常用mysql语句备忘
- Sql Server 2005/2008 SqlCacheDependency查询通知的使用总结
- capwap学习笔记——初识capwap(三)