• DM3730 X-load 分析


    DM3730的启动过程:ROM code -->MLO-->u-boot.bin-->解析boot.scr-->uImage->挂载文件系统

    其中MLO就是x-load编译而来,相当于SPL

    以我现在使用的LogicPD SOM-LV核心板及其SDK为例,该SDK是在官方SDK基础上小改而来,大同小异

    X-loader编译

    cd rpm/BUILD/x-loader-1.46/

    make distclean 

    make CROSS_COMPILE=/opt/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi- dm3730logic_config

    make CROSS_COMPILE=/opt/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi- 

    具体编译脚本请查看目录下的makefile

    编译OK后,会生成MLO x-load x-load.bin x-load_usb x-load_usb.bin 

    由编译脚本可知:

    $(obj)MLO:    $(obj)x-load.bin.ift
        cp $(obj)x-load.bin.ift $(obj)MLO

    $(obj)x-load.bin.ift:    $(obj)x-load.bin $(obj)scripts/signGP
        $(obj)scripts/signGP $(obj)x-load.bin $(CONFIG_SYS_TEXT_BASE)
    $(obj)scripts/signGP:     $(src)scripts/signGP.c
        mkdir -p $(obj)scripts
        $(HOSTCC) -o $@ $<

    $(obj)x-load.bin:    $(obj)x-load
            $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

    MLO是通过signGP工具从x-loader.bin生成而来,具体可看 scripts/signGP.c的实现,实质是在x-load.bin的基础上增加了一个4字节的header,header内容是4个字节的x-loader长度和x-loader被load的目标地址。

    本开发板的目标地址是定义在board/dm3730logic/config.mk下 CONFIG_SYS_TEXT_BASE=0x40200800 该变量在编译脚本中被传给了signGP,

    先用连接脚本board/dm3730logic/x-load.lds开始

    1. OUTPUT_ARCH(arm)
    2. ENTRY(_start)
    3. SECTIONS
    4. {
    5.     . = 0x00000000;
    6.     . = ALIGN(4);
    7.     .text      :
    8.     {
    9.       cpu/omap3/start.o    (.text)
    10.       *(.text)
    11.     }
    12.     . = ALIGN(4);
    13.     .rodata : { *(.rodata) }
    14.     . = ALIGN(4);
    15.     .data : { *(.data) }
    16.     . = ALIGN(4);
    17.     .got : { *(.got) }
    18.     . = ALIGN(4);
    19.     __bss_start = .;
    20.     .bss : { *(.bss) }
    21.     _end = .;
    22. }


    指定了入口函数_start以及最先执行的程度代码start.S

    1. _start:
    2.     b    reset
    3.      ldr    pc, _hang
    4.     ldr    pc, _hang
    5.     ldr    pc, _hang
    6.     ldr    pc, _hang
    7.     ldr    pc, _hang
    8.     ldr    pc, _hang
    9.     ldr    pc, _hang
    10. reset:
    11.     /*
    12.      * set the cpu to SVC32 mode
    13.      */
    14.     mrs    r1,cpsr
    15.     bic    r1,r1,#0x1f
    16.     orr    r1,r1,#0xd3
    17.     msr    cpsr,r1
    18.     /* Save the booting parameter structure  *
    19.          * (passed via pointer from r0 from ROM) *
    20.          * (12 bytes)                            */
    21.     adr    r1, booting_parameter  //保存Rom code读取到的启动设备参数
    22.     ldmia    r0!, {r4-r7}
    23.     stmia    r1!, {r4-r7}
    24.     /* Copy vectors to mask ROM indirect addr */
    25.     adr     r0, _start              /* r0 <- current position of code   */
    26.     add     r0, r0, #4        /* skip reset vector                */
    27.     mov     r2, #64                 /* r2 <- size to copy               */
    28.     add     r2, r0, r2              /* r2 <- source end address         */
    29.     mov     r1, #SRAM_OFFSET0       /* build vect addr                  */
    30.     mov     r3, #SRAM_OFFSET1
    31.     add     r1, r1, r3
    32.     mov     r3, #SRAM_OFFSET2
    33.     add     r1, r1, r3
    34. next:
    35.     ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
    36.     stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
    37.     cmp     r0, r2                  /* until source end address [r2]    */
    38.     bne     next                    /* loop until equal */
    39.     bl    cpy_clk_code            /* put dpll adjust code behind vectors */
    40.     /* the mask ROM code should have PLL and others stable */
    41.     bl  cpu_init_crit
    42.     ldr    pc, _start_armboot    /* jump to C code                   */
    43. _start_armboot: .word start_armboot

    start.S里面先设置CPU工作方式,保存启动设备参数,初始化CPU,最好调_stat_armboot 
        // cpu/omap3/start.S 
        bl  cpu_init_crit  // cpu/ompa3/start.S 
                bl    lowlevel_init    // cpu/omap3/platform.S 
                        bl      s_init  // board/dm3730logic.c   //进行主要的CPU级初始化,bss,watchdog,clk,timer,serial, ddr, nand,i2c等

    特别说明logicpd这个核心板,硬件默认优先nand启动,

    一切初始化OK之后,跳到lib/board.c:start_armboot() 开始执行C代码

    init_fnc_t *init_sequence[] = {
        cpu_init,        /* basic cpu dependent setup */
        board_init,        /* basic board dependent setup */
    #ifdef CFG_PRINTF
         serial_init,        /* serial communications setup */
        trace_dump,
        print_info,
    #endif
          nand_init,        /* board specific nand init */
          NULL,
    };

    misc_init_r();

        /* go run U-Boot and never return */
         ((init_fnc_t *)boot_fnc_ptr)();

    这个函数中先是进一步初始化了一些外设和CPU功能,然后根据Romcode识别到的启动设备,从启动设备加载u-boot.bin 到启动地址,然后直接跳转执行。(注意我手头的x-load只实现了从nand,emmc,usb启动,没有实现从nor启动)

    有一个问题,为什么TI 平台不直接用u-boot或者bootloader,而要先搞一个x-loader呢?

    在回答这个问题之前,我们先回顾下Nor和Nand的区别,Nand Flash的读写速度慢,但是容量大,价格相对便宜,寿命更长。Nor编程简单,有独立的地址引脚,可以方便的存取其内容的每一个字节。一般的,Nandflash用于存储数据,NorFlash一般用于存储启动代码。

    Samsuang公司未了弥补Nandflash的不足,在Nandflahs芯片内集成了一个RAM接口,命令未OneNandFlash,这类Flash拥有和NorFlash相同的简单接口,而且不受地址引脚的限制,即容量与地址引脚无关。简单的说,OneNandFlash就是采用了Nor的接口,Nand的架构,是两者的性能得到了综合。传统的bootloader是放在Nand的架构下的,而CPU却是从Nor的接口下读取bootloader到SDRAM中,因此需要有一个步骤,就是怎么把Bootloader/uboot从OneNand架构下复制到SDRAM中,这就是x-loader的功能,不仅初始化OneNand,并且把u-boot从Nand的架构下复制到bufferRam中,再复制到SDRAM中。

    X-loader还支持从SD/MMC/下引导uboot。本质上x-loader起到了初始化OneNand和引导u-boot的作用。

    TI平台的GPMC ,可以接Nor,也可以和FPGA等通信,通过不同的CS片选来通信,本开发板所使用的RAM和Nand,是直接POP到CPU的,即DM3730背上贴有一片MCP(DDR+NAND)

    对于GPMC,本文不详诉,参考网络资料。

    有其他疑问,欢迎留言提问,我有空会回复解答

  • 相关阅读:
    Android线程优化——整体思路与方法
    第三课 Python利器
    2022年《一生一系统作业》python练习题
    用代谢组学解密纳米颗粒缓解烟草重金属中毒机制
    太方便了,钉钉上就可完成代码发布审批啦!
    印刷企业使用数字工厂管理系统前后有什么变化
    从0到1 手把手搭建spring cloud alibaba 微服务大型应用框架(六)(优化篇)开发篇-如何解决微服务开发环境请求实例转发到别人机器问题
    m基于GA遗传优化的BP神经网络时间序列预测算法matlab仿真
    python自带静态web服务器搭建代码实现(一)
    2022_08_06__106期__二叉树
  • 原文地址:https://blog.csdn.net/layuetian2011/article/details/126136107