startup_ch32v00x.S启动文件分析(上)
引言
CH32系列MCU是由南京沁恒(WCH)公司推出的一系列处理器芯片。引自官网:
CH32V、CH32X、CH32L系列MCU采用自研的青稞RISC-V内核,基于蓬勃发展的RISC-V开源指令集架构,针对低功耗和高速响应等应用优化扩展,免费配套IDE等开发工具软件,免除第三方内核技术的授权费和提成费,通过内置和组合USB、PD、低功耗蓝牙、以太网等专业接口外设,构建了既有全球未来生态又能自主可控、且极具长期竞争力的MCU产品线。
本文通过对 CH32V003 芯片所使用的启动文件 startup_ch32v00x.S 进行分析,梳理RISC-V芯片的启动过程。
文件内容预览
逐句分析
Part1 - Init
从代码第一行看起。
.section .init, "ax", @progbits
- .section 标明本句为对段的定义。
- .init是该段的名字。
- "ax"标识段的权限,a代表运行时载入内存,x代表可执行。
- @progbits标识了段的类型,表示“Section contains either initialized data and instructions or instructions only."。
.globl _start
定义_start位置全局可见,用于作程序的起始地址。
.align 2
定义下一条指令/数据对齐方式。可确保下一条指令的地址为“2的x次方”的倍数。此处,2的2次方为4,因此下一条指令的地址将顺推至4的倍数。
注意与.balign伪指令的区分,其用于将下一条指令地址顺推至x的倍数。即.align 2等效于.balign 4。
_start:
程序起始位置。
.option norvc;
rvc、norvc是RISC-V架构特有的选项:
- “.option rvc”伪操作表示接下来的汇编程序可以被汇编生成16位宽的压缩指令。
- “.option norvc”伪操作表示接下来的汇编程序不可以被汇编生成16位宽的压缩指令
j handle_reset
跳转至 handle_reset 处。
Part2 - Reset
从代码106行开始看起。
.section .text.handle_reset, "ax", @progbits
对段的定义,不再赘述。
handle_reset:
由上一部分跳转至此,随后顺序执行。
.option push
- “.option push”伪操作暂时将当前的选项设置保存起来,从而允许之后使用.option伪操作指定新的选项;而“.option pop”伪操作将最近保存的选项设置恢复出来重新生效。
- 通过“.option push”和“.option pop”的组合,便可以在汇编程序中在不影响全局选项设置的情况下,为其中嵌入的某一段代码特别地设置不同的选项。
.option norelax
la gp, __global_pointer$
将ld文件中的标签__global_pointer所处的地址值赋给gp寄存器
.option pop
恢复option。
启动部分
把启动部分一起,通过注释进行解释。该部分用到的各类预设地址,均来自于ld链接脚本文件Link.ld。
1: la sp, _eusrstack /* 将ld文件中的标签_eusrstack所处的地址值赋给sp寄存器 */ 2: /* Load data section from flash to RAM */ la a0, _data_lma /* Flash中的data段地址 */ la a1, _data_vma /* 物理RAM地址 */ la a2, _edata /* data段尾地址 */ bgeu a1, a2, 2f /* a1 greater/equal a2时,跳转到下一个2标签 */ 1: lw t0, (a0) sw t0, (a1) addi a0, a0, 4 addi a1, a1, 4 bltu a1, a2, 1b /* a1 less than a2时,跳转到上一个1标签 */ 2: /* clear bss section */ la a0, _sbss /* bss起始地址 */ la a1, _ebss /* bss结尾地址 */ bgeu a0, a1, 2f /* a0 greater/equal a1时,跳转到下一个2标签 */ 1: sw zero, (a0) addi a0, a0, 4 bltu a0, a1, 1b /* a0 less than a1时,跳转到上一个1标签 */ 2: li t0, 0x80 /* 立即数0x80 */ csrw mstatus, t0 /* 写入mstatus寄存器 */ li t0, 0x3 /* 立即数0x3 */ csrw 0x804, t0 /* 写入intsyscr寄存器 */ la t0, _start /* _start地址 */ ori t0, t0, 3 /* t0 = t0 | 3 */ csrw mtvec, t0 /* 写入mtvec寄存器 */ jal SystemInit /* 跳转至SystemInit,随后函数返回 */ la t0, main /* main函数地址 */ csrw mepc, t0 /* 写入mepc寄存器 */ mret /* 退出机器模式,进入用户模式。 */
Part3 - INT vectors
剩余部分,为中断向量的设置,与MCU所提供的具体功能相关,不再赘述。
源代码
.section .init, "ax", @progbits .globl _start .align 2 _start: .option norvc; j handle_reset .word 0 .word NMI_Handler /* NMI Handler */ .word HardFault_Handler /* Hard Fault Handler */ .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word SysTick_Handler /* SysTick Handler */ .word 0 .word SW_Handler /* SW Handler */ .word 0 /* External Interrupts */ .word WWDG_IRQHandler /* Window Watchdog */ .word PVD_IRQHandler /* PVD through EXTI Line detect */ .word FLASH_IRQHandler /* Flash */ .word RCC_IRQHandler /* RCC */ .word EXTI7_0_IRQHandler /* EXTI Line 7..0 */ .word AWU_IRQHandler /* AWU */ .word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */ .word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */ .word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */ .word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */ .word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */ .word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */ .word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */ .word ADC1_IRQHandler /* ADC1 */ .word I2C1_EV_IRQHandler /* I2C1 Event */ .word I2C1_ER_IRQHandler /* I2C1 Error */ .word USART1_IRQHandler /* USART1 */ .word SPI1_IRQHandler /* SPI1 */ .word TIM1_BRK_IRQHandler /* TIM1 Break */ .word TIM1_UP_IRQHandler /* TIM1 Update */ .word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ .word TIM2_IRQHandler /* TIM2 */ .option rvc; .section .text.vector_handler, "ax", @progbits .weak NMI_Handler .weak HardFault_Handler .weak SysTick_Handler .weak SW_Handler .weak WWDG_IRQHandler .weak PVD_IRQHandler .weak FLASH_IRQHandler .weak RCC_IRQHandler .weak EXTI7_0_IRQHandler .weak AWU_IRQHandler .weak DMA1_Channel1_IRQHandler .weak DMA1_Channel2_IRQHandler .weak DMA1_Channel3_IRQHandler .weak DMA1_Channel4_IRQHandler .weak DMA1_Channel5_IRQHandler .weak DMA1_Channel6_IRQHandler .weak DMA1_Channel7_IRQHandler .weak ADC1_IRQHandler .weak I2C1_EV_IRQHandler .weak I2C1_ER_IRQHandler .weak USART1_IRQHandler .weak SPI1_IRQHandler .weak TIM1_BRK_IRQHandler .weak TIM1_UP_IRQHandler .weak TIM1_TRG_COM_IRQHandler .weak TIM1_CC_IRQHandler .weak TIM2_IRQHandler NMI_Handler: 1: j 1b HardFault_Handler: 1: j 1b SysTick_Handler: 1: j 1b SW_Handler: 1: j 1b WWDG_IRQHandler: 1: j 1b PVD_IRQHandler: 1: j 1b FLASH_IRQHandler: 1: j 1b RCC_IRQHandler: 1: j 1b EXTI7_0_IRQHandler: 1: j 1b AWU_IRQHandler: 1: j 1b DMA1_Channel1_IRQHandler: 1: j 1b DMA1_Channel2_IRQHandler: 1: j 1b DMA1_Channel3_IRQHandler: 1: j 1b DMA1_Channel4_IRQHandler: 1: j 1b DMA1_Channel5_IRQHandler: 1: j 1b DMA1_Channel6_IRQHandler: 1: j 1b DMA1_Channel7_IRQHandler: 1: j 1b ADC1_IRQHandler: 1: j 1b I2C1_EV_IRQHandler: 1: j 1b I2C1_ER_IRQHandler: 1: j 1b USART1_IRQHandler: 1: j 1b SPI1_IRQHandler: 1: j 1b TIM1_BRK_IRQHandler: 1: j 1b TIM1_UP_IRQHandler: 1: j 1b TIM1_TRG_COM_IRQHandler: 1: j 1b TIM1_CC_IRQHandler: 1: j 1b TIM2_IRQHandler: 1: j 1b .section .text.handle_reset, "ax", @progbits .weak handle_reset .align 1 handle_reset: .option push .option norelax la gp, __global_pointer$ .option pop 1: la sp, _eusrstack 2: /* Load data section from flash to RAM */ la a0, _data_lma la a1, _data_vma la a2, _edata bgeu a1, a2, 2f 1: lw t0, (a0) sw t0, (a1) addi a0, a0, 4 addi a1, a1, 4 bltu a1, a2, 1b 2: /* clear bss section */ la a0, _sbss la a1, _ebss bgeu a0, a1, 2f 1: sw zero, (a0) addi a0, a0, 4 bltu a0, a1, 1b 2: li t0, 0x80 csrw mstatus, t0 li t0, 0x3 csrw 0x804, t0 la t0, _start ori t0, t0, 3 csrw mtvec, t0 jal SystemInit la t0, main csrw mepc, t0 mret
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具