Linux越界访问/用户栈扩展/页面周转

一、越界访问
        当页式转换过程中出现无法访问物理内存单元时,CPU会产生缺页中断,几种情况:
1、响应的目录项目PGD或者页表PT空,就是尚未建立起映射或者映射已经撤销(例如,mmap映射后ummap,仍然访问之前的地址)
2、物理页面不在内存中,已被交换到磁盘上
3、权限不符,例如企图写一个只读的页面
        这里假定已经到达处理服务程序的主体do_page_fault()函数。以下是(非法访问已撤销的地址)处理步骤:
1、保存失败的线性地址到CR2里,还传过来了pt_regs的结构体指针,存放当时寄存器的副本,还有一个error_code
2、获取当前进程结构task_struct(TS, 存放当前进程的一些信息)
3、调用in_interrupt检查失败是否发生在某终端服务里,而与当前进程无关,检查当前进程的mm_struct指针是否为空,空的话说明映射还未建立,如果都不是,则跳到别处处理
4、使用find_vma()函数查找是否越界访问(栈空间以上)或者进程内的空洞区地址,就跳转bad_area处理,否则跳转good_area处理
5、否则,就是堆栈里的数据访问出错,查看errno_code,然后设置一下TS,向进程发出信号
6、中断/异常返回前都会检查未处理信号,有些信号会强制退出进程,有些会交给进程处理
二、用户栈扩展
        如果访问的地址在栈边,并且与栈底的差距在%esp-32以内(intel有条指令一次性压栈32字节),系统会检查是否还有空洞可以被分配,
如果没了,会跳到bad_area处理,若可以,则调用expand_stack改变栈大小,然后到good_area去处理增加映射,可能要增加页表项PTE
这时候会alloc一个PTE,PTE有缓存,被删掉的PT会缓存起来,需要再分配的时候会先从缓存获取。
        然后调用handle_pte_fault()初始化PTE,接着给物理内存分配页面,一般通过vm_operations_struct结构体里的函数指针,
若分配内存的函数指针为空,就调用默认函数分配
        再设置页面的一些属性标志。
      
        当CPU从缺页异常返回到用户空间时,会先执行因映射失败的而夭折的指令,才往下执行。
        注意这里异常与中断不同,中断返回后是直接执行下一条指令。
 
三、页面周转
        内存页面周转包括两方面,一是页面的分配、使用和回收,二是盘区的交换。
只有用户空间的页面才会被交换到磁盘或者文件中去。包括以下几种:
1、普通页面,包括代码段、数据段、堆栈段等
2、mmap映射到用户空间的内容
3、进程间的共享内存区
        每个内存页面都对应一个page数据结构,系统初始化阶段,会为每个物理内存页面建立一个page结构,并形成一个page数组。
使用一个全局量mem_map指向这个数组
        同时,将这些页面拼成物理地址连续的许多块,再根据块大小建立若干管理区,每个管理区设置一个空闲块队列,以便分配使用。
        被交换到磁盘去的页面内核使用swap_info_struct结构体管理,其中的swap_map指向一个数组,
里面的每个数代表盘上的一个物理页面,下标决定了盘上或文件上的位置。数组的大小取决于交换设备或者页面的大小。
用一个swap_list_t链表来记录这些swap_info_struct,盘上的页面用一个swap_enter_t结构来管理。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值