linux bootloader 分析,Bootloader 源码分析

Bootloader 完成了Linux系统启动前的硬件初始化,并将跳到C执行入口,进行firmware的初始化部分。这里主要分析汇编部分。

U-boot 启动过程属于多阶段类型。第一阶段完成CPU体系结构初始化,通常由汇编完成。第二阶段实现较为复杂的功能如实现初始化硬件、内存映射、TFTP传输,串口调试,内核参数传递等,通常由C语言实现。

1. 第一阶段代码分析

第一阶段的源文件包括CPU初始化相关以及开发板初始化相关分别对应/cpu/arm920t/start.S和board/***/lowlevel_init.S文件。

1.1. 硬件初始化

完成对CPU正常工作所必须初始化工作,如时钟、工作模式、MMU等。

reset:

/*

* 设置CPU 工作在超级保护模式(SVC32)

*/

mrs r0,cpsr

bic r0,r0,#0x1f

orr r0,r0,#0xd3

msr cpsr,r0

ldr r0, =pWTCON /*关闭看门狗*/

mov r1, #0x0

str r1, [r0]

.....

bl cpu_init_crit /*跳转到该标签设置CPU寄存器MMU Cache等*/

1.2 初始化SDRAM控制器

准备Bootloader第二阶段代码RAM空间。

lowlevel_init:

ldr r0, =SMRDATA /*13个寄存器值存放地址*/

ldr r1, _TEXT_BASE

sub r0, r0, r1 /*地址变换*/

ldr r1, =BWSCON /* Bus Width Status Controller */

add r2, r0, #13*4 /*SMRDATA 末尾地址*/

0: /*循环读取设置*/

ldr r3, [r0], #4

str r3, [r1], #4

cmp r2, r0

bne 0b

/* everything is fine now */

mov pc, lr

.ltorg

/* the literal pools origin */

SMRDATA:

.word ....

1.3 设置堆栈

stack_setup:

ldr r0, _TEXT_BASE /*代码段地址之前作为堆栈 */

sub r0, r0, #CFG_MALLOC_LEN/*留给 malloc 动态分配*/

sub r0, r0, #CFG_GBL_DATA_SIZE /*存放全局变量 */

#ifdef CONFIG_USE_IRQ

sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

/*IRQ和FIQ申请堆栈*/

#endif

sub sp, r0, #12 /* 留下12字节的abord异常空间*/

1.4复制Bootloader第二阶段程序到RAM空间

relocate: /* 将U-boot复制到RAM空间*/

adr r0, _start /* 当前代码地址作为源地址给r0 */

ldr r1, _TEXT_BASE/*代码段链接地址作为目标地址给r1 */

cmp r0, r1 /* don't reloc during debug */

beq clear_bss /*测试是否在RAM中调试,否则继续复制*/

ldr r2, _armboot_start /*启动地址*/

ldr r3, _bss_start /*BSS段起始地址 即 代码段结束地址*/

sub r2, r3, r2 /* 代码段大小给 r2*/

bl CopyCode2Ram /*Nand启动时(位于bord/boot_init.c )

跳转复制函数 r0: source, r1: dest, r2: size*/

add r2, r0, r2 /* r2

copy_loop: /*Nor flash 启动循环复制*/

ldmia r0!, {r3-r10}/*copy from source address[r0] */

stmia r1!, {r3-r10} /* copy to target address [r1] */

cmp r0, r2 /*until source end addreee [r2] */

ble copy_loop

1.5 跳转到C入口

跳转之前清除堆栈空间,然后PC指针跳转到/lib_arm/board.c中的start_armboot( )函数开始执行bootloader的第二阶段代码。

ldr pc, _start_armboot

_start_armboot: .word start_armboot

2.第二阶段代码分析

Bootloader第二阶段完成工作从lib_arm/board.c中的start_armboot( )函数开始执行,也即是第一阶段跳转到的地址。从这部分开始下面全是由C编写完成,分析起来较为容易,不做过多介绍,依次完成的主要工作:

size = flash_init ();

nand_init(); /* go init the NAND */

env_relocate (); /* initialize environment */

devices_init (); /* get the devices list going. */

jumptable_init (); /* 初始化跳转列表 */

console_init_r (); /* fully init console as a device */

enable_interrupts ();/* 中断使能 */

board_late_init ();

eth_initialize(gd->bd);/* 初始化网口 */

在main_loop ()中死循环,等待用户交互。

for (;;)

{

main_loop ();

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值