您的位置:首页 > 其它

U-Boot启动引导内核分析(二)

2010-09-13 20:50 549 查看
标签:ARM bootloader U-Boot 代码分析 抵岸科技

也许细心的你会问:我在用UBoot的时候并没有直接进入用户命令界面呀,而是在倒计时结束后自动引导kernel。这是怎么回事呢?
在 main_loop()函数当中有如下一段代码:

#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)



s = getenv ("bootcmd");
/*获取bootcmd 的内容*/
/*bootcmd=nand read 0x22000000 0xB0000 0x200000; bootm */


# ifndef CFG_HUSH_PARSER
run_command (s, 0);
/*运行s包含的命令*/
/*运行nand read 0x22000000 0xB0000 0x200000表示将NANDFLASH
0xB0000处数据读取放于0x22000000处,读取长度为0x200000
*/
/*运行bootm命令,引导内核启动*/
# else
parse_string_outer(s, FLAG_PARSE_SEMICOLON |
FLAG_EXIT_FROM_LOOP);
# endif



#endif /* CONFIG_BOOTDELAY */

bootm命令是什么?它是怎样引导内核的?
要知道想解决这个问题,就要分析common/cmd_bootm.c中的函数do_bootm,因为引导kernel就是bootm这条命令的工作,do_bootm是命令bootm的执行函数。
现在我们来分析一下common/cmd_bootm.c中的函数do_bootm,这是bootm命令的处理函数。

int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong iflag;
const char *type_name;
uint unc_len = CFG_BOOTM_LEN;
uint8_t comp, type, os;

void *os_hdr;
ulong os_data, os_len;
ulong image_start, image_end;
ulong load_start, load_end;
ulong mem_start;
phys_size_t mem_size;

struct lmb lmb;

memset ((void *)&images, 0, sizeof (images));
images.verify = getenv_yesno ("verify");
images.lmb = &lmb;

lmb_init(&lmb);

mem_start = getenv_bootm_low();
mem_size = getenv_bootm_size();

lmb_add(&lmb, (phys_addr_t)mem_start, mem_size);

board_lmb_reserve(&lmb);

/* get kernel image header, start address and length */
/* 获取内核镜像头信息 */
/* 打印 “## Booting kernel from Legacy Image at 22000000 ...
Image Name: Linux-2.6.30
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1507760 Bytes = 1.4 MB
Load Address: 20008000
Entry Point: 20008000
Verifying Checksum ... OK”*/
os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
&images, &os_data, &os_len);
if (os_len == 0) {
puts ("ERROR: can't get kernel image!/n");
return 1;
}

/* get image parameters */
/* 获取内核镜像格式 */
switch (genimg_get_format (os_hdr)) {
case IMAGE_FORMAT_LEGACY:
/* 获取内核镜像参数 */
type = image_get_type (os_hdr);
comp = image_get_comp (os_hdr);
os = image_get_os (os_hdr);

image_end = image_get_image_end (os_hdr);
load_start = image_get_load (os_hdr);
break;
}

image_start = (ulong)os_hdr;
load_end = 0;
type_name = genimg_get_type_name (type);

/* 禁止所有中断 */
iflag = disable_interrupts();

#ifdef CONFIG_AMIGAONEG3SE
/*
* We've possible left the caches enabled during
* bios emulation, so turn them off again
*/
icache_disable();
invalidate_l1_instruction_cache();
flush_data_cache();
dcache_disable();
#endif

switch (comp) {
case IH_COMP_NONE:
/* 加载内核镜像 */
/* 打印“Loading Kernel Image ... OK” */
if (load_start == (ulong)os_hdr) {
printf (" XIP %s ... ", type_name);
} else {
printf (" Loading %s ... ", type_name);

memmove_wd ((void *)load_start,
(void *)os_data, os_len, CHUNKSZ);
}
load_end = load_start + os_len;
puts("OK/n");
break;
}
puts ("OK/n");
debug (" kernel loaded at 0x%08lx, end = 0x%08lx/n", load_start, load_end);
show_boot_progress (7);

/* 加载错误 */
if ((load_start < image_end) && (load_end > image_start)) {
debug ("image_start = 0x%lX, image_end = 0x%lx/n", image_start, image_end);
debug ("load_start = 0x%lx, load_end = 0x%lx/n", load_start, load_end);

if (images.legacy_hdr_valid) {
if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
puts ("WARNING: legacy format multi component "
"image overwritten/n");
} else {
puts ("ERROR: new format image overwritten - "
"must RESET the board to recover/n");
show_boot_progress (-113);
do_reset (cmdtp, flag, argc, argv);
}
}

show_boot_progress (8);

lmb_reserve(&lmb, load_start, (load_end - load_start));

switch (os) {
default: /* handled by (original) Linux case */
case IH_OS_LINUX:
#ifdef CONFIG_SILENT_CONSOLE
fixup_silent_linux();
#endif
/* 引导内核启动函数 */
do_bootm_linux (cmdtp, flag, argc, argv, &images);
break;
}

show_boot_progress (-9);
#ifdef DEBUG
puts ("/n## Control returned to monitor - resetting.../n");
do_reset (cmdtp, flag, argc, argv);
#endif
if (iflag)
enable_interrupts();

return 1;
}

至此do_bootm函数完成引导内核前的准备任务了。引导内核启动函数将由do_bootm_linux()函数执行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: