我知道ARM926ej-s正在使用完全降序堆栈。现在我有了这个启动代码,其中我使用/**/
在与此问题相关的行上进行了搜索。
.global __start
.global arm926ejs_reset
.global dcache_flush
.global __gnu_bssstart
.global __gnu_bssend
.global __image_size
.EQU MODE_USR, 0x010
.EQU MODE_FIQ, 0x011
.EQU MODE_IRQ, 0x012
.EQU MODE_SVC, 0x013
.EQU MODE_SVC_NI, 0x0D3
.EQU MODE_ABORT, 0x017
.EQU MODE_UNDEF, 0x01b
.EQU MODE_SYSTEM, 0x01f
.EQU MODE_BITS, 0x01f
.EQU I_MASK, 0x080
.EQU F_MASK, 0x040
.EQU IF_MASK, 0x0C0
.EQU BROM_MMU_BASE_ADDR, 0x1201C000
.EQU MMU_DISABLE_MASK, 0xFFFFEFFA
.EQU MMU_ENABLE_MASK, 0x00001005
.EQU FIQ_STACK_SIZE, 128
.EQU IRQ_STACK_SIZE, 256
.EQU ABORT_STACK_SIZE, 32
.EQU UNDEF_STACK_SIZE, 32
.EQU SYSTEM_STACK_SIZE, 64
.text
.code 32
.align 2
__start:
arm926ejs_reset:
B arm926ejs_reset_handler /*reset vector*/
.word 0x41676d69
.word 0,0,0,0,0
image_type:
.word 0x0000000A
sizeOfPermanentCode:
.word (__image_size)
.word 0,0
bootparameter:
.word 0
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
arm926ejs_reset_handler:
MOV r0, #MODE_SVC_NI
MSR cpsr_cxsf, r0
MRC p15, 0, r1, c1, c0, 0
LDR r2,=MMU_DISABLE_MASK
AND r1, r1, r2
MCR p15, 0, r1, c1, c0, 0
MOV r1,#0
MCR p15, 0, r1, c8, c7, 0
MCR p15, 0, r1, c7, c7, 0
MRC p15, 0, r1, c1, c0, 0
LDR r2,=0x1000
ORR r1, r1, r2
MCR p15, 0, r1, c1, c0, 0
MVN r1, #0
MCR p15, 0, r1, c3, c0, 0
LDR r3, =BROM_MMU_BASE_ADDR
MCR p15, 0, r3, c2, c0, 0
LDR r5, =inVirtMem
MRC p15, 0, r1, c1, c0, 0
LDR r2,=MMU_ENABLE_MASK
ORR r1, r1, r2
MCR p15, 0, r1, c1, c0, 0
MOV pc, r5
NOP
NOP
NOP
inVirtMem:
ADR r3, arm926ejs_reset /*we store the reset vector address*/
SUB r3, r3, #4 /*why do we then substract 4 bytes?*/
MOV r1, #IF_MASK
ORR r0, r1, #MODE_FIQ /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #FIQ_STACK_SIZE
ORR r0, r1, #MODE_IRQ /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #IRQ_STACK_SIZE
ORR r0, r1, #MODE_ABORT /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #ABORT_STACK_SIZE
ORR r0, r1, #MODE_UNDEF /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #UNDEF_STACK_SIZE
ORR r0, r1, #MODE_SYSTEM /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
SUB r3, r3, #SYSTEM_STACK_SIZE
ORR r0, r1, #MODE_SVC /*sets stack for MCPU mode*/
MSR cpsr_cxsf, r0
MOV sp, r3
LDR r0, =__gnu_bssstart
LDR r1, =__gnu_bssend
MOV r2, #0
clearzi:
CMP r0, r1
BEQ clearzi_exit
STR r2, [r0]
ADD r0, r0, #4
B clearzi
clearzi_exit:
load_entry:
LDR pc, =c_entry
NOP
dcache_flush:
CMP r0, #0
BNE inval
flushonly:
MRC p15, 0, r15, c7, c10, 3
BNE flushonly
MOV pc, lr
inval:
MRC p15, 0, r15, c7, c14, 3
BNE inval
MOV pc, lr
.END
在上面的代码中,第一个注释显示了一个重置向量(一个分支指令B arm926ejs_reset_handler
),紧接着是一个标题和一些准备mcu的命令......
现在看一下我们将重置向量的地址存储到寄存器r3
中的下一个注释,然后在下一行中我们从该地址中减去4
个字节。
Q1:为什么我们这样做?此地址现在是否显示在.word 0x41676d69
?
在下一行中有多个simmilar块,每个块都为不同的mcpu模式设置堆栈。让我们看一下堆栈指针sp
加载寄存器r3
的第一个,然后从该地址中减去堆栈的大小以获得此mcpu模式的堆栈大小。
Q2:此堆栈是否会覆盖.word 0x41676d69
上的标头以及用于准备mcu的所有指令?重置向量B arm926ejs_reset_handler
是否保持不变?为什么我们owerwrite标头?我们不再需要了吗?
答案 0 :(得分:2)
现在看看下一个注释,我们将复位向量的地址存储到寄存器r3中,在下一行中我们从该地址中减去4个字节。
Q1:我们为什么要这样做?此地址现在是否显示在.word 0x41676d69的位置?
通常代码增量。所以值.word 0x41676d69
在* arm926ejs_reset + 4 *之后。减去时,将降序堆栈的开头放在代码存储器之前。
Q2:此堆栈是否会覆盖.word 0x41676d69上的标头以及用于准备mcu的所有指令?复位向量B arm926ejs_reset_handler是否保持不变?为什么我们owerwrite标头?我们不再需要了吗?
不,它没有被覆盖。图像之前的内存用于堆栈。