前边,我们说了,一般的bootloader都分为两个阶段。我在讲U-boot实现源码分析时,也是按照这连个阶段来分析,如果对这两个阶段不清楚,请看前边的博客。好了,开始今天的主题:U-boot在开发板上移植过程详解(2)---U-boot实现源码分析(start.S分析)
第一阶段:
1)一些基本的硬件初始化工作
u-boot对应的第一阶段代码放在cpu/arm920t/start.S文件中,入口代码如下:
.globl _start ;global声明一个符号可被其它文件引用,相当于声明了一个全局变量,.globl与.global相同 _start: b reset ;b是不带返回的跳转(bl是带返回的跳转),意思是无条件直接跳转到reset标号出执行程序 ldr pc, _undefined_instruction ;ldr相当于mov操作 ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _irq ldr pc, _fiq ;.word伪操作用于分配一段字内存单元(分配的单元都是字对齐的),并用伪操作中的expr初始化。 _undefined_instruction: .word undefined_instruction ;就是在当前地址,即_undefined_instruction 处存放 undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq |
这部分就是异常向量表。当系统上电或复位后,将执行第一条指令,即跳转到标签为reset的代码处执行,具体如下:
reset: ;设置CPU为SVC32管理模式 mrs r0,cpsr ;mrs将状态寄存器cpsr(current program status register)的内容传送至通用寄存器 bic r0,r0,#0x1f ;r0和0x1f(00011111)的反码进行位与,是把 r0后面5位清零 orr r0,r0,#0xd3 ;r0和0xd3(11010011)进行位或,最后得到r0=11010011,目的是设置r0的后5位为10011,让ARM进入SVC特权模式 msr cpsr,r0 #if defined(CONFIG_S3C2400) ;关闭看门狗 # define pWTCON 0x15300000 ;看门狗寄存器 # define INTMSK 0x14400008 ;中断屏蔽寄存器 # define CLKDIVN 0x14800014 ;时钟分频寄存器 #elif defined(CONFIG_S3C2410) # define pWTCON 0x53000000 # define INTMSK 0x4A000008 # define INTSUBMSK 0x4A00001C ;次级中断屏蔽寄存器 # define CLKDIVN 0x4C000014 ;时钟分频寄存器 #endif #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] mov r1, #0xffffffff ;屏蔽所有中断 ldr r0, =INTMSK str r1, [r0] # if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK str r1, [r0] # endif ldr r0, =CLKDIVN ;设置时钟 mov r1, #3 str r1, [r0] #endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT bl cpu_init_crit ;跳转并把转移后面紧接的一条指令地址保存到链接寄存器LR(R14)中,以此来完成子程序的调用 |