新手上路
- 积分
- 44
- 金钱
- 44
- 注册时间
- 2023-11-15
- 在线时间
- 8 小时
|
楼主 |
发表于 2023-11-24 17:00:52
|
显示全部楼层
- .global _start
- _start:
- ldr pc, =Reset_Handler /*复位中断服务函数 */
- ldr pc, =Undefined_Handler /* 未定义指令中断 */
- ldr pc, =SVC_Handler /* SVC(Supervisor)中断 */
- ldr pc, =PrefAbort_Handler /* 预取终止中断 */
- ldr pc, =DataAbort_Handler /* 数据终止中断 */
- ldr pc, =NotUsed_Handler /* 未使用中断 */
- ldr pc, =IRQ_Handler /* IRQ 中断 */
- ldr pc, =FIQ_Handler /* FIQ 中断 */
- /*复位中断服务函数 */
- Reset_Handler:
- cpsid i /*关闭 IRQ中断 */
- /*1.关闭I,D Cache 和 MMU,修改SCTLR寄存器,采用读 改 写的方式*/
- mrc p15, 0, r0, c1, c0, 0 /*读取SCTLR寄存器数据到r0寄存器里 */
- bic r0, r0, #(1 << 12) /* 清除 C1 的 I 位,关闭 I Cache */
- bic r0, r0, #(1 << 11) /* 清除 C1 的 Z 位,关闭分支预测 */
- bic r0, r0, #(1 << 2) /* 清除 C1 的 C 位,关闭 D Cache */
- bic r0, r0, #(1 << 1) /* 清除 C1 的 A 位,关闭对齐检查 */
- bic r0, r0, #(1 << 0) /* 清除 C1 的 M 位,关闭 MMU */
- mcr p15, 0, r0, c1, c0, 0 /*将r0寄存器写入SCTLR寄存器里 */
- #if 0
- /*设置中断向量偏移 */
- ldr r0, =0x87800000
- dsb
- isb
- mcr p15, 0, r0, c12, c0, 0 /*设置VBAR寄存器=0x87800000 */
- dsb
- isb
- #endif
- .global _bss_start
- _bss_start:
- .word __bss_start
- .global _bss_end
- _bss_end:
- .word __bss_end
- /* clean bss */
- ldr r0, _bss_start
- ldr r1, _bss_end
- mov r2, #0
- bss_loop:
- stmia r0!, {r2} /*r0*/
- cmp r0, r1
- ble bss_loop
- /*设置各个模式下的SP指针 */
- mrs r0, cpsr
- bic r0, r0, #0x1f
- orr r0, r0, #0x12 /*IRQ模式 */
- msr cpsr, r0
- ldr sp, =0x8060000 /*设置改模式下的sp */
- /* 进入 SYS 模式 */
- mrs r0, cpsr
- bic r0, r0, #0x1f
- orr r0, r0, #0x1f /*SYS模式 */
- msr cpsr, r0
- ldr sp, =0x80400000
-
- /* 进入 SVC 模式 */
- mrs r0, cpsr
- bic r0, r0, #0x1f
- orr r0, r0, #0x13 /*SVC模式 */
- msr cpsr, r0
- ldr sp, =0x80200000
- cpsie i /*使能IRQ中断 */
- b main
-
- /* 未定义指令中断服务函数 */
- Undefined_Handler:
- ldr r0, =Undefined_Handler
- bx r0
- /* SVC(Supervisor)中断服务函数 */
- SVC_Handler:
- ldr r0, =SVC_Handler
- bx r0
- /* 预取终止中断服务函数 */
- PrefAbort_Handler:
- ldr r0, =PrefAbort_Handler
- bx r0
- /* 数据终止中断服务函数 */
- DataAbort_Handler:
- ldr r0, =DataAbort_Handler
- bx r0
- /* 未使用中断服务函数 */
- NotUsed_Handler:
- ldr r0, =NotUsed_Handler
- bx r0
- /* IRQ 中断服务函数 */
- IRQ_Handler:
- push {lr} /* 保存 lr 地址 */
- push {r0-r3, r12} /* 保存 r0-r3, r12 寄存器 触发中断会保存一些,剩下需要自己手动保存*/
- mrs r0, spsr /* 读取 spsr 寄存器 */
- push {r0} /* 保存 spsr 寄存器 */
- mrc p15, 4, r1, c15, c0, 0 /* 将 CP15 的 C0 CBAR寄存器内的值到 R1 寄存器中 ,GIC物理首地址
- * 参考文档 ARM Cortex-A(armV7)编程手册 V4.0.pdf P49
- * Cortex-A7 Technical ReferenceManua.pdf P68 P138
- */
- add r1, r1, #0X2000 /* GIC 基地址加 0X2000, 得到 CPU 接口端基地址 */
- ldr r0, [r1, #0XC] /* CPU 接口端基地址加 0X0C 就是 GICC_IAR 寄存器,
- * GICC_IAR 保存着当前发生中断的中断号,我们要根据
- * 这个中断号来绝对调用哪个中断服务函数
- */
- push {r0, r1} /* 保存 r0,r1 */
- cps #0x13 /* 进入 SVC 模式,允许其他中断再次进去 */
- push {lr} /* 保存 SVC 模式的 lr 寄存器 */
- ldr r2, =system_irqhandler /* 加载 C 语言中断处理函数到 r2 寄存器中*/
- blx r2 /* 运行 C 语言中断处理函数,带有一个参数 */
-
- pop {lr} /* 执行完 C 语言中断服务函数, lr 出栈 */
- cps #0x12 /* 进入 IRQ 模式 */
- pop {r0, r1}
- str r0, [r1, #0X10] /* 中断执行完成,写 EOIR */
- pop {r0}
- msr spsr_cxsf, r0 /* 恢复 spsr */
-
- pop {r0-r3, r12} /* r0-r3,r12 出栈 */
- pop {lr} /* lr 出栈 */
- subs pc, lr, #4 /* 将 lr-4 赋给 pc 执行 译码 取码 pc在取码,返回后该执行的是已译码的代码 即pc-4*/
- /* FIQ 中断服务函数 */
- FIQ_Handler:
- ldr r0, =FIQ_Handler
- bx r0
复制代码
使用这个start.S就不行,使用文档里面的就可以,这个和文档里的是有什么不同吗 |
|