ARM中异常模式的跳转
时间:11-09
来源:互联网
点击:
例如在人的生活中,表情有喜怒哀乐.在ARM工作状态中,也有不同的模式如下表所示:
(详细内容请参考 ARM架构参考手册第二章41页)
对应的中文详细模式如下:
今天主要对ARM的 undefined模式来认识ARM中处理异常的机制,在ARM中,如果遇到异常情况,首先会找异常向量表,如下图(详细请参考ARM架构手册54页)
例如,有以下代码。在板子运行的时候就会发生异常。对应的,由于.word这是undifined异常,对应异常向量表,就会在04这个位子来寻求解决异常的办法.......
1 #include《stdio.h》2 3 int main()4 {5 6 __asm__ __volatile__(7 ".word 0x77\n"8 );9 10 11 12 }
异常
但是。。。。不巧的是在ARM中地址00到10地址是ROM,ROM是只可读,不可写的。所以,这就是MMU存在的意义之所在了,来一个“隔山打牛”把内存04这个地址映射到其他可以写入的地方,以后操作04这个地址就是在操作其他地址了。
顺便回顾上一次MMU的代码。详细请参考上一篇笔记
1 2 int (*printf)(char *, ...) = 0xc3e114d8;3 4 void init_ttb(unsigned long *addr);5 void enable_mmu(void);6 7 int main()8 {9 10 printf("hello mmu!\n");11 //3040 -> 500-60012 unsigned long *pp=0x51;13 *pp= 0x;14 printf("*pp is%x \n",*pp);15 16 enable_mmu();17 18 unsigned long *pv=0x31;19 printf("*pv is %x\n",*pv);20 }21 22 void init_ttb(unsigned long *addr)23 {24 unsigned long va = 0;//定义虚拟地址25 unsigned long pa = 0;//定义物理地址26 27 //40-80 ==== 408028 for(va=0x40; va<=0x80; va+=0x100){29 pa = va;30 addr[va >> 20] = pa 2;31 //2的目的是将0-2位置为10此时将是小页模式4K32 }33 34 //10-14 ==== 101435 for(va=0x10; va<=0x14; va+=0x100){36 pa = va;37 addr[va >> 20] = pa 2;38 }39 40 //30-40 ==== 506041 for(va=0x30; va<0x40; va+=0x100){42 pa = va + 0x20;43 addr[va >> 20] = pa 2;44 }45 }46 47 void enable_mmu(void)48 49 {50 unsigned long addr = 0x60;51 init_ttb(addr);52 //step:初始化页表53 54 unsigned long mmu = 1 (1 < 1) (1 < 8);55 //将MMU的第0,1,8位置156 __asm__ __volatile__(57 "mov r0, #3\n"58 "MCR p15, 0, r0, c3, c0, 0\n"//manager59 "MCR p15, 0, %0, c2, c0, 0\n"//addr 60 "MCR p15, 0, %1, c1, c0, 0\n"// enable mmu61 :62 : "r" (addr), "r" (mmu)63 : "r0"64 );65 printf("MMU is enable!\n");66 }67
在代码中,首先,在0x 31的地址中存入了数据0x11.然后,将0x30地址映射到了0x50的地址中,最后,打印0x51地址里的值,就是打印0x31的地址里的值。
以下是对于处理异常模式跳转的代码:
1 2 int (*printf)(char *, ...) = 0xc3e114d8;3 4 void init_ttb(unsigned long *addr);5 void enable_mmu(void);6 unsigned long volitale_init();7 void memcopy(unsigned long* dest,unsigned long* source,int len);8 9 int main()10 {11 //发生异常时会进入异常模式跳转到0 4地址处理异常事件 12 unsigned long source_addr=volitale_init();13 //异常事件处理函数14 printf("souce addr is %x\n",source_addr);15 //将异常处理地址的值放到0x6416 memcopy(0x64,source_addr,0x100);17 18 enable_mmu();19 //内存映射将0x04映射到0x6004 20 __asm__ __volatile__(21 ".word 0x77\n"22 );23 printf("welcome back! \n");24 25 26 }27 28 void memcopy(unsigned long* dest,unsigned long* source,int len)29 {30 int i=0;;31 for(i=0;i> 20] = pa 2;88 //2的目的是将0-2位置为10此时将是小页模式4K89 }90 91 //00-10 ==== 607092 for(va=0x00; va<=0x10; va+=0x100){93 pa = va+0x60;94 addr[va >> 20] = pa 2;95 }96 97 //10-14 ==== 101498 for(va=0x10; va<=0x14; va+=0x100){99 pa = va;100 addr[va >> 20] = pa 2;101 }102 103 //30-40 ==== 5060104 for(va=0x30; va<0x40; va+=0x100){105 pa = va + 0x20;106 addr[va >> 20] = pa 2;107 }108 }109 110 void enable_mmu(void)112 {113 unsigned long addr = 0x70;114 init_ttb(addr);115 //step:初始化页表116 117 unsigned long mmu = 1 (1 < 1) (1 < 8);118 //将MMU的第0,1,8位置1119 __asm__ __volatile__(120 "mov r0, #3\n"121 "MCR p15, 0, r0, c3, c0, 0\n"//manager122 "MCR p15, 0, %0, c2, c0, 0\n"//addr 123 "MCR p15, 0, %1, c1, c0, 0\n"// enable mmu124 :125 : "r" (addr), "r" (mmu)126 : "r0"127 );128 printf("MMU is enable!\n");129 }
ARM异常模式跳 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)