U_Boot第一启动阶段Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解)
Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解)
1 u-boot.lds
首先了解uboot的链接脚本board/my2410/u-boot.lds,它定义了目标程序各部分的链接顺序。OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*指定输出可执行文件为ELF格式,32为,ARM小端*/
OUTPUT_ARCH(arm)
/*指定输出可执行文件为ARM平台*/
ENTRY(_start)
/*起始代码段为_start*/
SECTIONS
{
/* 指定可执行image文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置*、. = 0x00000000;从0x0位置开始
. = ALIGN(4); 4字节对齐
.text :
{
cpu/arm920t/start.o (.text)
board/my2440/lowlevel_init.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : { *(.data) } /* 只读数据段,所有的只读数据段都放在这个位置*/
. = ALIGN(4);
.got : { *(.got) } /*指定got段, got段式是uboot自定义的一个段, 非标准段*/
. = .;
__u_boot_cmd_start = .; /*把__u_boot_cmd_start赋值为当前位置, 即起始位置*/
.u_boot_cmd : { *(.u_boot_cmd) }
/* u_boot_cmd段,所有的u-boot命令相关的定义都放在这个位置,因为每个命令定义等长,所以只要以__u_boot_cmd_start为起始地址进行查找就可以很快查找到某一个命令的定义,并依据定义的命令指针调用相应的函数进行处理用户的任务*/
__u_boot_cmd_end = .;
/* u_boot_cmd段结束位置,由此可以看出,这段空间的长度并没有严格限制,用户可以添加一些u-boot的命令,最终都会在连接是存放在这个位置。*/
. = ALIGN(4);
__bss_start = .; /*把__bss_start赋值为当前位置,即bss段的开始位置*/
.bss (NOLOAD) : { *(.bss) . = ALIGN(4); } /*指定bss段,这里NOLOAD的意思是这段不需装载,仅在执行域中才会有这段*/
_end = .; /*把_end赋值为当前位置,即bss段的结束位置*/
}
第一个链接的是cpu/board/start.o,也即Uboot的入口指令在start中,下面详细分析程序的跳转和函数调用关系。
2 Stage1 : cpu/arm920t/start.S
这个汇编程序时UBoot的入口程序,以复位向量开头。
reset
↓
cpu_init_crit
↓
relocate
↓
stack_setup
↓
start_armboot()
↓
init_sequence[]
↓
getenv()
↓
main_loop()
其中前面4步为Stage1
下面来详细分析一下cpu/arm920t/start.S
这里以ARM9 2410为例,2440移植时需要修改一些配置,具体的再后面的移植中介绍. /* 这段代码的主要作用:
进入SVC模式
关闭看门狗
屏蔽所有IRG掩码
设置时钟频率 FCLK HCLK PCLK
清楚I/D Cache
禁止MMU和CACHE
配置memory control
重定位:如果代码不在指定的地址上需要把uboot从当前位置copy到RAM指定位置上建立堆栈,为进入C函数做准备
清0 .bss段
跳入start_armboot函数进入stage2(lib_arm/board.c)*/
.globl _start
_start: /* 系统复位位置, 各个异常向量对应的跳转代码 */
b reset /* 复位向量 */
ldr pc, _undefined_instruction /* 未定义的指令异常向量 */
ldr pc, _software_interrupt /* 软件中断异常向量 */
ldr pc, _prefetch_abort /* 预取指令操作异常向量 */
ldr pc, _data_abort /* 数据操作异常向量 */
ldr pc, _not_used /* 未使用 */
ldr pc, _irq /* 慢速中断异常向量 */
ldr pc, _fiq /* 快速中断异常向量 */
_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