首页 > 其他 > 详细

s3c2440裸机-异常中断(三. swi软中断)

时间:2020-01-06 15:28:27      阅读:137      评论:0      收藏:0      [点我收藏+]

swi(软中断)

我们知道arm有7中工作模式,除了usr模式,其他6种都是特权模式。我们知道usr模式无法修改CPSR直接进入其他特权模式,但linux应用程序一般运行在usr模式,既然usr模式权限非常低,是无法直接访问硬件寄存器的,那么它是如何访问硬件的呢?

linux应用程序是通过系统调用,从而进入内核态,运行驱动程序来访问的硬件,那么系统调用又是如何实现的呢,就是通过软中断swi指令来进入svc模式,进入到svc模式后当然就能访问硬件啦。

所以我们的应用程序在usr模式想访问硬件,必须切换模式,怎么切换?

有以下两种方式:

1.发生异常或中断(被动的)

2.swi + 某个值(主动的)

现在介绍如何进入软中断swi

我们知道cpu一上电会跳到0地址(reset复位)执行代码,此时CPU处于svc模式,2440异常向量表如下图所示:

技术分享图片

  1. 为了验证usr模式能够主动的通过swi软中断指令来进入svc模式, 我们先将模式切换到usr模式,那么这个时候就不能访问硬件了,也不能直接修改cpsr直接进入其他模式。

    技术分享图片

    技术分享图片

    从上图我们设置CPSR让M4-M0处在10000,这样就进入了usr模式, 然后我们修改。修改start.s如下:

     .global _start
    
     _start:
         b reset
         b do_und   /*未定义指令异常向量*/
         b do_swi   /*软中断向量*/
    
     reset:
         /*
         看门狗
         时钟
         set SP
         sdram_init
         重定位
         bl uart0_init
         */
    
    
         /*先进入usr模式*/
         mrs r0, cpsr      /* 读出cpsr 读到r0 */
         /*使用bic命令 bitclean 把低4位清零*/
         bic r0, r0, #0xf  /* 修改M4-M0为0b10000, 进入usr模式 */
         msr cpsr, r0     /* 写入cpsr */
    
         /* 设置usr模式下的栈sp_usr */
         ldr sp, =0x33f00000
         swi 0x123  /* 执行此命令, 触发SWI异常, 进入0x8执行 */
         ldr pc, =main  /* 绝对跳转, 跳到SDRAM */
    
     halt:
         b halt

那么当执行到swi 0x123,就会触发SWI异常, 进入0x8的向量去执行,调用do_swi,我们参考上一节do_und实现我们的软中断服务程序do_swi。

do_swi:
/* 执行到这里之前:
 * 1. lr_svc保存有被中断模式中的下一条即将执行的指令的地址
 * 2. SPSR_svc保存有被中断模式的CPSR
 * 3. CPSR中的M4-M0被设置为10011, 进入到svc模式
 * 4. 跳到0x08的地方执行程序 
 */

/* sp_svc未设置, 先设置它 */
ldr sp, =0x33e00000

/* 保存现场 */
/* 在swi异常处理函数中有可能会修改r0-r12, 所以先保存 */
/* lr是异常处理完后的返回地址, 也要保存 */
stmdb sp!, {r0-r12, lr}  

/* 处理swi异常 */
mrs r0, cpsr
ldr r1, =swi_string /*这里r0, r1只是为了给printException传参*/
bl printException

/* 恢复现场 */
ldmia sp!, {r0-r12, pc}^  /* ^会把spsr的值恢复到cpsr里 */

swi_string:
    .string "swi exception"

完整的代码如下:

展开代码


    .global _start
    _start:
        b reset
        b do_und   /*未定义指令异常向量*/
        b do_swi   /*软中断向量*/

    do_swi:
    /* 执行到这里之前:
     * 1. lr_svc保存有被中断模式中的下一条即将执行的指令的地址
     * 2. SPSR_svc保存有被中断模式的CPSR
     * 3. CPSR中的M4-M0被设置为10011, 进入到svc模式
     * 4. 跳到0x08的地方执行程序 
     */

    /* sp_svc未设置, 先设置它 */
    ldr sp, =0x33e00000

    /* 保存现场 */
    /* 在swi异常处理函数中有可能会修改r0-r12, 所以先保存 */
    /* lr是异常处理完后的返回地址, 也要保存 */
    stmdb sp!, {r0-r12, lr}  
    
    /* 处理swi异常 */
    mrs r0, cpsr
    ldr r1, =swi_string /*这里r0, r1只是为了给printException传参*/
    bl printException
    
    /* 恢复现场 */
    ldmia sp!, {r0-r12, pc}^  /* ^会把spsr的值恢复到cpsr里 */
    
    swi_string:
        .string "swi exception"

    .align 4

    reset:
        /*
        看门狗
        时钟
        set SP
        sdram_init
        重定位
        bl uart0_init
        */

        /*先进入usr模式*/
        mrs r0, cpsr      /* 读出cpsr 读到r0 */
        /*使用bic命令 bitclean 把低4位清零*/
        bic r0, r0, #0xf  /* 修改M4-M0为0b10000, 进入usr模式 */
        msr cpsr, r0     /* 写入cpsr */
        
        /* 设置usr模式下的栈sp_usr */
        ldr sp, =0x33f00000
        swi 0x123  /* 执行此命令, 触发SWI异常, 进入0x8执行 */
        ldr pc, =main  /* 绝对跳转, 跳到SDRAM */

    halt:
        b halt

测试结果如下:

  1. 我们现在不断增加的程序代码量,那么有可能在 ‘ldr pc, =main‘ 这条指令执行之前程序就已经超过4k。那么我们当从nand启动的时候,还没执行到ldr pc, =main这句来,就无法取指令执行了。 所以我们干脆重定位完代码后就直接跳转到sdram上去执行,代码裁剪如下:

     ...
     reset:
         /*
         看门狗
         时钟
         set SP
         sdram_init
         重定位


    ldr pc, =sdram
    sdram:
    bl uart0_init

    */

         /*先进入usr模式*/
         mrs r0, cpsr      /* 读出cpsr 读到r0 */
         /*使用bic命令 bitclean 把低4位清零*/
         bic r0, r0, #0xf  /* 修改M4-M0为0b10000, 进入usr模式 */
         msr cpsr, r0     /* 写入cpsr */
    
         /* 设置usr模式下的栈sp_usr */
         ldr sp, =0x33f00000
         swi 0x123  /* 执行此命令, 触发SWI异常, 进入0x8执行 */
         ldr pc, =main  /* 绝对跳转, 跳到SDRAM */
    
     halt:
         b halt
  2. 会较大在start.s中的后面放一条swi 0x123,当执行到这条语句这样就会触发swi异常,跳转到swi异常向量0x8地址去执行,然后就会跳转到swi的中断服务程序do_swi。这里

s3c2440裸机-异常中断(三. swi软中断)

原文:https://www.cnblogs.com/fuzidage/p/12155982.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!