移植u-boot1.3.3到Davinci DM6446平台笔记

来源:互联网 发布:java 重载 返回值不同 编辑:程序博客网 时间:2024/05/20 06:29
相信做此工作的都对板子和u-boot有一定的理解,废话省略。写这个笔记以记录这段时间研究这个东西的一些心得,供以后参考。这个文档很不完善,画的图也变形了,郁闷!当然我工作也还没有结束,随着更深入的工作我会慢慢完善这个笔记。分析的方式我参考以前阅读的一位以pxa270目标平台的文献资料,但具体位置已不记得了,在此说明。
首先,u-boot已经提供了对davinci处理器的支持,目前1.3.3版本中有三个davinci目标板子,分别为:TI的dv-evm,另外两个schmoogie和sonata我也不大清楚是哪个公司的产品,总之我没有见过更没有用过。

板子概况:
处理器:Davinci DM6446(ARM926EJS + DSP64X+)
SDRAM:MT47H64M16BT 256M
NAND FLASH:K9F1208
网卡:BCM5221

下载u-boot-1.3.3.tar.bz2,解压后
修改顶极的Makefile,添加自己交叉编译器的名称,当然首先要导出该交叉编译工具链的环境变量。
板子的名称在该Makefile中已有,所以直接使用。
在/board/davinci/dv-evm目录下即为目标板子的相关代码文件。
CPU相关的代码在/cpu/arm926ejs以及/cpu/arm926ejs/davinci目录
在/include/configs/目录下有板子相关的定义文件davinci_dvevm.h,对着自己板子的具体情况修改就是。

做完这些工作,现测试一下,看是不是修改的能够通过:
#make davinci_dvevm_config
#make
通过,表明前期工作正常。
开始深入u-boot研究。
涉及到的目录和文件列表为:
启动第一阶段(stage 1,主要为汇编语言):
1、/cpu/arm926ejs/start.S
2、/board/davinci/dv-evm/u-boot.lds
3、/cpu/arm926ejs/davinci/lowlevel_init.S
4、/include/asm-arm/arch-davinci/
5、/include/configs/davinci/davinci_dvevm.h
6、/board/davinci/da-evm/config.mk

启动第二阶段(stage 2,主要为C语言):
1、/lib_arm/board.c
2、/board/davinci/dv-evm/dv_board.c

通过查看/board/davinci/dv-evm/u-boot.lds可知,u-boot入口函数为_start,该函数定义于/cpu/arm926ejs/start.S文件

.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

在ARM体系结构中,0x0为异常向量表地址,上电执行的第一条指令是跳转到reset复位处理程序;
reset:
    /*
     * set the cpu to SVC32 mode  
     */
//note:Bootloader中没有必要支持中断的实现,这属于内核机制以及设备驱动管理的管理范畴;SVC模式是系统的一种保护模式,这样就可以进行一些只能在SVC模式下的操作,例如一些特定寄存器访问操作。

    mrs    r0,cpsr
    bic    r0,r0,#0x1f
    orr    r0,r0,#0xd3
    msr    cpsr,r0
    /*
     * we do sys-critical inits only at reboot,
     * not when booting from ram!
     */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl    cpu_init_crit
#endif

一般情况下,不定义CONFIG_SKIP_LOWLEVEL_INIT,那么接下来跳转到cpu_init_crit处执行,
cpu_init_crit:
    /*
     * 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
     */
//note:MMU必须关闭,原因为Bootloader中所有对地址的操作都是使用物理地址,是实在的实地址,不存在虚拟地址,因此MMU必须关闭。
    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 */
    orr    r0, r0, #0x00001000    /* set bit 12 (I) I-Cache */
    mcr    p15, 0, r0, c1, c0, 0
//note:数据cache必须关闭;原因为Bootloader主要是装载内核镜像,镜像数据必须真实写回SDRAM中,所以数据cache必须关闭;
指令cache可以关闭也可以开启;对于指令cache,不存在强制性的规定,但是一般情况下,推荐关闭指令 cache。

    /*
     * Go setup Memory and board specific bits prior to relocation.
     */
    mov    ip, lr        /* perserve link reg across call */
    bl    lowlevel_init    /* go setup pll,mux,memory */
    mov    lr, ip        /* restore link */
    mov    pc, lr        /* back to my caller */

如上描述,程序跟着进入lowlevel_init执行,该函数定义于/cpu/arm926ejs/davinci/lowlevel_init.S
此函数主要用来初始化各种寄存器,各种寄存器定义可以参阅TMS320DM6446 Digital Media System-on-Chip手册。
其中,寄存器在/include/asm-arm/arch-davinci/中定义,当然该目录下一些数据类型的定义还要参阅/include/asm-arm/arch-arm926ejs/sizes.h
寄存器的初始值定义于/include/configs/davinci/davinci_dvevm.h.

按照程序的执行流程,从cpu_init_crit执行完毕后返回,紧接着执行relocate:
relocate:                /* relocate U-Boot to RAM        */
    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, _bss_start
    sub    r2, r3, r2        /* r2 <- size of armboot            */
    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 */

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

    bl coloured_LED_init
    bl red_LED_on

    ldr    pc, _start_armboot

_start_armboot:
    .word start_armboot

relocate的目的在于将u-boot镜象从nand flash copy 到SDRAM中TEXT_BASE开始的存储空间并初始化堆栈,在SDRAM中跳转到u-boot stage 2的C程序入口start_armboot函数。其中,TEXT_BASE定义于/board/davinci/da-evm/config.mk.
至此,u-boot存储映射图如下:
|---------------------------------|                  -------------|
|          ......                 |                               |
|---------------------------------|<---_end                       |
|                                 |                               |
|             BSS                 |<---_bss_start                 |
|---------------------------------|                               |
|                                 |                               |
|         u-boot image            |                               |
|---------------------------------|<---TEXT_BASE(_start)          |
|                                 |                               | ^high addr
|         CFG_MALLOC_LEN          |                               |
|---------------------------------|                                > SDRAM
|                                 |                               |
|         GLB_DATA_SIZE           |<---the pointer gd for gd_t    | Vlow addr
|---------------------------------|                               |    
|                                 |                               |
|      Stack for IRQ&FIQ          |                               |
|---------------------------------|<---user top stack sp          |
|                                 |                               |
|          user stack             |                               |
|---------------------------------|<---SDRAM_BASE  ------| -------|
|                                 |                      |
|             ......              |                      |
|                                 |                      |
|---------------------------------|                      > Flash
|                                 |                      |
|        u-boot image             |                      |
|---------------------------------|<---0x00000000  ------|


 start_armboot函数定义于/lib_arm/board.c.
原创粉丝点击