uboot启动文件分析(hi3515)
1. 引言 1.1 编写目的
编写此文档记录学习uboot的过程,本文为系列第二篇 1.2 定义无 2. 概述U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: ?????? (1)第一阶段的功能 ·?? 硬件设备初始化 ·?? 加载U-Boot第二阶段代码到RAM空间 ·?? 设置好栈 ·?? 跳转到第二阶段代码入口 ?????? (2)第二阶段的功能 ·?? 初始化本阶段使用的硬件设备 ·?? 检测系统内存映射 ·?? 将内核从Flash读取到RAM中 ·?? 为内核设置启动参数 ·?? 调用内核 本文主要分析启动的第一阶段 3. 硬件设备初始化根据链接脚本(本系列第一篇)u-boot-2008.10cpuarm926ejsstart.s? 文件为cpu上电后执行的第一的文件(第一段代码) Start.s代码开头如下: 3.1 设置异常向量.globl _start _start:??? b???? start_code???????????????????????? /* 复位 */ ?????? ldr?? pc,_undefined_instruction????? /*?未定义指令向量 */
/*? 中断向量表入口地址 */ _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指令后的内存映像为:
?????? 以上代码设置了ARM异常向量表,各个异常向量介绍如下: 表 2.1 ARM异常向量表 |
地址? |
异常? |
进入模式 |
描述 |
0x00000000? |
复位 |
管理模式 |
复位电平有效时,产生复位异常,程序跳转到复位处理程序处执行 |
0x00000004? |
未定义指令 |
未定义模式 |
遇到不能处理的指令时,产生未定义指令异常 |
0x00000008 |
软件中断 |
管理模式 |
执行SWI指令产生,用于用户模式下的程序调用特权操作指令 |
0x0000000c |
预存指令 |
中止模式 |
处理器预取指令的地址不存在,或该地址不允许当前指令访问,产生指令预取中止异常 |
0x00000010 |
数据操作 |
中止模式 |
处理器数据访问指令的地址不存在,或该地址不允许当前指令访问时,产生数据中止异常 |
0x00000014 |
未使用 |
未使用 |
未使用 |
0x00000018 |
IRQ |
IRQ |
外部中断请求有效,且CPSR中的I位为0时,产生IRQ异常 |
0x0000001c |
FIQ |
FIQ |
快速中断请求引脚有效,且CPSR中的F位为0时,产生FIQ异常 |
?????? 在cpuarm926ejsstart.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保存于boardhi3515v100config.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 */
?????? ?* disable MMU stuff and caches
?????? mrc? p15,c1,c0,0
以上禁止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 */
此处的_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]
?????? @Set clear remap bit.
?????? str??? r0,244)"> ?????? @Setup ITCM (ENABLED,4KB)
?????? mcr???? p15,c9,1
?????? 以上清除重映射,清除重映射后地址0x000000处安排为ITCM,此处有一个疑问,既然还运行在flash里面那么清重映射后就会运行在ITCM里面,但是ITCM里面保存有代码吗?
?????? @enable I-Cache now
?????? @Setup lowlevel sp
?????? ldr?? sp,=(MEM_BASE_ITCM + MEM_SIZE_ITCM)
//???? @Check if I'm running in static mem bank
?????? 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??????????? */
?????? 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]??? */
?????? ble?? copy_loop
#endif???? /* CONFIG_SKIP_RELOCATE_UBOOT */
以上重定位代码,既把代码段复制到ram空间里面
/* Set up the stack???????????????????????????????????? ??? */
stack_setup:
?????? sub? r0,#CFG_MALLOC_LEN????? /* malloc area????????????????????? */
?????? sub? sp,#12???????????? /* leave 3 words for abort-stack??? */
以上设置堆栈
clear_bss:
?????? mov r2,#0x00000000?????????? /* clear??????????????????????????? */
clbss_l:str?????? r2,[r0]?????????? /* clear loop...??????????????????? */
?????? add? r0,#4
?????? ble?? clbss_l
以上清除BSS
_start_armboot:
?????? .word start_armboot
以上跳转到第二段
下图是分析到目前为止存储空间的示意图
原文:http://biancheng.dnbcw.info/linux/339267.html
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!