开发板:DM3730
虚拟机:ubuntu 14.04
编译器:arm-none-linux-gnueabi
x-loader:
这几天小小的研究了一下linux的启动机制 所里这里做个小小的总结吧
现在一般的芯片的linux启动机制是这样的
上电自运行ROMCODE也就是在rom里固化的代码
ROMCODE启动后会根据SYS_BOOT[5:0]的值来去选择从nand,nor,mmc,usb,uart之类的模式启动 也就是启动x-load/MLO
x-load的主要功能就是去nand,mmc之类的mem读取uboot到内存上运行
具体为什么要这么做我还没到这个境界 现在的程度只能知道他的机制就是这么做
x-load的代码我觉得很像uboot,在我看来就是一个小型的uboot而已 只不过uboot启动的是kernel,而x-load启动的的uboot
话不多说 上来就是看代码好吧 理论也扯完了
x-load一开始跑的函数是start_armboot
void start_armboot (void)
{
init_fnc_t **init_fnc_ptr;
int i;
char boot_dev_name[8];
uchar *buf;
/* 执行cpu,board,nand,serial,nand,mmc等初始化函数 */
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
/* uart boot */
#ifdef START_LOADB_DOWNLOAD
do_load_serial_bin (CFG_LOADADDR, 115200);
#else
/* 相关单板的II2,LED初始化 在omp3单板上没有任何作用 */
misc_init_r();
/* CFG_LOADADDR=0x80008000 应该是ram地址 */
buf = (uchar*) CFG_LOADADDR;
/* Always first try mmc without checking boot pins */
#ifndef CONFIG_OMAP3_BEAGLE
if ((get_mem_type() == MMC_ONENAND) || (get_mem_type() == MMC_NAND))
#endif /* CONFIG_OMAP3_BEAGLE */
/* 先尝试从mmc启动 */
buf += mmc_boot(buf);
/* 判断是否从NAND启动 */
if (buf == (uchar *)CFG_LOADADDR) {
if (get_mem_type() == GPMC_NAND){
#ifdef CFG_PRINTF
printf("Booting from nand . . .\n");
#endif
/* 从nand上0x0080000-0x0240000地址一个块一个块的读写uboot到ram上的0x80008000运行 */
for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){
if (!nand_read_block(buf, i))
buf += NAND_BLOCK_SIZE; /* advance buf ptr */
}
}
/* 判断是否从onenand启动 */
if (get_mem_type() == GPMC_ONENAND){
#ifdef CFG_PRINTF
printf("Booting from onenand . . .\n");
#endif
for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++){
if (!onenand_read_block(buf, i))
buf += ONENAND_BLOCK_SIZE;
}
}
}
/* 和我们的omap单板无关 */
#if defined (CONFIG_AM3517EVM)
/*
* FIXME: Currently coping uboot image,
* ideally we should leverage XIP feature here
*/
if (get_mem_type() == GPMC_NOR) {
int size;
printf("Booting from NOR Flash...\n");
size = nor_read_boot(buf);
if (size > 0)
buf += size;
}
#endif
/* 如果从mmc,nand,onenand都启动了 那就悬挂*/
if (buf == (uchar *)CFG_LOADADDR)
hang();
#endif
/* 运行uboot */
/* go run U-Boot and never return */
printf("Starting OS Bootloader...\n");
((init_fnc_t *)CFG_LOADADDR)();
/* should never come here */
}
大概的执行过程就这样了 其他无非就是nand mmc的初始化 读取函数罢了