uboot启动文件分析(hi3515)

1. 引言 1.1 编写目的

编写此文档记录学习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      /* 未定义指令向量 */

       ldr   pc, _software_interrupt            /*  软件中断向量 */

       ldr   pc, _prefetch_abort                  /*  预取指令异常向量 */

       ldr   pc, _data_abort                        /*  数据操作异常向量 */

       ldr   pc, _not_used                           /*  未使用   */

       ldr   pc, _irq                                     /*  irq中断向量  */

       ldr   pc, _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

软件中断

管理模式

执行SWI指令产生,用于用户模式下的程序调用特权操作指令

0x0000000c

预存指令

中止模式

处理器预取指令的地址不存在,或该地址不允许当前指令访问,产生指令预取中止异常

0x00000010

数据操作

中止模式

处理器数据访问指令的地址不存在,或该地址不允许当前指令访问时,产生数据中止异常

0x00000014

未使用

未使用

未使用

0x00000018

IRQ

IRQ

外部中断请求有效,且CPSR中的I位为0时,产生IRQ异常

0x0000001c

FIQ

FIQ

快速中断请求引脚有效,且CPSR中的F位为0时,产生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

/* IRQ stack memory (calculated at run-time) */

.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

#endif

此处计算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,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, 0, r0, c7, c7, 0       /* flush v3/v4 cache */

       mcr  p15, 0, r0, c8, c7, 0       /* flush v4 TLB */

       /*

        * disable MMU stuff and caches

        */

       mrc  p15, 0, r0, c1, c0, 0

       bic   r0, r0, #0x00002300      /* clear bits 13, 9:8 (--V- --RS) */

       bic   r0, r0, #0x00000087      /* clear bits 7, 2:0 (B--- -CAM) */

       orr   r0, r0, #0x00000002      /* set bit 2 (A) Align */

       mcr  p15, 0, r0, c1, c0, 0

以上禁止MMU

       ldr   r0, =REG_BASE_SCTL

       ldr     r1, [r0, #0x8c]

       and     r1, r1, #0x60

       lsr    r4, r1, #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 */

       ldreq   pc, _clr_remap_rom_entry

此处的_clr_remap_nand_entry与_clr_remap_rom_entry为LMA地址,前面已分析

do_clr_remap:

       ldr     r4, =REG_BASE_SCTL

       @ldr       r0, =REG_VALUE_SC_NOLOCK

       @str       r0, [r4, #REG_VALUE_SC_LOCKED]

       ldr   r0, [r4, #REG_SC_CTRL]

       @Set clear remap bit.

       orr   r0, #(1<<8)

       str    r0, [r4, #REG_SC_CTRL]

       @Setup ITCM (ENABLED, 4KB)

       ldr   r0, =( 1 | (MEM_CONF_ITCM_SIZE<<2) | MEM_BASE_ITCM)

       mcr     p15, 0, r0, c9, c1, 1

       以上清除重映射,清除重映射后地址0x000000处安排为ITCM,此处有一个疑问,既然还运行在flash里面那么清重映射后就会运行在ITCM里面,但是ITCM里面保存有代码吗?

       @enable I-Cache now

       mrc  p15, 0, r0, c1, c0, 0

       orr   r0, r0, #0x00001000      /* set bit 12 (I) I-Cache */

       mcr  p15, 0, r0, c1, c0, 0

       @Setup lowlevel sp

       ldr   sp, =(MEM_BASE_ITCM + MEM_SIZE_ITCM)

//     @Check if I'm running in static mem bank

       mov r0, pc, 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 */

#endif

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

relocate:                       /* relocate U-Boot to RAM       */

       ldr     r0, =REG_BASE_SCTL

       ldr     r6, [r0, #0x8c]

       and     r6, #0x60

       lsr   r4, r6, #5

       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            */

       cmp       r4, #2

       ldreq   r2, =(CFG_NAND_U_BOOT_ONE_PART)

       add  r2, r0, 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]    */

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

       ble   copy_loop

#endif     /* CONFIG_SKIP_RELOCATE_UBOOT */

以上重定位代码,既把代码段复制到ram空间里面

/* Set up the stack                                         */

stack_setup:

       ldr   r0, _TEXT_BASE         /* upper 128 KiB: relocated uboot   */

       sub  r0, r0, #CFG_MALLOC_LEN      /* malloc area                      */

       sub  r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */

#ifdef CONFIG_USE_IRQ

       sub  r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

       sub  sp, r0, #12             /* leave 3 words for abort-stack    */

以上设置堆栈

clear_bss:

       ldr   r0, _bss_start         /* find start of bss segment        */

       ldr   r1, _bss_end          /* stop here                        */

       mov r2, #0x00000000           /* clear                            */

clbss_l:str       r2, [r0]           /* clear loop...                    */

       add  r0, r0, #4

       cmp r0, r1

       ble   clbss_l

以上清除BSS

       ldr   pc, _start_armboot

_start_armboot:

       .word start_armboot

以上跳转到第二段

下图是分析到目前为止存储空间的示意图

原文:http://biancheng.dnbcw.info/linux/339267.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值