编写此文档记录学习uboot的过程,本文为系列第二篇
1.2 定义无
2. 概述U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下:
(1)第一阶段的功能
· 硬件设备初始化
· 加载U-Boot第二阶段代码到RAM空间
· 设置好栈
(2)第二阶段的功能
· 初始化本阶段使用的硬件设备
· 检测系统内存映射
· 将内核从Flash读取到RAM中
· 为内核设置启动参数
· 调用内核
本文主要分析启动的第一阶段
3. 硬件设备初始化根据链接脚本(本系列第一篇)\u-boot-2008.10\cpu\arm926ejs\start.s 文件为cpu上电后执行的第一的文件(第一段代码)
Start.s代码开头如下:
3.1 设置异常向量.globl _start
_start: b start_code /* 复位 */
ldr pc,_undefined_instruction /* 未定义指令向量 */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_software_interrupt /* 软件中断向量 */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_prefetch_abort /* 预取指令异常向量 */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_data_abort /* 数据操作异常向量 */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_not_used /* 未使用 */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_irq /* irq中断向量 */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_fiq /* 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
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef //设置对齐方式为16位对齐方式,空白区域自动用0xdeafbeef填充
其中
_undefined_instruction;_software_interrupt为lable,和C语言里面的lable一样,lable的值为当前代码的地址。
.word为GCC汇编伪指令,表示在当前位置定义一个字的变量,变量的内容紧跟其后。
所以执行_undefined_instruction: .word undefined_instruction指令后的内存映像为:
地址 |
大小 |
|
0x000000004 _undefined_instruction |
undefined_instruction |
Word(32) |
以上代码设置了ARM异常向量表,各个异常向量介绍如下:
表 2.1 ARM异常向量表
地址
异常
进入模式
描述
0x00000000
复位
管理模式
复位电平有效时,产生复位异常,程序跳转到复位处理程序处执行
0x00000004
未定义指令
未定义模式
遇到不能处理的指令时,产生未定义指令异常
0x00000008
软件中断
管理模式
0x0000000c
预存指令
中止模式
处理器预取指令的地址不存在,或该地址不允许当前指令访问,产生指令预取中止异常
0x00000010
数据操作
中止模式
处理器数据访问指令的地址不存在,或该地址不允许当前指令访问时,产生数据中止异常
0x00000014
未使用
未使用
未使用
0x00000018
IRQ
IRQ
外部中断请求有效,且cpsR中的I位为0时,产生IRQ异常
0x0000001c
FIQ
FIQ
在cpu\arm926ejs\start.s中还有这些异常对应的异常处理程序。当一个异常产生时,cpu根据异常号在异常向量表中找到对应的异常向量,然后执行异常向量处的跳转指令,cpu就跳转到对应的异常处理程序执行。
其中复位异常向量的指令“b start_code”决定了U-Boot启动后将自动跳转到标号“start_code”处执行。
3.2 设置定位lable_TEXT_BASE:
.word TEXT_BASE
TEXT_BASE在系列一中有分析,在MAKEFIE 中通过TEXT_BASE指定代码段的VMA地址偏移,其中TEXT_BASE保存于board\hi3515v100\config.mk 中,在这里用来计算其他的地址偏移
.globl _armboot_start
_armboot_start:
.word _start
.globl _img_end
_img_end:
.word __img_end
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
以上代码定义了一些断地址,并导出为全局变量(.globle),在连接文件里面有对这些变量赋值,在这里同样用于计算偏移
#ifdef CONfig_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
此处尚有疑问
#ifdef CONfig_HISILICON
_clr_remap_rom_entry:
.word ROM_TEXT_ADRS + do_clr_remap - TEXT_BASE
_clr_remap_nand_entry:
.word NAND_TEXT_ADRS + do_clr_remap - TEXT_BASE
此处计算do_clr_remap的LMA,由于没有进行代码搬移前代码是执行在LMA地址上的(同时这一段代码也是地址无关的代码即PIC,关于地址无关的代码见博文http://hi.baidu.com/kinylei/blog/item/c7acf92235b8104493580795.html ),此处分别计算代码存储在norflash和nandflash里面的LMA.
3.3 设置其他相关reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,#0xd3
msr cpsr,r0
cpsR位图
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
#ifndef CONfig_SKIP_LOWLEVEL_INIT
* flush v4 I/D caches
mov r0,#0
mcr p15,c7,0 /* flush v3/v4 cache */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,c8,0 /* flush v4 TLB */
* disable MMU stuff and caches
mrc p15,c1,c0,0
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#0x00002300 /* clear bits 13,9:8 (--V- --RS) */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#0x00000087 /* clear bits 7,2:0 (B--- -CAM) */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#0x00000002 /* set bit 2 (A) Align */
以上禁止MMU
ldr r0,=REG_BASE_SCTL
ldr r1,[r0,#0x8c]
and r1,r1,#0x60
lsr r4,#5
以上获取BOOT状态到R4
mov r0,pc,lsr#24s
cmp r0,#0x0
bne do_clr_remap
检测是否需要跳转,PC的高八位如果不为0(已经在ram中运行了)则跳转
cmp r4,#2 /* boot from nand flash*/
ldreq pc,_clr_remap_nand_entry
cmp r4,#0 /* boot from nor flash */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_clr_remap_rom_entry
此处的_clr_remap_nand_entry与_clr_remap_rom_entry为LMA地址,前面已分析
do_clr_remap:
ldr r4,244)"> @ldr r0,=REG_VALUE_SC_NOLOCK
@str r0,[r4,#REG_VALUE_SC_LOCKED]
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#REG_SC_CTRL]
@Set clear remap bit.
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#(1<<8)
str r0,244)"> @Setup ITCM (ENABLED,4KB)
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,=( 1 | (MEM_CONF_ITCM_SIZE<<2) | MEM_BASE_ITCM)
mcr p15,c9,1
以上清除重映射,清除重映射后地址0x000000处安排为ITCM,此处有一个疑问,既然还运行在flash里面那么清重映射后就会运行在ITCM里面,但是ITCM里面保存有代码吗?
@enable I-Cache Now
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#0x00001000 /* set bit 12 (I) I-Cache */
@Setup lowlevel sp
ldr sp,=(MEM_BASE_ITCM + MEM_SIZE_ITCM)
// @Check if I'm running in static mem bank
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,lsr#28
cmp r0,#(TEXT_BASE>>28)
* Go setup Memory and board specific bits prior to relocation.
beq relocate
bl lowlevel_init /* go setup pll,mux,memory */
#ifndef CONfig_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
ldr r0,244)"> ldr r6,244)"> and r6,244)"> lsr r4,r6,244)"> adr r0,_start /* r0 <- current position of code */
ldr r1,_TEXT_BASE /* test if we run from flash or RAM */
cmp r0,r1 /* don't reloc during debug */
beq stack_setup
ldr r2,_armboot_start
ldr r3,_img_end
sub r2,r3,r2 /* r2 <- size of armboot */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#2
ldreq r2,=(CFG_NAND_U_BOOT_ONE_PART)
add r2,r2 /* r2 <- source end address */
copy_loop:
ldmia r0!,{r3-r10} /* copy from source address [r0] */
stmia r1!,{r3-r10} /* copy to target address [r1] */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,r2 /* until source end addreee [r2] */
ble copy_loop
#endif /* CONfig_SKIP_RELOCATE_UBOOT */
/* Set up the stack */
stack_setup:
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0,#CFG_MALLOC_LEN /* malloc area */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#CFG_GBL_DATA_SIZE /* bdinfo */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,#(CONfig_STACKSIZE_IRQ+CONfig_STACKSIZE_FIQ)
sub sp,#12 /* leave 3 words for abort-stack */
以上设置堆栈
clear_bss:
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_bss_start /* find start of bss segment */
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_bss_end /* stop here */
mov r2,#0x00000000 /* clear */
clbss_l:str r2,[r0] /* clear loop... */
add r0,#4
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,r1
ble clbss_l
以上清除BSS
ottom:0px; margin-top:0px; margin-bottom:0px; list-style-type:none; list-style-position:initial; line-height:1.5em; font-family:Simsun; font-size:14px; background-color:rgb(244,_start_armboot
_start_armboot:
.word start_armboot
以上跳转到第二段
下图是分析到目前为止存储空间的示意图
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。