各位小伙伴,我是小笨叔,从今天开始,笨叔尽量每天给大家分享一点点小东西,可能是笨笨的小点滴,就像小雨点一样,它会慢慢汇合到大江大海!
前两天有一个两个小伙伴讨论这么一个问题。
A :  在do_page_fault函数中有这样一段代码,这都是在内核中的代码了为什么还要判断是在内核态还是在用户态?   处理异常时肯定是在内核态吧?
if (!user_mode(regs))
goto no_context;
B: 内核常驻内存,不会缺页,相反,用户态内存有可能会产生缺页,进入内核的异常处理流程入口执行异常处理,没感觉有什么不妥,缺页不一定是在内核态,这个假设错的。
A: 既然这样的话,那么内核的代码永远不会发生缺页中断了。只能是用户进程发生缺页中断了。
A同学继续说。
A: 当发生异常时,arm的状态就会发生变化,此时不会是用户态的。arm不是有7种工作模式吗?
cpsr寄存器的低四位都为0的话,说明是用户模式,发生异常时有相应的异常模式,但是肯定不会是用户模式,所以我觉得内核代码中
if (user_mode(regs))
这条语句永远不会成立,
#define user_mode(regs)\
(((regs)->ARM_cpsr & 0xf) == 0)
从它的实现来看,就是判断最低4位是否为0,显然在异常模式下,不可能为0的
上面是A同学和B同学的对话,你们觉得他们讨论的东西都对吗?
01  关于异常
我们理解的CPU不就是干两件事情嘛?一个是取指令,另外一个是把指令给执行了。就好比我家小朋友,她名字叫做小笨笨。我和她说,小笨笨,你去冰箱里帮爸爸拿一罐可乐。小朋友第一件事情,就是要听到我说的话,这个就是取指令,她听懂了之后,她可能有如下几个行为。
            1. 她去冰箱给我拿了一罐可乐给我

             2. 她走去冰箱那里,但是中途遇到妈妈,妈妈逗她玩了一会,她去厨房给我拿了一个苹果
             3. 耍赖,跑了
上面三种情况,就是CPU的三种情况,第一个是CPU正常执行了这条命令,第二种情况,正在执行这条指令的时候,中途遇到问题了,结果发生错误了。第三条,简直就是一条非法指令。
对于ARM处理器来说,支持4大类的异常。
      1. 中断(interrupt)。就是我们平常理解的中断,主要由外设触发,是典型的异步异常。 ARM中主要包括两种类型的中断:IRQ(普通中断)和FIQ。
       2. 异常(aborts)可能是同步或异步异常。包括指令异常(取指令时产生)、数据异常(读写内存数据时产生),可以由MMU产生(比如典型的缺页异常),也可以由外部存储系统产生(通常是硬件问题)。
      3.  复位(reset)复位被视为一种特殊的异常。
      4. 异常指令。由异常触发指令触发的异常,比如Supervisor Call (SVC)、Hypervisor Call (HVC)、Secure monitor Call (SMC),SWI等
   那么ARM处理器在发生异常之后,通常会有一个异常向量表来和软件进行交互,因为异常发生了,处理器自己处理不了,需要操作系统或者软件来参与。下面这张图就是ARM手册上的列出来的异常向量表。
这张图是比较简单的明了的vector table。
通常异常发生之后,ARM处理器会帮我们做一些事情,这些事情是硬件帮忙我们做的:
   1. 把下一条指令的地址(返回地址)保存到新处理器模式的LR寄存器
   2. 把cpsr保存到spsr中
   3. 设置适当的cpsr(改变处理器的ARM状态、改变处理器进入相应的异常模式、(视情况)改变中断禁止位禁止相应中断)
  4. 设置PC指向异常向量表中对应的地方
那么软件需要做些啥呢???
 1. 保存当前共用寄存器的值,(如SVC模式和IRQ模式共用r0~r12 以及r15及pc)到当前模式的栈内存。保证之前模式的值不被破坏。
  2. 进入异常处理函数。处理异常。
   3. 中断返回,将之前保存到栈里的值读回,并SPSR的值赋值给CPSR实现主动切换到之前的模式
02

所以回到刚才那个同学的讨论,当执行到do_page_fault时,这时候已经是在SVC模式,也就是内核模式,但是发生异常的那个时间点,有可能是在用户模式也可能是在内核模式,所以,在do_page_fault时,数据结构struct pt_regs保存的是 发生异常现场时候的寄存器上下文,而不是do_page_fault当前的寄存器的状态,比如CPSR。
注意这里do_page_fault函数里的第三个参数regs, 不要被regs的名字迷惑了,虽然她长得好看,但是不是表示当前这个时间点的 寄存器的状态哟。
struct pt_regs数据结构定义如下。
  最后记得关注笨叔的 奔跑吧Linux社区哟!
继续阅读
阅读原文