<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM中異常模式的跳轉(zhuǎn)

          ARM中異常模式的跳轉(zhuǎn)

          作者: 時間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
          例如在人的生活中,表情有喜怒哀樂.在ARM工作狀態(tài)中,也有不同的模式如下表所示:

          (詳細(xì)內(nèi)容請參考 ARM架構(gòu)參考手冊第二章41頁)

          本文引用地址:http://www.ex-cimer.com/article/201611/317864.htm

                  對應(yīng)的中文詳細(xì)模式如下:

          今天主要對ARM的 undefined模式來認(rèn)識ARM中處理異常的機(jī)制,在ARM中,如果遇到異常情況,首先會找異常向量表,如下圖(詳細(xì)請參考ARM架構(gòu)手冊54頁)

          例如,有以下代碼。在板子運(yùn)行的時候就會發(fā)生異常。對應(yīng)的,由于.word這是undifined異常,對應(yīng)異常向量表,就會在04這個位子來尋求解決異常的辦法.......

          1    #include《stdio.h》2 3 int main()4   {5     6       __asm__ __volatile__(7           ".word 0x77n"8       );9   10     11 12   }
          異常

          但是。。。。不巧的是在ARM中地址00到10地址是ROM,ROM是只可讀,不可寫的。所以,這就是MMU存在的意義之所在了,來一個“隔山打牛”把內(nèi)存04這個地址映射到其他可以寫入的地方,以后操作04這個地址就是在操作其他地址了。

          順便回顧上一次MMU的代碼。詳細(xì)請參考上一篇筆記

          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 %xn",*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, #3n"58         "MCR p15, 0, r0, c3, c0, 0n"http://manager59         "MCR p15, 0, %0, c2, c0, 0n"http://addr  60         "MCR p15, 0, %1, c1, c0, 0n"http:// enable mmu61         :62         : "r" (addr), "r" (mmu)63         : "r0"64     );65     printf("MMU is enable!n");66 }67 

          在代碼中,首先,在0x 31的地址中存入了數(shù)據(jù)0x11.然后,將0x30地址映射到了0x50的地址中,最后,打印0x51地址里的值,就是打印0x31的地址里的值。

          以下是對于處理異常模式跳轉(zhuǎn)的代碼:

          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     //發(fā)生異常時會進(jìn)入異常模式跳轉(zhuǎn)到0 4地址處理異常事件   12     unsigned long source_addr=volitale_init();13     //異常事件處理函數(shù)14     printf("souce addr is %xn",source_addr);15     //將異常處理地址的值放到0x6416     memcopy(0x64,source_addr,0x100);17 18     enable_mmu();19     //內(nèi)存映射將0x04映射到0x6004    20     __asm__ __volatile__(21          ".word 0x77n"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, #3n"121         "MCR p15, 0, r0, c3, c0, 0n"http://manager122         "MCR p15, 0, %0, c2, c0, 0n"http://addr  123         "MCR p15, 0, %1, c1, c0, 0n"http:// enable mmu124         :125         : "r" (addr), "r" (mmu)126         : "r0"127     );128     printf("MMU is enable!n");129 }
          View Code

          在程序中,

          volitale_init()函數(shù)的作用就是獲得處理異常函數(shù)的地址,存到變量source中并返回.

          voctor_start匯編函數(shù)主要就是實(shí)現(xiàn)了從SVR模式跳入到UND模式,在UND模式中打印了一句話

          hello undefined并且跳出來在代碼中,跳轉(zhuǎn)模式主要有三步,而跳出模式也有兩步,代碼中沒給出,就是/1:將CPSR保存在SPSR中2:將PC保存到新模式下的lr中;。

          memcopy()函數(shù)的作用是:將source_addr里的數(shù)據(jù)拷貝到0x64地址,一共拷貝len個地址

          實(shí)際上就是將處理異常函數(shù)的地址存到可以讀寫的地址。下次到0x04地址找處理函數(shù)的時候久直接調(diào)用到了處理異常函數(shù)。

          接下來是enable_mmu()函數(shù),用法與上一個一樣。但是,此時在制表函數(shù)init_ttb()中。新把

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

          對于匯編部分,對于不太了解的沒關(guān)系,主要了解實(shí)現(xiàn)功能是什么。掌握主要流程, 到最后再作

          統(tǒng)一總結(jié)。

          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

            



          關(guān)鍵詞: ARM異常模式跳

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();