ARM中的流水线分为:取值,译码,执行,仿存,回写这五步,SWI(软中断)和UND中断都出现在译码阶段,而其他5种中断都发生在执行阶段。SWI和UND异常两种处理方法步骤都差不多,但是如果是异常出现在执行阶段要怎么样处理呢?

int main()
 10 { 
 11     //发生异常时会进入异常模式跳转到0000 0004地址处理异常事件   
 12     unsigned long source_addr=data_abort_init();
 13     //异常事件处理函数
 14     printf("swi_souce addr is %x\n",source_addr);
 15     //将异常处理地址的值放到0x60000004
 16     memcopy(0x60000010,source_addr,0x1000);
 17     
 18     enable_mmu();
 19     //内存映射将0x00000004映射到0x6000000004    
 20     __asm__ __volatile__( 
 21         "mov r0, #1\n"
 22         "ldr r1, [r0]\n"
 23      );
 24     printf("welcome back! \n"); 
 25 
 26 
 27 }

ARM多种异常的处理如果代码中的汇编语言执行的时候将会发生DATA Abrot异常,将会到0x0000010地址区执行处理代码其中,处理执行的时候发生异常和处理译码时候的异常都大同小异。但是需要注意的是:

 1 
  2 int (*printf)(char *, ...) = 0xc3e114d8;
  3 
  4 void init_ttb(unsigned long *addr);
  5 void enable_mmu(void);
  6 unsigned long data_abort_init();
  7 void memcopy(unsigned long* dest,unsigned long* source,int len);
  8 
  9 int main()
 10 {
 11     //发生OBORT异常时会进入异常模式跳转到0000 0010地址处理异常事件  
 12     unsigned long source_addr=data_abort_init();
 13     //异常事件处理函数
 14     printf("swi_souce addr is %x\n",source_addr);
 15     //将异常处理地址的值放到0x600000010
 16     memcopy(0x60000010,source_addr,0x1000);
 17 
 18     enable_mmu();
 19     //内存映射将0x00000004映射到0x6000000004    
 20     __asm__ __volatile__(
 21         "mov r0, #1\n"
 22         "ldr r1, [r0]\n"
 23      );
 24     printf("welcome back! \n");
 25 
 26 
 27 }
 28 
 29 void memcopy(unsigned long* dest,unsigned long* source,int len)
 30 {
 31     int i=0;;
 32     for(i=0;i<len;i++)
 33         dest[i]=source[i];
 34 }
 35 
 36 unsigned long  data_abort_init()
 37 {
 38     unsigned long source;
 39     __asm__ __volatile__(
 40 
 41          "ldr %0, =voliate_start\n"
 42          : "=r" (source)
 43      );
 44 
 45 
 46     return source;
 47 
 48 }
 49 
 50 __asm__(
 51 
 52 "voliate_start:\n"
 53     //跳转要分三部:
 54     //1:将PC保存到新模式下的lr中;
 55     //2:将CPSR保存在SPSR中
 56     //3:初始化SP
 57     //前两步由硬件完成,而第三部需要手动完成
 58      "sub lr, lr, #4\n"
 59      "mov sp, #0x66000000\n"//初始化SP
 60      "stmfd sp!, {r0-r12, lr}\n"//初始化sp,入栈保护寄存器 
 61     //打印一句话 
 62      "ldr r0, =data_string\n"
 63      "ldr r2, show\n"
 64      "blx r2\n"
 65     //跳回来分两部
 66     //1:将CPSR保存在SPSR中
 67     //2:将PC保存到新模式下的lr中;
 68      "mov sp, #0x66000000\n"//
 69      "ldmea sp, {r0-r12, pc}^\n"// 
 70 
 71     "show:\n"
 72      ".word 0xc3e114d8\n"
 73 
 74      "data_string:\n"
 75      ".asciz \"hello DATA_ABORT!\\n\" \n"
 76 
 77         );
 78 
 79 void init_ttb(unsigned long *addr)
 80 {
 81     unsigned long va = 0;//定义虚拟地址
 82     unsigned long pa = 0;//定义物理地址
 83 
 84     //40000000-------80000000   ====  40000000------80000000
 85     for(va=0x40000000; va<=0x80000000; va+=0x100000){
 86         pa = va;
 87         addr[va >> 20] = pa | 2;
 88         //|2的目的是将0-2位置为10此时将是小页模式4K
 89     }
 90 
 91     //00000000-------10000000   ====  60000000------70000000
 92     for(va=0x00000000; va<=0x10000000; va+=0x100000){
 93         pa = va+0x60000000;
94         addr[va >> 20] = pa | 2;
 95     }
 96 
 97     //10000000-------14000000   ====  10000000------14000000
 98     for(va=0x10000000; va<=0x30000000; va+=0x100000){
 99         pa = va;
100         addr[va >> 20] = pa | 2;
101     }
102 
103     //30000000-------40000000   ====  50000000------60000000
104     for(va=0x30000000; va<0x40000000; va+=0x100000){
105         pa = va + 0x20000000;
106         addr[va >> 20] = pa | 2;
107     }
108 }
109 
110 void enable_mmu(void)
111 
112 {
113     unsigned long addr = 0x70000000;
114     init_ttb(addr);
115     //step:初始化页表
116 
117     unsigned long mmu = 1 | (1 << 1) | (1 << 8);
118     //将MMU的第0,1,8位置1
119     __asm__ __volatile__(
120         "mov r0, #3\n"
121         "MCR p15, 0, r0, c3, c0, 0\n"//manager
122         "MCR p15, 0, %0, c2, c0, 0\n"//addr  
123         "MCR p15, 0, %1, c1, c0, 0\n"// enable mmu
124         :
125         : "r" (addr), "r" (mmu)
126         : "r0"
127     );
128     printf("MMU is enable!\n");
129 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-12-19
  • 2021-06-03
  • 2021-12-02
  • 2022-12-23
  • 2022-12-23
  • 2022-01-01
猜你喜欢
  • 2021-12-13
  • 2021-04-05
  • 2021-09-11
  • 2021-08-02
  • 2021-09-27
相关资源
相似解决方案