您的位置 首页 分销

ARM中反常形式的跳转

例如在人的生活中,表情有喜怒哀乐.在ARM工作状态中,也有不同的模式如下表所示:(详细内容请参考ARM架构参考手册第二章41页)…

例如在人的日子中,表情有喜怒哀乐.在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 }
View Code

在程序中,

volitale_init()函数的效果便是取得处理反常函数的地址,存到变量source中并回来.

voctor_start汇编函数首要便是完成了从SVR形式跳入到UND形式,在UND形式中打印了一句话

hello undefined而且跳出来在代码中,跳转形式首要有三步,而跳出形式也有两步,代码中没给出,便是/1:将CPSR保存在SPSR中2:将PC保存到新形式下的lr中;。

memcopy()函数的效果是:将source_addr里的数据复制到0x64地址,总共复制len个地址

实际上便是将处理反常函数的地址存到能够读写的地址。下次到0x04地址找处理函数的时分久直接调用到了处理反常函数。

接下来是enable_mmu()函数,用法与上一个相同。可是,此刻在制表函数init_ttb()中。新把

从00-10的地址映射到了60--70 地址

关于汇编部分,关于不太了解的不要紧,首要了解完成功用是什么。把握首要流程, 到最终再作

一致总结。

Makefile:

1 2 all:3     arm-none-linux-gnueabi-gcc -c mmu.c -o mmu.o4     arm-none-linux-gnueabi-ld -Ttext=0x41 mmu.o  -o mmu 5     arm-none-linux-gnueabi-objcopy  -Ielf32-littlearm -Obinary  mmu mmu.bin6 7 clean:8     rm -rf mmu mmu.o  mmu.bin9 10 11 
View Code

在PC终端make

在minicom板子上dnw到41地址go41

  

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/fenxiao/277063.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部