• Tiny4412中断介绍


      通过几天裸板驱动开发,今天对ARM的中断做一些简单总结,前面我们已经了解了ARM的7种异常模式,中断是异常模式的一种,在ARM中异常事件发生将会触发中断,但是,所有的中断都不能直接访问cpu,而是都统一由GIC(中断管理器)来管理;下面是samsung提供的模式图:

    其中GIC管理的中断有分为:

     

      (1)SGI:一个cpu中断另一个cpu(cpu0 ->cpu1)

      (2)PPI:一个中断只能中断一个cpu

      (3)SPI:一个中断可以中断多个cpu

      处理一个中断大致需要三步:

      (1)cpu permit interrupt (cpu允许中断)

      (2)GIC enable (启用GIC)

      (3)SET Interrupt source (设置中断源)

      下面是用SGI实现的一个程序:

      头文件:

     1 #ifndef __BUNFLY_H
     2 #define __BUNFLY_H
     3 
     4 #define ICCICR_CPU0    (*(volatile unsigned long *)0x10480000)
     5 #define ICCPMR_CPU0    (*(volatile unsigned long *)0x10480004)
     6 #define ICDDCR        (*(volatile unsigned long *)0x10490000)
     7 #define ICDIPR2_CPU0    (*(volatile unsigned long *)0x10490408)
     8 #define ICDIPTR2_CPU0    (*(volatile unsigned long *)0x10490808)
     9 #define ICDISER0_CPU0    (*(volatile unsigned long *)0x10490100)
    10 #define ICDSGIR        (*(volatile unsigned long *)0x10490f00)
    11 #define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010)
    12 #define ICCIAR_CPU0  (*(volatile unsigned long *)0x1048000c)
    13 
    14 #endif    //__BUNFLY_H
      1 #include "bunfly.h"
      2 
      3 int (*printf)(char *, ...) = 0xc3e114d8;
      4 void enable_mmu();
      5 void init_table(unsigned long *addr);
      6 void memcpy(unsigned char *dest, unsigned char *src, int len);
      7 extern unsigned long  vector_start;
      8 void do_irq();
      9 
     10 int main()
     11 {    
     12     memcpy(0x70000000, vector_start, 0x1000);    
     13     enable_mmu();
     14 
     15     *(unsigned long *)0x47000000 = do_irq;
     16 
     17     //step 1: set cpu permit interrupt
     18     __asm__ __volatile__(
     19         "mrs r0, cpsr
    "
     20         "bic r0,r0, #0x80
    "
     21         "msr cpsr, r0
    "
     22         :::"r0"
     23     );
     24 
     25     //step 2: set GIC (cgi) enable
     26     ICCICR_CPU0 = 1;//cpu接口控制寄存器(总开关)
     27     ICCPMR_CPU0 =0xff;//中断总优先级(门槛)
     28     ICDDCR = 1;//本中断开关
     29     ICDIPR2_CPU0 = (3 << 9);//本中断优先级
     30     ICDIPTR2_CPU0 = (1 << 9);//目标cpu
     31     ICDISER0_CPU0 = (1 << 9);//启用本中断
     32     
     33     //step 3: set interrupt source
     34     ICDSGIR = 9 | (1 << 16);
     35         
     36     printf("welcom back
    ");
     37 }
     38 
     39 void do_irq()
     40 {
     41     unsigned long ack_id = 0;
     42     unsigned long cpu_id = 0;
     43     unsigned long data = ICCIAR_CPU0;
     44 
     45     /*clean interrupt*/
     46     ack_id = data & 0x3ff;
     47     cpu_id = data & (0x7 << 10);
     48     ICCEOIR_CPU0 = ack_id | cpu_id;
     49 
     50     printf("this is interrupt
    ");
     51     printf("cup_id is %d
    ", cpu_id >> 10);
     52     printf("ack_id is %d
    ", ack_id);
     53 
     54 }
     55 
     56 void memcpy(unsigned char *dest, unsigned char *src, int len)
     57 {
     58     int i = 0;
     59     for(i = 0; i < len; i++) {
     60         dest[i] = src[i];
     61     }
     62 }
     63 
     64 void enable_mmu()
     65 {
     66     /*构建表*/
     67     unsigned long addr = 0x50000000;
     68     init_table(addr);
     69     /*打开mmu*/
     70     unsigned long mmu = 0;
     71     mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);
     72     __asm__ __volatile__ (
     73         "mov r0, #3
    "
     74         "MCR p15, 0, r0, c3, c0, 0
    "//设置为管理员
     75         "MCR p15, 0, %0, c2, c0, 0
    "//设置表的地址
     76         "MCR p15, 0, %1, c1, c0, 0
    "//开启mmu
     77         :    
     78         :    "r" (addr), "r" (mmu)
     79         :
     80     );
     81 
     82 }
     83 
     84 __asm__(
     85 
     86 "vector: 
    "
     87 "    b reset
    "
     88 "    b und
    "
     89 "    b swi
    "
     90 "    b pre_abt
    "
     91 "    b data_abt
    "
     92 "    .word 0x0
    "
     93 "    b irq
    "
     94 "    b fiq
    "
     95 "reset:
    "
     96 "und:
    "
     97 "    mov sp, #0x47000000
    "
     98 "    stmdb sp!, {r0-r12, lr}
    "
     99 
    100 "    ldr r3, =0x47000004
    "
    101 "    ldr r2, [r3]
    "
    102 "    blx r2
    "
    103 
    104 "    mov sp, #0x47000000
    "
    105 "    ldmdb sp, {r0-r12, pc}^    
    "
    106 
    107 "swi:
    "
    108 "    mov sp, #0x47000000
    "
    109 "    stmdb sp!, {r0-r12, lr}^
    "
    110 
    111 "    mov sp, #0x47000000
    "
    112 "    ldmdb sp, {r0-r12, pc}^    
    "
    113 
    114 "pre_abt:
    "
    115 
    116 "data_abt:
    "
    117 "    mov sp, #0x47000000
    "
    118 "    sub lr, lr, #4
    "
    119 "    stmdb sp!, {r0-r12, lr}
    "
    120 
    121 "    ldr r3, =0x47000008
    "
    122 "    ldr r2, [r3]
    "
    123 "    blx r2
    "
    124 
    125 "    mov sp, #0x47000000
    "
    126 "    ldmdb sp, {r0-r12, pc}^    
    "
    127 "irq:
    "
    128 
    129 "    mov sp, #0x47000000
    "
    130 "    sub lr, lr, #4
    "
    131 "    stmdb sp!, {r0-r12, lr}
    "
    132 
    133 "    ldr r3, =0x47000000
    "
    134 "    ldr r2, [r3]
    "
    135 "    blx r2
    "
    136 
    137 "    mov sp, #0x47000000
    "
    138 "    ldmdb sp, {r0-r12, pc}^    
    "
    139 
    140 "fiq:
    "
    141 
    142     ".global vector_start
    "
    143 "vector_start: 
    "
    144     ".word vector 
     "
    145 
    146 );
    147 
    148 void init_table(unsigned long *addr)
    149 {
    150     unsigned long va = 0;
    151     unsigned long phys = 0;
    152 
    153     //0x40000000-0x80000000 -> 0x40000000-0x80000000    
    154     for(va = 0x40000000; va < 0x80000000; va += 0x100000) {
    155         phys = va;
    156         addr[va >> 20] = phys | 2;
    157     }
    158 
    159     //0x10000000-0x14000000 -> 0x10000000-0x140000000    
    160     for(va = 0x10000000; va < 0x14000000; va += 0x100000) {
    161         phys = va;
    162         addr[va >> 20] = phys | 2;
    163     }
    164     //0x10000000-0x14000000 -> 0x10000000-0x140000000    
    165     for(va = 0x0; va < 0x10000000; va += 0x100000) {
    166         phys = va + 0x70000000;
    167         addr[va >> 20] = phys | 2;
    168     }
    169             
    170 }

     运行结果如下:

  • 相关阅读:
    【移动安全基础篇】——14、创建破解代码库
    【移动安全基础篇】——13、Android关键代码快速定位
    【移动安全基础篇】——12、Dalvik虚拟机
    【移动安全基础篇】——11、Android_jni
    【移动安全基础篇】——10、Android源代码修改
    【移动安全基础篇】——09、Android源代码目录结构
    【移动安全高级篇】————7、APK 的自我保护
    【移动安全高级篇】————6、Android DEX安全攻防战
    【移动安全高级篇】————5、Andorid APK反逆向解决方案---梆梆加固原理探寻
    Scene
  • 原文地址:https://www.cnblogs.com/wenqiang/p/4778349.html
Copyright © 2020-2023  润新知