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开始
- OUTPUT_ARCH(arm)
- ENTRY(_start)
- SECTIONS
- {
- . = 0x00000000;
-
- . = ALIGN(4);
- .text :
- {
- cpu/omap3/start.o (.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .rodata : { *(.rodata) }
-
- . = ALIGN(4);
- .data : { *(.data) }
-
- . = ALIGN(4);
- .got : { *(.got) }
-
- . = ALIGN(4);
- __bss_start = .;
- .bss : { *(.bss) }
- _end = .;
- }
指定了入口函数_start以及最先执行的程度代码start.S
- _start:
- b reset
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
-
- reset:
- /*
- * set the cpu to SVC32 mode
- */
- mrs r1,cpsr
- bic r1,r1,#0x1f
- orr r1,r1,#0xd3
- msr cpsr,r1
-
- /* Save the booting parameter structure *
- * (passed via pointer from r0 from ROM) *
- * (12 bytes) */
- adr r1, booting_parameter //保存Rom code读取到的启动设备参数
- ldmia r0!, {r4-r7}
- stmia r1!, {r4-r7}
-
- /* Copy vectors to mask ROM indirect addr */
- adr r0, _start /* r0 <- current position of code */
- add r0, r0, #4 /* skip reset vector */
- mov r2, #64 /* r2 <- size to copy */
- add r2, r0, r2 /* r2 <- source end address */
- mov r1, #SRAM_OFFSET0 /* build vect addr */
- mov r3, #SRAM_OFFSET1
- add r1, r1, r3
- mov r3, #SRAM_OFFSET2
- add r1, r1, r3
- next:
- ldmia r0!, {r3-r10} /* copy from source address [r0] */
- stmia r1!, {r3-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end address [r2] */
- bne next /* loop until equal */
-
- bl cpy_clk_code /* put dpll adjust code behind vectors */
-
- /* the mask ROM code should have PLL and others stable */
- bl cpu_init_crit
- ldr pc, _start_armboot /* jump to C code */
-
- _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,本文不详诉,参考网络资料。
有其他疑问,欢迎留言提问,我有空会回复解答