“ 各位小伙伴,我是小笨叔,从明天开始,笨叔尽量每天给大家分享一点点小东西,可能是笨笨的小点滴,就像小雨点一样,它会缓缓会合到大江大海!”

前两天有一个两个小伙伴探讨这么一个问题。

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状态、扭转处理器进入相应的异样模式、(视状况)扭转中断禁止位禁止相应中断)
  1. 设置PC指向异样向量表中对应的中央

那么软件须要做些啥呢???

  1. 保留以后共用寄存器的值,(如SVC模式和IRQ模式共用r0~r12 以及r15及pc)到以后模式的栈内存。保障之前模式的值不被毁坏。

    1. 进入异样处理函数。解决异样。

      1. 中断返回,将之前保留到栈里的值读回,并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社区哟!