中级会员
- 积分
- 217
- 金钱
- 217
- 注册时间
- 2016-7-20
- 在线时间
- 54 小时
|
我实际测试发现,将imx6ull工作模式切换为usr模式,并设置堆栈指针,程序无法正常运行,但是sys模式下就可以运行,这是什么原因?
代码如下:
.global _star, _vector_table
/*.word表示这里放了一个变量,_bss_start就是这个变量的标签,类似变量名 */
@ .global __bss_start
@ _bss_start:
@ .word __bss_start
@
@ .global __bss_end
@ _bss_end:
@ .word __bss_end
_start:
_vector_table:
/* 中断向量表 */
ldr pc, =Reset_Handler /* Reset */
ldr pc, =Undefined_Handler /* Undefined instructions */
ldr pc, =SVC_Handler /* Supervisor Call */
ldr pc, =PrefAbort_Handler /* Prefetch abort */
ldr pc, =DataAbort_Handler /* Data abort */
.word 0 /* RESERVED */
ldr pc, =IRQ_Handler /* IRQ interrupt */
ldr pc, =FIQ_Handler /* FIQ interrupt */
Reset_Handler:
cpsid i /* 关闭不确定中止、IRQ和FIQ */
/* Reset SCTlr Settings */
mrc p15, 0, r0, c1, c0, 0 /* Read CP15 System Control register */
bic r0, r0, #(0x1 << 12) /* Clear I bit 12 to disable I Cache */
bic r0, r0, #(0x1 << 2) /* Clear C bit 2 to disable D Cache */
bic r0, r0, #0x2 /* Clear A bit 1 to disable strict alignment */
bic r0, r0, #(0x1 << 11) /* Clear Z bit 11 to disable branch prediction */
bic r0, r0, #0x1 /* Clear M bit 0 to disable MMU */
mcr p15, 0, r0, c1, c0, 0 /* Write value back to CP15 System Control register */
cps #0x13 /* 设置处理器为SVC模式 */
ldr sp, =0x80200000 /* 设置SVC模式下堆栈的栈顶指针 */
cps #0x12 /* 设置处理器为IRQ模式 */
ldr sp, =0x80400000 /* 设置IRQ模式下堆栈的栈顶指针 */
cps #0x1f /* 设置处理器为SYS模式、可以运行 */
@cps #0x10 /* 设置处理器为usr模式、不可以运行 */
ldr sp, =0x80600000 /* 设置SYS模式下堆栈的栈顶指针 */
/* 设置中断向量表偏移地址 */
ldr r0, =_vector_table
mcr p15, 0, r0, c12, c0, 0 /* set VBAR, Vector Base Address Register*/
@ mrc p15, 0, r0, c12, c0, 0 //read VBAR
bl clean_bss /* 清除BSS段 */
cpsie i /* 开启IRQ */
b main
Undefined_Handler:
ldr r0, =Undefined_Handler
bl Undefined_Handler
SVC_Handler:
ldr r0, =SVC_Handler
bl SVC_Handler
PrefAbort_Handler:
ldr r0, =PrefAbort_Handler
bl PrefAbort_Handler
DataAbort_Handler:
ldr r0, =DataAbort_Handler
bl DataAbort_Handler
IRQ_Handler:
ldr r0, =IRQ_Handler
bl IRQ_Handler
FIQ_Handler:
ldr r0, =FIQ_Handler
bl FIQ_Handler
clean_bss:
/* 清除BSS段 */
ldr r0, =__bss_start /* 使用ldr伪指令将数据加载到寄存器时,需要在数据前加"="前缀 */
ldr r1, =__bss_end
mov r2, #0 /* 使用mov指令将数据加载到寄存器的时候,需要在数据前面添加"#"前缀 */
bss_loop:
stmia r0!, {r2} /* 将r2寄存器中的数据写入到r0,并对寄存器地址自增 */
cmp r0, r1 /* 比较r0和r1里面的值 */
ble bss_loop /* 当r0小于等于r1,继续清除bss段 */
mov pc, lr /* 跳回到原来的程序 */
.end
|
|