用ADS写一个ARM启动代码遇到的问题
2008-05-10 00:41
567 查看
今天一天我一直被一个启动代码所捆饶着:在调用一个堆栈初始化函数以后,堆栈竟然出现错误配置,指向了那些不可用的地址,导致取数据异常。一开始我以为是不是我的分散加载文件写错误了,找遍了所有的资料,都可以确认我的分散加载文件是没有问题。
这个问题是这样的:
在安装完异常向量代码以后,我调用一个Stack_init函数来实现对堆栈进行初始化。如下
start
LDR PC,RESET_ADDR
....
RESET_ADDR DCD RESET_Handler
...
RESET_Handler
BL Stack_init ;初始化堆栈,为了更好模块化,Stack_init 在另外一个文件Stack.s中实现
....
;File : Stack.S
;Author : embs
;Date : 2008/05/08
;Version : 1.0
;------------------------------------------------------------
;This File is the bootloader code for arm7,when power up.use to
; Initalization the stack of all kinds of mode
;
; you must change the size of mode that maybe use for your project
; the size of stack must align to 32bit. if not,it will data abort
;-------------------------------------------------------------------
UND_STACK_SIZE EQU 0x00000004
ABT_STACK_SIZE EQU 0x00000004
FIQ_STACK_SIZE EQU 0x00000004
IRQ_STACK_SIZE EQU 0x00000100
SVC_STACK_SIZE EQU 0x00000020
MODE_USR EQU 0x10 ;/* User Mode */
MODE_FIQ EQU 0x11 ;/* FIQ Mode */
MODE_IRQ EQU 0x12 ;/* IRQ Mode */
MODE_SVC EQU 0x13 ;/* Supervisor Mode */
MODE_ABT EQU 0x17 ;/* Abort Mode */
MODE_UND EQU 0x1B ;/* Undefined Mode */
MODE_SYS EQU 0x1F ;/* System Mode */
FIQ_MASK EQU 0x40 ;mask of IFQ ,set disable
IRQ_MASK EQU 0x80 ;mask of IRQ ,set disable
EXPORT STACK_init
CODE32
AREA Start,CODE,READONLY
STACK_init
MOV R0,LR
LDR R1,=Stack_TOP
MSR CPSR_c,#MODE_UND|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#UND_STACK_SIZE
MSR CPSR_c,#MODE_ABT|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#ABT_STACK_SIZE
MSR CPSR_c,#MODE_FIQ|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#FIQ_STACK_SIZE
MSR CPSR_c,#MODE_IRQ|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#IRQ_STACK_SIZE
MSR CPSR_c,#MODE_SVC|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#SVC_STACK_SIZE
MSR CPSR_c,#MODE_SYS|FIQ_MASK|IRQ_MASK ;default start mode
MOV SP,R1
IF :LNOT:(:DEF:START_MODE)
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
MOV PC,R0
AREA StackS,DATA,NOINIT
Stack_TOP
END
该代码反汇编以后的代码如下:
STACK_init
$a
Start
0x00000000: e1a0000e .... MOV r0,r14
0x00000004: e59f1048 H... LDR r1,0x54 <<==问题就出在这里,按理它应该加载0x00000050地址的值才对,可现在加载的0x54地址处的值。这个可以很容易与源代码比较知道
0x00000008: e321f0db ..!. MSR CPSR_c,#0xdb
0x0000000c: e1a0d001 .... MOV r13,r1
0x00000010: e2411004 ..A. SUB r1,r1,#4
0x00000014: e321f0d7 ..!. MSR CPSR_c,#0xd7
0x00000018: e1a0d001 .... MOV r13,r1
0x0000001c: e2411004 ..A. SUB r1,r1,#4
0x00000020: e321f0d1 ..!. MSR CPSR_c,#0xd1
0x00000024: e1a0d001 .... MOV r13,r1
0x00000028: e2411004 ..A. SUB r1,r1,#4
0x0000002c: e321f0d2 ..!. MSR CPSR_c,#0xd2
0x00000030: e1a0d001 .... MOV r13,r1
0x00000034: e2411f40 @.A. SUB r1,r1,#0x100
0x00000038: e321f0d3 ..!. MSR CPSR_c,#0xd3
0x0000003c: e1a0d001 .... MOV r13,r1
0x00000040: e2411020 .A. SUB r1,r1,#0x20
0x00000044: e321f0df ..!. MSR CPSR_c,#0xdf
0x00000048: e1a0d001 .... MOV r13,r1
0x0000004c: e1a0f000 .... MOV pc,r0
$d
0x00000050: 00000000 .... DCD 0 <<应该加载的地方
找了一天,花费了很多时间,终于找到了罪魁祸首:
IF :LNOT:(:DEF:START_MODE)
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
非常粗心把IF逻辑判断写错了
应该修改为:
IF :DEF:START_MODE
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
现在这是修改后的反汇编代码,修改好以后,也就再也不出现取数据异常了。
STACK_init
$a
Start
0x00000000: e1a0000e .... MOV r0,r14
0x00000004: e59f1044 D... LDR r1,0x50 << 0x50
0x00000008: e321f0db ..!. MSR CPSR_c,#0xdb
0x0000000c: e1a0d001 .... MOV r13,r1
0x00000010: e2411004 ..A. SUB r1,r1,#4
0x00000014: e321f0d7 ..!. MSR CPSR_c,#0xd7
0x00000018: e1a0d001 .... MOV r13,r1
0x0000001c: e2411004 ..A. SUB r1,r1,#4
0x00000020: e321f0d1 ..!. MSR CPSR_c,#0xd1
0x00000024: e1a0d001 .... MOV r13,r1
0x00000028: e2411004 ..A. SUB r1,r1,#4
0x0000002c: e321f0d2 ..!. MSR CPSR_c,#0xd2
0x00000030: e1a0d001 .... MOV r13,r1
0x00000034: e2411f40 @.A. SUB r1,r1,#0x100
0x00000038: e321f0d3 ..!. MSR CPSR_c,#0xd3
0x0000003c: e1a0d001 .... MOV r13,r1
0x00000040: e2411020 .A. SUB r1,r1,#0x20
0x00000044: e321f0df ..!. MSR CPSR_c,#0xdf
0x00000048: e1a0d001 .... MOV r13,r1
0x0000004c: e1a0f000 .... MOV pc,r0
$d
0x00000050: 00000000 .... DCD 0 <<Stack_TOP就存储在这里
所以工作必须要细心,微小的东西往往可以给人致命的打击。以后要加强修炼才行。
这个问题是这样的:
在安装完异常向量代码以后,我调用一个Stack_init函数来实现对堆栈进行初始化。如下
start
LDR PC,RESET_ADDR
....
RESET_ADDR DCD RESET_Handler
...
RESET_Handler
BL Stack_init ;初始化堆栈,为了更好模块化,Stack_init 在另外一个文件Stack.s中实现
....
;File : Stack.S
;Author : embs
;Date : 2008/05/08
;Version : 1.0
;------------------------------------------------------------
;This File is the bootloader code for arm7,when power up.use to
; Initalization the stack of all kinds of mode
;
; you must change the size of mode that maybe use for your project
; the size of stack must align to 32bit. if not,it will data abort
;-------------------------------------------------------------------
UND_STACK_SIZE EQU 0x00000004
ABT_STACK_SIZE EQU 0x00000004
FIQ_STACK_SIZE EQU 0x00000004
IRQ_STACK_SIZE EQU 0x00000100
SVC_STACK_SIZE EQU 0x00000020
MODE_USR EQU 0x10 ;/* User Mode */
MODE_FIQ EQU 0x11 ;/* FIQ Mode */
MODE_IRQ EQU 0x12 ;/* IRQ Mode */
MODE_SVC EQU 0x13 ;/* Supervisor Mode */
MODE_ABT EQU 0x17 ;/* Abort Mode */
MODE_UND EQU 0x1B ;/* Undefined Mode */
MODE_SYS EQU 0x1F ;/* System Mode */
FIQ_MASK EQU 0x40 ;mask of IFQ ,set disable
IRQ_MASK EQU 0x80 ;mask of IRQ ,set disable
EXPORT STACK_init
CODE32
AREA Start,CODE,READONLY
STACK_init
MOV R0,LR
LDR R1,=Stack_TOP
MSR CPSR_c,#MODE_UND|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#UND_STACK_SIZE
MSR CPSR_c,#MODE_ABT|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#ABT_STACK_SIZE
MSR CPSR_c,#MODE_FIQ|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#FIQ_STACK_SIZE
MSR CPSR_c,#MODE_IRQ|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#IRQ_STACK_SIZE
MSR CPSR_c,#MODE_SVC|FIQ_MASK|IRQ_MASK
MOV SP,R1
SUB R1,R1,#SVC_STACK_SIZE
MSR CPSR_c,#MODE_SYS|FIQ_MASK|IRQ_MASK ;default start mode
MOV SP,R1
IF :LNOT:(:DEF:START_MODE)
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
MOV PC,R0
AREA StackS,DATA,NOINIT
Stack_TOP
END
该代码反汇编以后的代码如下:
STACK_init
$a
Start
0x00000000: e1a0000e .... MOV r0,r14
0x00000004: e59f1048 H... LDR r1,0x54 <<==问题就出在这里,按理它应该加载0x00000050地址的值才对,可现在加载的0x54地址处的值。这个可以很容易与源代码比较知道
0x00000008: e321f0db ..!. MSR CPSR_c,#0xdb
0x0000000c: e1a0d001 .... MOV r13,r1
0x00000010: e2411004 ..A. SUB r1,r1,#4
0x00000014: e321f0d7 ..!. MSR CPSR_c,#0xd7
0x00000018: e1a0d001 .... MOV r13,r1
0x0000001c: e2411004 ..A. SUB r1,r1,#4
0x00000020: e321f0d1 ..!. MSR CPSR_c,#0xd1
0x00000024: e1a0d001 .... MOV r13,r1
0x00000028: e2411004 ..A. SUB r1,r1,#4
0x0000002c: e321f0d2 ..!. MSR CPSR_c,#0xd2
0x00000030: e1a0d001 .... MOV r13,r1
0x00000034: e2411f40 @.A. SUB r1,r1,#0x100
0x00000038: e321f0d3 ..!. MSR CPSR_c,#0xd3
0x0000003c: e1a0d001 .... MOV r13,r1
0x00000040: e2411020 .A. SUB r1,r1,#0x20
0x00000044: e321f0df ..!. MSR CPSR_c,#0xdf
0x00000048: e1a0d001 .... MOV r13,r1
0x0000004c: e1a0f000 .... MOV pc,r0
$d
0x00000050: 00000000 .... DCD 0 <<应该加载的地方
找了一天,花费了很多时间,终于找到了罪魁祸首:
IF :LNOT:(:DEF:START_MODE)
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
非常粗心把IF逻辑判断写错了
应该修改为:
IF :DEF:START_MODE
MSR CPSR_c,#START_MODE|FIQ_MASK|IRQ_MASK
ENDIF
现在这是修改后的反汇编代码,修改好以后,也就再也不出现取数据异常了。
STACK_init
$a
Start
0x00000000: e1a0000e .... MOV r0,r14
0x00000004: e59f1044 D... LDR r1,0x50 << 0x50
0x00000008: e321f0db ..!. MSR CPSR_c,#0xdb
0x0000000c: e1a0d001 .... MOV r13,r1
0x00000010: e2411004 ..A. SUB r1,r1,#4
0x00000014: e321f0d7 ..!. MSR CPSR_c,#0xd7
0x00000018: e1a0d001 .... MOV r13,r1
0x0000001c: e2411004 ..A. SUB r1,r1,#4
0x00000020: e321f0d1 ..!. MSR CPSR_c,#0xd1
0x00000024: e1a0d001 .... MOV r13,r1
0x00000028: e2411004 ..A. SUB r1,r1,#4
0x0000002c: e321f0d2 ..!. MSR CPSR_c,#0xd2
0x00000030: e1a0d001 .... MOV r13,r1
0x00000034: e2411f40 @.A. SUB r1,r1,#0x100
0x00000038: e321f0d3 ..!. MSR CPSR_c,#0xd3
0x0000003c: e1a0d001 .... MOV r13,r1
0x00000040: e2411020 .A. SUB r1,r1,#0x20
0x00000044: e321f0df ..!. MSR CPSR_c,#0xdf
0x00000048: e1a0d001 .... MOV r13,r1
0x0000004c: e1a0f000 .... MOV pc,r0
$d
0x00000050: 00000000 .... DCD 0 <<Stack_TOP就存储在这里
所以工作必须要细心,微小的东西往往可以给人致命的打击。以后要加强修炼才行。
相关文章推荐
- 今天更新代码之后,突然出现一个问题:Tomcat启动时,总是会出现jvm fatal error错误导致tomcat无法正常启动,以下是错误信息:
- 移植代码到 DLL 时遇到的一个问题
- 今天遇到一个问题,将fedora磁盘扩展空间后,启动不成功
- SSH2项目启动报错(一个项目所遇到的问题,我就写一个了)
- 写C++代码遇到的一个问题,错误已经在代码中注释了
- 调试 ARM STM32 外部中断 遇到的一个问题
- 打开一个别人的代码遇到的问题
- 启动HBase后遇到的一个问题
- ARM启动代码及ADS基本使用
- 使用wildfly-10.1.0遇到一个问题:启动时提示“系统找不到指定的文件”
- 对调用了TypeMock.net的代码进行调试遇到的怪问题--在vs.net中启动resharper自带的unit test的过程和方式是什么样的?
- VMware启动时今天遇到一个很恶心的问题
- 今天代码遇到一个问题以及优化-2016年08月04日19:08:40
- 初学java,写的一个小程序遇到点问题,又碰上论坛关闭,在此上代码,希望能有人帮我看下,多谢
- 哪些年遇到过的Andriod问题(13)Mars的下载文件代码不知道是什么问题,在网上去新COPY了一个就可以下载了。
- 将一个工程中的代码复制进另一个新建的工程遇到如下问题,谨以此记。
- 一个maven项目启动遇到的问题
- XP启动不了,提示“Windows产品激活,一个问题阻止Windows正确检查此机器的许可证。错误代码:0x8007000”
- 启动HBase后遇到的一个问题
- 最近遇到了一个问题,搞了好几天还是没有什么起色!郁闷中啦!