在之前介绍malloc()和mmap()两个用户API函数的内核实现时,我们发现它们只建立了进程地址空间,在用户空间可以看到虚拟内存,但没有建立虚拟内存和物理内存之间的映射关系。当进程访问这些还没有建立映射关系的虚拟内存时,处理器自动触发一个缺页异常(也称为"缺页中断"),linux内核必须处理此异常。缺页异常是内存管理当中最复杂和重要的一部分,需要考虑很多的细节,包括匿名页面、KSM页面、page cache页面、写时复制、私有映射和共享映射等。

缺页异常处理依赖于处理器的体系结构,因此缺页异常底层的处理流程在内核代码中特定体系结构的部分。下面以ARMv7为例来介绍底层缺页异常处理的过程。

当在数据访问周期里进行存储访问时发生异常,基于ARMv7-A架构的处理器会跳转到异常向量表的Data abort向量中。Data abort的底层汇编处理和irq中断类似。汇编处理流程为__vectors_start->vector_dabt->__dabt_usr/__dabt_svc->dabt_helper->v7_early_abort,我们从ENTRY(v7_early_abort)开始介绍。

[arch/arm/mm/abort-ev7.S]

ENTRY(v7_early_abort)mrc p15, 0, r1, c5, c0, 0       @ get FSRmrc p15, 0, r0, c6, c0, 0       @ get FAR/** V6 code adjusts the returned DFSR.* New designs should not need to patch up faults.*/#if defined(CONFIG_VERIFY_PERMISSION_FAULT)/** Detect erroneous permission failures and fix*/ldr r3, =0x40d          @ On permission faultand r3, r1, r3cmp r3, #0x0dbne do_DataAbortmcr p15, 0, r0, c7, c8, 0       @ Retranslate FARisbmrc p15, 0, ip, c7, c4, 0       @ Read the PARand r3, ip, #0x7b           @ On translation faultcmp r3, #0x0bbne do_DataAbortbic r1, r1, #0xf            @ Fix up FSR FS[5:0]and ip, ip, #0x7eorr r1, r1, ip, LSR #1
#endifb   do_DataAbort

ARM的MMU中有如下两个与存储访问失效相关的寄存器。

  • 失效状态寄存器(Data Fault Status Register, FSR).

  • 失效地址寄存器(Data Fault Address Register, FAR).

当发生存储访问失效时,失效状态寄存器FSR会反映所发生的存储失效的相关信息,包括存储访问所属域和存储访问的类型等,同时失效地址寄存器会记录访问失效的虚拟地址。汇编函数v7_early_abort通过协处理器的寄存器c5和c6读取出FSR和FAR寄存器后,直接调用C语言的do_DataAbort()函数。

/** Dispatch a data abort to the relevant handler.*/
asmlinkage void __exception
do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{/*struct fsr_info数据结构用于描述一条失效状态对应的处理方案,下面给出,请立即查看*/const struct fsr_info *inf = fsr_info + fsr_fs(fsr);struct siginfo info;if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs))return;pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",inf->name, fsr, addr);show_pte(current->mm, addr);info.si_signo = inf->sig;info.si_errno = 0;info.si_code  = inf->code;info.si_addr  = (void __user *)addr;arm_notify_die("", regs, &info, fsr, 0);
}
static inline int fsr_fs(unsigned int fsr)
{return (fsr & FSR_FS3_0) | (fsr & FSR_FS4) >> 6;
}
struct fsr_info {int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);int sig;int code;const char *name;
};
@fn: 表示修复这条失效状态的函数指针.
@sig:表示处理失败时linux内核要发送的信号类型.
@name: 表示这条失效状态的名称.

[arch/arm/mm/fsr-2level.c]

tatic struct fsr_info fsr_info[] = {/** The following are the standard ARMv3 and ARMv4 aborts.  ARMv5* defines these to be "precise" aborts.*/{ do_bad,       SIGSEGV, 0,     "vector exception"         },{ do_bad,       SIGBUS,  BUS_ADRALN,    "alignment exception"          },{ do_bad,       SIGKILL, 0,     "terminal exception"           },{ do_bad,       SIGBUS,  BUS_ADRALN,    "alignment exception"          },{ do_bad,       SIGBUS,  0,     "external abort on linefetch"      },{ do_translation_fault, SIGSEGV, SEGV_MAPERR,   "section translation fault"    },{ do_bad,       SIGBUS,  0,     "external abort on linefetch"      },{ do_page_fault,    SIGSEGV, SEGV_MAPERR,   "page translation fault"       },{ do_bad,       SIGBUS,  0,     "external abort on non-linefetch"  },{ do_bad,       SIGSEGV, SEGV_ACCERR,   "section domain fault"         },{ do_bad,       SIGBUS,  0,     "external abort on non-linefetch"  },{ do_bad,       SIGSEGV, SEGV_ACCERR,   "page domain fault"        },{ do_bad,       SIGBUS,  0,     "external abort on translation"    },{ do_sect_fault,    SIGSEGV, SEGV_ACCERR,   "section permission fault"     },{ do_bad,       SIGBUS,  0,     "external abort on translation"    },{ do_page_fault,    SIGSEGV, SEGV_ACCERR,   "page permission fault"        },......
};

fsr_info[]数组列出了常见的地址失效处理方案,以页面转换失效(page translation fault)和页面访问权限失效为例,它们最终的解决方案是调用do_page_fault()来修复。

11. 缺页中断处理概述相关推荐

  1. 详解缺页中断-----缺页中断处理(内核、用户)

    一.什么是缺页中断? 进程线性地址空间里的页面不必常驻内存,在执行一条指令时,如果发现他要访问的页没有在内存中(即存在位为0),那么停止该指令的执行,并产生一个页不存在的异常,对应的故障处理程序可通过 ...

  2. Linux0.11 键盘中断处理过程

    Linux0.11 键盘中断处理过程 键盘中断初始化 在console.c的con_init(void)中: void con_init(void) {... set_trap_gate (0x21, ...

  3. linux缺页处理步骤,Linux缺页中断处理

    Linux缺页中断处理 在i386 CPU 将一个线性地址映射为物理地址的过程中,如果该地址的映射已经建立,但是发现相应的页面表项或目录项中的P(Present)标志为0,则表明相应的物理 页面不在内 ...

  4. 操作系统---(35)缺页中断与缺页中断处理过程

    1. 缺页中断 2. 缺页中断的断点 缺页中断是指令执行过程中产生的中断,而非(一般的中断)在一条指令执行完成后产生的. 3. 缺页中断的断点压入 当CPU执行指令希望访问一个不在内存的页面时,将产生 ...

  5. 模拟请求分页管理中地址转换和缺页中断处理_Linux内存管理:缺页异常(一)

    缺页异常: 缺页异常(Page Faults)属于ARM V8处理器的异常类型中的同步异常.当MMU走表时可能会产生若干种类型的MMU faults(有同步的也有异步的),其中的同步异常,即这里将要讨 ...

  6. 深度学习系列11:ReID概述和资源

    1. ReID算法介绍 综述相关资料:https://zhuanlan.zhihu.com/p/31921944 综述文章:https://arxiv.org/pdf/1610.02984.pdf 2 ...

  7. 2016/11/10 kettle概述

    ETL(Extract-Transform-Load,即抽取,转换,加载),数据仓库技术,是用来处理将数据从来源(以前做的项目)经过抽取,转换,加载到达目的端(正在做的项目)的过程.也就是新的项目需要 ...

  8. 修改掉Linux内核缺页中断处理的exception fixup表

    近日,我在写内核模块的时候犯了一个低级错误: 直接access用户态的内存而没有使用copy_to_user/copy_from_user! 在内核看来,用户态提供的虚拟地址是不可信的,所以在一旦在内 ...

  9. 【计算机操作系统】测试题:动态分区内存分配;调页系统;分页存储管理;快表是什么?计算指令操作数地址;有效存储访问时间,缺页次数,缺页率;

    目录 填空题: 选择题: 简答题: 应用题: 填空题: 1. 在动态分区式内存分配算法中,倾向于优先使用低地址部分空闲区的算法是   首次适应算法   :能使内存空间中空闲区分布较均匀的算法是  循环 ...

最新文章

  1. 优达学城《DeepLearning》2-1:卷积神经网络
  2. backup ram不稳定 stm32_STM32学习笔记
  3. 最新(2019/3)CSDN博客Markdown编辑格式说明,包含效果图
  4. Windows Azure Camp---漫步云端,创意无限
  5. free 内存 注意点的事
  6. 前端学习(3243):react的生命周期新
  7. 2017年网易校招题 输入一个数将其变为斐波那契数(最小步数)
  8. html5缓动下拉菜单,HTML5 Canvas鼠标跟随的缓动效果
  9. 编译原理教程_7 语法制导的语义计算
  10. 领存工业级 3U VPX 8TB 存储模块性能参数
  11. C#绘制简单围棋棋盘
  12. shader变体是什么_一种Shader变体收集和打包编译优化的思路
  13. 读书笔记3|使用Python,networkx对卡勒德胡赛尼三部曲之——《群山回唱》人物关系图谱绘制
  14. python三行情书代码_“三行情书”——给你三行代码的爱恋~
  15. 苹果在旧设备中修复了两个 iOS 零日漏洞
  16. 【图形学数学基础】第一章
  17. 安卓虚拟摄像头_iPhone 的第四颗摄像头位置,为什么给了激光雷达?
  18. 安全威胁分类STRIDE
  19. java 对大数据的处理
  20. HTB----Heist(Hard)

热门文章

  1. 移动平均法 VS 指数平滑法
  2. linux命令之删除
  3. 详解 JS 中 a.x = a = {} 到底发生了啥?(图文并茂,包你看懂)
  4. 看它!!!!看它!!快看!!!!
  5. 中国最牛的5位程序员
  6. “死锁”四个必要条件的合理解释
  7. Java生存技能汇总,程序员必看!
  8. Linux上的Shebang符号
  9. 大话设计模式——第二章:商场促销策略模式
  10. ✿bugku✿一切有为法如梦幻泡影