S3C2440的七种模式之——未定义模式(去掉bl print1 bug解决)
现在做第一个实验,模拟未定义模式。
未定义模式,是cpu遇到自己不能识别的指令时候做出的异常处理。
arm指令的机器码一定是按照某种规范要求的,不然你随意写一条指令,cpu不是都可以执行吗?在cpu没有定义该条指令含义的情况下,我们执行了这样未定义的指令,就会进入未定义异常。
现在我们要模拟一个未定义异常,所以我们只要写出一个cpu无法识别的指令即可。
在这之前,要明白一个道理,在内存中执行的机器码,只有0,1两个值,不同的指令被分解为不同的0,1信号的机器码。
所以,我们在运行内存中存放一个32bit的值,这个值又恰恰是上图所不能表示的指令,那么这样,就可以测试未定义异常了。我们采用.word 关键字,.word expression就是在当前位置放一个word型的值,这个值就是expression 。
.word 接收4字节的数据,放在当前地址。
现在我们仔细观察上面的那个图,找到一个未定义的机器码,把这个值放在.word的地方,当cpu运行到.word 地址时,发现这个地址的0,1数据即机器码它不能识别,就发生未定义异常。
所以我们可以使用 .word 0xf3000000来表示一条未定义指令,但大家用的比较多的是.word 0xbadc0de(很形象,表示坏代码)。
现在更改star.S:
.text
.global _start _start:
b reset /* vector : reset */
ldr pc, und_addr /* vector : und */ und_addr:
.word do_und do_und:
/* 执行到这里之前:
* . lr_und保存有被中断模式中的下一条即将执行的指令的地址
* . SPSR_und保存有被中断模式的CPSR
* . CPSR中的M4-M0被设置为11011, 进入到und模式
* . 跳到0x4的地方执行程序
*/ /* sp_und未设置, 先设置它 */
ldr sp, =0x34000000 /* 在und异常处理函数中有可能会修改r0-r12, 所以先保存 */
/* lr是异常处理完后的返回地址, 也要保存 */
stmdb sp!, {r0-r12, lr} /* 保存现场 */
/* 处理und异常 */
mrs r0, cpsr
ldr r1, =und_string
bl printException /* 恢复现场 */
ldmia sp!, {r0-r12, pc}^ /* ^会把spsr的值恢复到cpsr里 */ und_string:
.string "undefined instruction exception" .align reset:
/* 关闭看门狗 */
ldr r0, =0x53000000
ldr r1, =
str r1, [r0] /* 设置MPLL, FCLK : HCLK : PCLK = 400m : 100m : 50m */
/* LOCKTIME(0x4C000000) = 0xFFFFFFFF */
ldr r0, =0x4C000000
ldr r1, =0xFFFFFFFF
str r1, [r0] /* CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = :: */
ldr r0, =0x4C000014
ldr r1, =0x5
str r1, [r0] /* 设置CPU工作于异步模式 */
mrc p15,,r0,c1,c0,
orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA
mcr p15,,r0,c1,c0, /* 设置MPLLCON(0x4C000004) = (<<)|(<<)|(<<)
* m = MDIV+ = +=
* p = PDIV+ = + =
* s = SDIV =
* FCLK = *m*Fin/(p*^s) = **/(*^)=400M
*/
ldr r0, =0x4C000004
ldr r1, =(<<)|(<<)|(<<)
str r1, [r0] /* 一旦设置PLL, 就会锁定lock time直到PLL输出稳定
* 然后CPU工作于新的频率FCLK
*/ /* 设置内存: sp 栈 */
/* 分辨是nor/nand启动
* 写0到0地址, 再读出来
* 如果得到0, 表示0地址上的内容被修改了, 它对应ram, 这就是nand启动
* 否则就是nor启动
*/
mov r1, #
ldr r0, [r1] /* 读出原来的值备份 */
str r1, [r1] /* ->[] */
ldr r2, [r1] /* r2=[] */
cmp r1, r2 /* r1==r2? 如果相等表示是NAND启动 */
ldr sp, =0x40000000+ /* 先假设是nor启动 */
moveq sp, # /* nand启动 */
streq r0, [r1] /* 恢复原来的值 */ bl sdram_init
//bl sdram_init2 /* 用到有初始值的数组, 不是位置无关码 */ /* 重定位text, rodata, data段整个程序 */
bl copy2sdram ldr pc, =sdram
sdram:
/* 清除BSS段 */
bl clean_bss bl uart0_init bl print1
/* 故意加入一条未定义指令 */
und_code:
.word 0xdeadc0de /* 未定义指令 */
bl print2 //bl main /* 使用BL命令相对跳转, 程序仍然在NOR/sram执行 */
ldr pc, =main /* 绝对跳转, 跳到SDRAM */ halt:
b halt
cpu处理异常的时候,是有专门地址的,这里的未定义und异常,在地址0x4处,当发生未定义异常时,硬件让程序从地址0x4处执行。这里说明一下汇编中定义字符串:
.string “XXXX” 表示定义的字符串包含最后的\0.
.ascii "XXXX"表示定义的字符串不包含最后的\0.
.asciiz "XXXX"表示定义的字符串包含最后的\0,z代表zero。
参考:(点击这里)
.align 4 放在.string 后面是为了使后面的指令四字节对齐,因为字符串的字节数不一定是四字节对齐的。
进入异常处理前需要保存现场,异常处理之后需要恢复现场。
现在说明下面代码段:
ldr pc, und_addr /* vector : und */ und_addr:
.word do_und
但是我在想,为什么韦老大说nand启动,怕访问超过4k空间,所以采取上面的操作方式,这样保证肯定无论是否超过4k,程序都可以正常运行。但是,我们的sdram已经重定位完毕了,那样sdram已经是可以访问的了,所以就算超过4k也不会有问题啊?(这个等到后面上文件系统的时候测试,我觉得这里是不存在老师说的那种情况的)。
Question:
去掉star.S中的 bl print1
发现不会进入未定义异常了?这是为什么?
经过分析,是puts函数问题,只有调用了puts函数,才会进入未定义异常。原因。。。
我们上面忽略了一点,就是cond所占用的四个字节条件,
所以,未定义指令要忽略高4位cond条件码。
在测试过程中,我能发现是puts函数的问题,可是,puts函数是我们重定义的库函数,这和stm32 printf映射串口有一点像,具体编译器在操作puts的时候做了什么不得而知,但是可以肯定的是puts让cpsr高四位变成了无条件执行,才触发了未定义异常。现在我们把未定义指令的高四位改成1110,后面加上arm不能识别的指令,就可以进入未定义异常模式了。
S3C2440的七种模式之——未定义模式(去掉bl print1 bug解决)的更多相关文章
- 情景剧:C/C++中的未定义行为(undefined behavior)
写在前面 本文尝试以情景剧的方式,轻松.直观地解释C/C++中未定义行为(undefined behavior)的概念.设计动机.优缺点等内容1,希望读者能够通过阅读本文,对undefined beh ...
- ARM微处理器的七种运行模式
ARM微处理器的七种运行模式: 用户模式(usr):正常的程序执行状态 快速中断模式(fiq):用于处理快速中断,对高速数据传输或通道处理. 中断模式(irq):对一般情况下的中断进行处理. 管理模式 ...
- (转)深度分析Linux下双网卡绑定七种模式
现在一般的企业都会 使用双网卡接入,这样既能添加网络带宽,同时又能做相应的冗余,可以说是好处多多.而一般企业都会使用linux操作系统下自带的网卡绑定模式,当然现在 网卡产商也会出一些针对window ...
- linux bond配置步骤,七种bond模式说明
一.网卡绑定: 第一步:创建一个ifcfg-bondX # vi /etc/sysconfig/network-scripts/ifcfg-bond0 DEVICE=bond0 BONDING_OPT ...
- 深度分析Linux下双网卡绑定七种模式 多网卡的7种bond模式原理
http://blog.csdn.net/abc_ii/article/details/9991845多网卡的7种bond模式原理 Linux网卡绑定mode共有七种(~) bond0.bond1.b ...
- 深度分析Linux下双网卡绑定七种模式
现在一般的企业都会使用双网卡接入,这样既能添加网络带宽,同时又能做相应的冗余,可以说是好处多多.而一般企业都会使用linux操作系统下自带的网卡绑定模式,当然现在网卡产商也会出一些针对windows操 ...
- 《JAVASCRIPT高级程序设计》创建对象的七种模式
细看javascript创建对象模式的诞生,具体的脉络为:不使用任何模式——工厂模式——构造函数模式——原型模式——组合使用构造函数模式——动态原型模式——寄生构造函数模式——稳妥构造函数模式.每一种 ...
- 七种bond模式说明
第一种模式:mod=0 ,即:(balance-rr) Round-robin policy(平衡抡循环策略) 特点:传输数据包顺序是依次传输(即:第1个包走eth0,下一个包就走eth1….一直循环 ...
- MySQL逻辑架构、SQL加载执行顺序、七种JOIN模式图解
逻辑架构 存储引擎 查看当前安装的mysql提供的存储引擎 查看当前mysql默认的存储引擎 MyISAM和InnoDB SQL加载执行顺序 sql书写顺序 mysql解析器执行的顺序 考点:m ...
随机推荐
- nRF2401A/nRF24L01/nRF24L01+无线模块最常见问题汇集(转)
俗话说:每个人一生下来什么都会的,都是通过自己努力和探索出来的,NRF系列芯片,刚开始都好奇心加兴趣才来捣鼓它的,刚开始做硬件和软件,没有收发数据弄得整个人头都快炸开了,所以在此和大家分享一下前辈的经 ...
- vim学习笔记(一)—— vim安装方法
一.完全卸载vim的方法 sudo apt-get remove --purge vim (--purge 是完全删除,会连配置文件一起删除) 二.Vim前言——————“世界上只有三种编辑器,EMA ...
- JAXBContext处理CDATA
今天做Lucene数据源接口时,遇到一个问题,就是输出xml时将某些数据放在CDATA区输出: 1.依赖的jar包,用maven管理项目的话, <dependency> <group ...
- SharePoint 2013 启用 以其他用户身份登陆(Sign in as different user)
习惯于SharePoint 2010的用户会发现,SharePoint 2013默认把 以其他用户身份登陆(Sign in as different user)的选项去掉了,这对于开发人员来说很麻烦 ...
- 手动脱WinUpack 壳实战
作者:Fly2015 吾爱破解培训第一课选修作业第6个练习演示样例程序.不得不反复那句话,没见过这样的壳,该壳是压缩壳的一种,相对于压缩壳,加密壳的难度要大一些.特别是IAT表的修复问题上. 首先分别 ...
- 浅谈cocos2dx(18) 中工厂模式
----我的生活.我的点点滴滴! ! cocos2d-x中也有工厂模式.何为工厂模式,顾名思义就是用来产生产品的,工厂就是用来创建其它类对象的类,我们把这个创建其它类对象的类叫做工厂类.而这些被创建的 ...
- Java 8 – Convert a Stream to LIST
Java 8 – Convert a Stream to LIST package com.mkyong.java8; import java.util.List;import java.util.s ...
- selenium 实现网页截图
使用webdriver提供的 save_screenshot 方法: from selenium import webdriver driver = webdriver.Chrome() driver ...
- MongoDB ReplacaSet & Sharding集群安装 配置 和 非集群情况的安装 配置 -摘自网络
单台机器做sharding --单机配置集群服务(Sharding) --shard1_1 mongod --install --serviceName MongoDBServerShard1 --s ...
- php分享十五:php的命令行操作
一:像命令行传参数方法: 1: 使用$argc $argv 用法: /usr/local/php/bin/php ./getopt.php 123 456 2:使用getopt函数() http:/ ...