当前位置: 首页 > news >正文

优秀app网站设计咨询服务公司

优秀app网站设计,咨询服务公司,物流商 网站建设方案,外贸公司管理系统继续上次的内容#xff0c;在上次的分析中我们已经对SWI,FIQ,IRQ的流程有了一个大概的认识#xff0c;下面继续对DataAbort和PrefetchAbort以及公共分发程序CommonHandler进行一下认识#xff0c;完整异常处理的流程。 2-4 DataAbort服务程序 由数据异常触发… 继续上次的内容在上次的分析中我们已经对SWI,FIQ,IRQ的流程有了一个大概的认识下面继续对DataAbort和PrefetchAbort以及公共分发程序CommonHandler进行一下认识完整异常处理的流程。  2-4 DataAbort服务程序         由数据异常触发通常有三种指令引发数据异常,这些指令都是访存操作而且都是由MMU的引入后才可能会发生的情况。1.LDR/STR指令.2.SWAP指令。3.LDM/STM指令。而MMU的失效类型又分为4种存储访问失效、地址对齐失效、地址变换失效、域控制器失效、访问控制权限失效.因此当异常发生后,需要通过访问CP15来获知异常的产生具体原因和情况。mfc是微软的asmarm宏汇编器专用的宏指令相当于mcr指令。数据异常和中断模式一样都有可能在互锁时发生所以同样需要对执行互锁的情形进行处理。正常的情况下在保存完相关的寄存器后就会读取CP15的c6,c5,c13三个寄存器。这三个寄存器分别是失效地址寄存器(FAR)、失效状态寄存器(FSR)、进程号寄存器(这个翻译得不好PCP15)然后根据具体的失效类型来进行处理。在ARM处理器中对于CP15有三种地址类型VA,PA,MVA。VA(virtual address)也就是我们通常说的虚拟地址或逻辑地址也就是通过CP15按照PT转换后的地址而PA(physical Address)则是对应于AMBA上的地址对应的是电气介质也就是物理地址。而MVA(Modified virtual address)则是对应于Cache和TLB中转换地址。          NESTED_ENTRY    DataAbortHandler          sub     lr, lr, #8                      ; repair continuation address          stmfd   sp!, {r0-r3, r12, lr}          PROLOG_END sub     r0, lr, #INTERLOCKED_START          cmp     r0, #INTERLOCKED_END-INTERLOCKED_START          bllo    CheckInterlockedRestart          mfc15   r0, c6                          ; (r0) FAR                 mfc15   r1, c5                          ; (r1) FSR          mfc15   r2, c13                         ; (r2) process base address                   ;  FARFault address register      ;  CP 15: CRn 6, CRm 0, op_1 0, op_2 0          ;  FSRFault status register          ;  CP 15: CRn 5, CRm 0, op_1 0, op_2 0          ;  PCP15: PID  Process ID register      ;  CP 15: CRn 13, CRm 0, op_1 0, op_2 0                   tst     r0, #0xFE000000                 ; slot 0 reference?          orreq   r0, r0, r2                      ; (r0) process slot based address          and     r1, r1, #0x0D                   ; type of data abort          cmp     r1, #0x05                       ; translation error?          movne   r0, #0          CALLEQ  LoadPageTable                   ; (r0) !0 if entry loaded          tst     r0, r0          ldmnefd sp!, {r0-r3, r12, pc}^          ; restore regs continue          ;*********************************************************************          ldr     lr, KData-4          ldmfd   sp!, {r0-r3, r12}          stmdb   lr, {r0-r3}          ldmfd   sp!, {r0}          str     r0, [lr]                        ; save resume address          mov     r1, #ID_DATA_ABORT              ; (r1) exception ID          b       CommonHandler ENTRY_END DataAbortHandler  在DataAbort发生后c6中的数据保存的就是导致异常的MVA地址通过windowsCE memory layout可以了解到当前进程的运行空间是在slot0也就是0x0-0x1fffffff的位置事实上这个slot上的数据仅仅是实际进程的一个副本所以如果数据异常发生在slot0就需要去找到进程所在的实际slot的存放地址然后尝试将内核的页表复制到硬件实际使用的页表以达到恢复的目的。如果复制动作成功则返回否则进入异常分发程序CommonHandler。  2-5 PrefetchAbort服务程序     对于ARM处理器来说由于其内部使用了哈佛结构---独立的数据的指令总线因此在数据/指令的读取过程中产生的异常也就很自然地可以区分开来本质上而言这些异常都是同属于存储访问失败产生的异常因此这些异常都由MMU相关在ARM手册中DataAbort和PrefetchAbort都称为Memory abort。Prefetch也就是在预取指令的动作后产生的当处理器运行到这个无效的指令时(这个无效与undefined exception中的不可识别不同是指不存在或是无法得到)就触发该异常。所以不是所有的指令无效都产生异常例如一个分支程序指向一个不可访问的区域而之前的分支指向另一个可访问区域时。后一个区域尽管预取无效但是由于该分支并不执行所以并不产生异常。所以prefetch的准确定义应该是prefetch and executes Abort:).在ARMV5指令集中BKPT也可以产生预取无效但由于这儿的ARM通常都是ARM9的也就是使用ARMV4指令所以不讨论BKPT的情形。由于数据异常和指令异常同属存储异常而且两个异常不可能会相互中断所以在ARM的设计上这两个异常使用同一组寄存器abort组。    ALTERNATE_ENTRY PrefetchAbort sub     lr, lr, #0xF0000004  ;考察产生异常的地址是否在0xf0000000-0xf0010400            cmp     lr, #0x00010400    ;之间,如果是进入系统调用处理          bhs     ProcessPrefAbort      ;-正常的预取异常 执行ProcessPrefAbort      ...        ProcessPrefAbort          add     lr, lr, #0xF0000000             ; repair continuation address          stmfd   sp!, {r0-r3, r12, lr}             mov     r0, lr                          ; (r0) faulting address          mfc15   r2, c13                         ; (r2) process base address          tst     r0, #0xFE000000                 ; slot 0 reference?          orreq   r0, r0, r2                      ; (r0) process slot based address          CALL    LoadPageTable                   ; (r0) !0 if entry loaded          tst     r0, r0          ldmnefd sp!, {r0-r3, r12, pc}^          ; restore regs continue          ldmfd   sp!, {r0-r3, r12}          ldr     lr, KData-4          stmdb   lr, {r0-r3}          ldmfd   sp!, {r0}          str     r0, [lr]                        ; save resume address          mov     r1, #ID_PREFETCH_ABORT          ; (r1) exception ID          b       CommonHandler 下面来结合windowsCE的情形。PrefetchAbort就是该服务程序的入口在程序的一开始将lr也就是产生异常的地址4(流水线导致)的地址减掉0xf000 0004并比较是否在0-0x10400之间这是为什么呢原来windowsCE除了使用PrefetchAbort服务程序作为正常的异常处理以外还使用这个异常作为系统调用的手段。通过0xf0000000-0xf0010400这段地址的预取异常来进行系统调用。我们下面看处理预取失败的情况绕开系统调用的先不管。也就是ProcessPrefAbort的分支。 这个分支的内容就与上面DataAbort的内容一样了我就不再重复了。   2-6异常分发 CommonHandler 到此为止我们已经了解了windowsCE对各个异常/中断模式下的处理情况已经基本做了一个了解但是仍然有一些情况是送到CommonHandler来处理的下面就对这个分发程序进行分析完整windowsCE对整个异常流程的处理。             ALTERNATE_ENTRY CommonHandler          mrs     r2, spsr          msr     cpsr_c, #SVC_MODE:OR:0x80       ; switch to Supervisor mode w/IRQs disabled          ldr     r3, KData                      ; (r3) ptr to KData page  在CommonHandler开始系统就转入Supervisor态来执行。      ; Save the processor state into a thread structure. If the previous state was  ; User or System and the kernel isnt busy, then save the state into the current  ; thread. Otherwise, create a temporary thread structure on the kernel stack.  ;  ;       (r1) exception ID  ;       (r2) SPSR  ;       (r3) ptr to KData page  ;       Interrupted r0-r3, and Pc saved at (r3-0x14)  ;       In Supervisor Mode.          ALTERNATE_ENTRY SaveAndReschedule and     r0, r2, #0x1f                   ; (r0) previous mode          cmp     r0, #USER_MODE                  ; Z set if from user mode          cmpne   r0, #SYSTEM_MODE                ; Z set if from System mode          bne     %F50                            ; reentering kernel, save state on stack                          ; 现场保护分支                          发生异常前模态是否是用户态和系统态。FIQ/IRQ/SVC/Abort/Undef          ldr     r0, [r3,#pCurThd]               ; (r0) ptr to current thread                              ; r0 kDatapCurThd                                    add     r0, r0, #TcxR4                  ; (r0) ptr to r4 save                              ; r0 kDatapCurThdTcxR4                              ;THREAD_CONTEXT_OFFSET后的0x44bytes用于备份寄存器的内容          stmia   r0, {r4-r14}^                   ; save User bank registers                          ****************************************************          ; Save registers for fault from a non-preemptible state.  50      sub     sp, sp, #TcxSizeof              ; allocate space for temp. thread structure          cmp     r0, #SVC_MODE          bne     %F55                            ; must mode switch to save state          add     r0, sp, #TcxR4                  ; (r0) ptr to r4 save area          stmia   r0, {r4-r14}                    ; save SVC state registers          add     r4, sp, #TcxSizeof              ; (r4) old SVC stack pointer          str     r4, [r0, #TcxSp-TcxR4]          ; update stack pointer value          b       %B10 55          msr     cpsr, r2                        ; switch to mode exception came from add     r0, sp, #TcxR4                  ; (r0) ptr to r4 save area          stmia   r0, {r4-r14}                    ; save modes register state          msr     cpsr_c, #SVC_MODE:OR:0x80       ; back to supervisor mode          b       %B10                            ; go save remaining state 在进行统一的处理之前需要保存前态寄存器组的状态以便后面恢复在用户态和系统态的情况下直接保存用户态的寄存器。同时上面可以看到到达50的条件是前一状态为FIQ/IRQ/SVC/Abort/Undef也就是说为异常套嵌的情况系统套嵌的情形前面已经处理过了。这里首先处理的是SVC下被套嵌的情形上面可以看到SVC模式都是用于异常/中断后的具体事件处理(eg: HandleException)所以这个流程并不是独立存在的因此当前寄存器就是前态寄存器所以到这里需要重新计算stack指针的位置。而另外的FIQ/IRQ/Abort/Undef模式下的寄存器的保存则需要切换当前状态来进行所以在进入真正的处理程序之前需要不同的分支来保存前态寄存器状态。可为什么前后都看不到System模式下的寄存器保存呢这是因为系统态和用户态使用同一组寄存器所以保存用户态寄存器组就达到了现场保护了。这种设计完全是因为ARM分组寄存器的架构决定的所以需要不同的处理。通过上面的处理所有的情况都已经统一的完成了现场保护的动作下面就需要进一步处理这些异常了。  10      ldmdb   r3, {r3-r7}                     ; load saved r0-r3 Pc                          ;KData之前的16byte用作传递参数用                          ;所以每个异常句柄最后都由将r0-r3和PC送到这个位置。                         stmdb   r0!, {r2-r6}                    ; save Psr, r0-r3          sub     r0, r0, #THREAD_CONTEXT_OFFSET  ; (r0) ptr to Thread struct          str     r7, [r0,#TcxPc]                 ; save Pc          mfc15   r2, c6                          ; (r2) fault address          mfc15   r3, c5                          ; (r3) fault status      ;r0Kdata      ;r1exception ID      ;r2FAR      ;r3FSR     ; Process an exception or reschedule request. FirstSchedule  20      msr     cpsr_c, #SVC_MODE               ; enable interrupts CALL    HandleException          ldr     r2, [r0, #TcxPsr]               ; (r2) target status          and     r1, r2, #0x1f                   ; (r1) target mode          cmp     r1, #USER_MODE          cmpne   r1, #SYSTEM_MODE          bne     %F30                            ; not going back to user or system mode          ;System mode and user mode branch          add     r0, r0, #TcxR3          ldmia   r0, {r3-r14}^                   ; reload user/system mode registers          ldr     r1, KData          msr     cpsr_c, #SVC_MODE:OR:0x80       ; disable all interrupts          ldrb    r1, [r1, #bResched]             ; (r1) nest level reschedule flag          cmp     r1, #1          mov     r1, #ID_RESCHEDULE          beq     %B20                            ; interrupted, reschedule again          msr     spsr, r2          ldr     lr, [r0, #TcxPc-TcxR3]          ldmdb   r0, {r0-r2}          movs    pc, lr                          ; return to user or system mode HandleException是实际进行异常处理的函数针对上面没有处理完的异常进一步分析并进行处理。这个函数是没有公开代码的所以没有办法进一步深入下去。由于处理的异常类型比较多所以这个异常处理函数的代码量是相当大的因此会耗费相对比较多的时钟周期在之前的代码中我们都是在关闭中断的情况下进行异常处理如果在这里还不打开中断的话整个异常处理过程会相当的长这样会很大程度上影响系统的实时性所以在这里调用HandleException之前是将中断重新打开的待到处理完成再将中断关闭。对于这些异常如果不能处理就只有两种情况1.结束该进程/线程。2.挂起系统.第二种情况下挂起系统HandleException是不会返回的。因此只有异常处理正常流程和结束线程的可能。对于返回的情况这个时候如果返回触发异常的地址继续运行的话仍然会导致异常所以结束进程/线程都需要重新调度才能完成了。对于异常处理成功的情形就不必调度了直接就可以返回产生异常的地方继续执行。在这里还要考虑套嵌(这里仅仅是指系统模式和兼管模式的异常套嵌)的情形也就是中断/异常已经进入调度状态又再次产生中断/异常这个时候就强行取消上一次调度进而重新调度.这用于调度过程中遇到异常恢复和剥夺的情况如果不属于这种情况的话就直接恢复寄存器状态并且返回中断点继续执行。 ; Return to a non-preemptible privileged mode.  ;  ;       (r0) ptr to THREAD structure  ;       (r2) target mode 30    msr     cpsr, r2                        ; switch to target mode          add     r0, r0, #TcxR0          ldmia   r0, {r0-r15}                    ; reload all registers return  通过HandleException处理以后已经完成了所有异常的处理所以这里只是考虑反回的情况,由于这里不包含用户模式下的处理所以这里处理的都是特权模式完全可以访问kdata区域这里就直接利用Kdata区域中的线程备份来完成恢复寄存器和返回。
http://www.zqtcl.cn/news/363876/

相关文章:

  • 单县网站定制培训机构专业
  • 网站防红链接怎么做网站建设中提示页面
  • 网站开发和游戏开发的区别互联网服务平台投诉
  • 杭州定制网站公司出名的设计网站
  • 网站查询访问注册电气工程师考试
  • 北京企业网站推广哪家公司好电商平台代运营
  • 北京快速建站模板信息管理系统网站开发
  • 做网站后台需要写代码吗做网站收多少钱
  • 企业手机网站建设咨询为企业设计一个网站
  • 做网站平台成本珠海自适应网站设计
  • 做网站手机端需要pc端的源代码吗经营网站需要注意什么
  • 域名购买之后怎么做网站做+淘宝客最大的网站是叫什么
  • 在线营销型网站wordpress 怎么添加即时联系窗口
  • 网站加图标网站开发属于无形资产
  • 个人网站开发与设计摘要企业营销策划心得体会
  • 专注苏州网站优化自建网站的优缺点
  • 网络建站怎么做js与asp.net做的网站
  • 个人网站设计理念自己做简历网站
  • 做网页设计的网站网站流量多少做网盟
  • 上海协会网站建设网站制作培训费用
  • 学会网站建设总结淮北市建市
  • 泉州开发网站的公司有哪些域名不用了需要注销吗
  • 重庆网站推广平台东莞整站优化火速公司
  • 商务网站建设综合实训网站推广效果怎么样
  • 成都品牌网站建设电话项目外包平台接活
  • 教育培训类网站模板上海有几个区最好
  • 公司网站维护怎么维护东莞网站建设it s
  • pc网站怎么做男科医院治疗一次2000元
  • 电子网站建设心得企业查询app排行榜
  • 杭州做网站的科技公司永川做网站的公司