uboot start.s源码分析
最近面试不少被问到了启动流程相关的东西,自己总结下吧。
linux操作系统的启动流程可以分为 bootloader-->kernel-->rootfs
,其中uboot
是一种常用的bootloader
工具,该篇文章就简单写一下自己对bootloader
过程的理解。
bootloader制作uboot
-
下载u-boot源码
u-boot源码下载地址 -
下载对应交叉编译工具并配置到环境变量
工具链下载地址
sudo apt-get install libc6-i386
安装32位库支持
.zshrc文件加上export PAHT=$PATH:/usr/arm-linux-toolschains4.4.3/bin
-
make smdk2410_config 确定平台
生成include/config.mk include/config.h -
make 生成uboot.bin文件
uboot代码体系
Bootloader的启动过程又分为两个阶段stage1和stage2。
stage1全部由汇编编写,即start.s
,它的主要工作是:
- 初始化硬件设备
- 为加载Bootlodader的stage2准备RAM空间
- 拷贝Bootloader的stage2到RAM空间
- 设置好堆栈段为stager2的C语言环境做准备。
stage2全部由C语言编写,其的主要工作是:
- 初始化本阶段要使用到的硬件设备
- 将内核映像和根文件系统映像从 flash 上读到RAM
- 调用内核
start.s代码分析
/* 汇编中的.globl或.global = C语言中的extern */
.globl _start /
_start: b start_code
ldr pc, _undefined_instruction /* 未定义异常 */
ldr pc, _software_interrupt /* 软中断 */
ldr pc, _prefetch_abort /* 预取中止 */
ldr pc, _data_abort /* 数据中止 */
ldr pc, _not_used /* 未使用 */
ldr pc, _irq /* 中断异常IRQ */
ldr pc, _fiq /* 快中断异常FIQ */
/* 申请一个字的空间将.word的地址写入 */
_undefined_instruction: .word 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
.balignl 16,0xdeadbeef
/* .balignl来指定接下来的代码要16字节对齐,空缺的用0xdeadbeef,方便更加高效的访问内存 */
这部分是裸机开发最开始必须要写的,但不会一上电就执行,接下来我们看一下真正的start_code
start_code:
/* 上电后将系统设置为管理模式 */
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0
bl coloured_LED_init
bl red_LED_on
#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
/* 重定位异常表 */
ldr r0, =_start
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex
#endif
#ifdef CONFIG_S3C24X0
/* 关闭开门狗*/
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/* 屏蔽IRQ */
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
#