通过help bootm命令可以知道bootm所带的参数,以下内容来自于u-boot/common/cmd-bootm.c:U_BOOT_CMD(bootm,CFG_MAXARGS,1,do_bootm,"bootm- boot application image from memory/n","[addr [arg ...]]/n- boot application image stored in memory/n""/tpassing arguments 'arg ...'; when booting a Linux kernel,/n""/t'arg' can be the address of an initrd image/n");从这里可以知道,bootm后面可以带两个参数,一个是内核所在的地址,这个地址就是通过tftp或者loadx指令下载内核时的存放地址,另一个可以指明initrd所处的位置。
1.1.2do_bootm
在u-boot检测到bootm命令后,它将调用do_bootm这个函数进行内核引导:int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ulongiflag;ulongaddr;ulongdata, len, checksum;ulong*len_ptr;uintunc_len = CFG_BOOTM_LEN;inti, verify;char*name, *s;int(*appl)(int, char *[]);image_header_t *hdr = &header;/*1、提取命令行中的地址参数。*/s = getenv ("verify");verify = (s && (*s == 'n')) ? 0 : 1;if (argc < 2) {addr = load_addr;} else {addr = simple_strtoul(argv[1], NULL, 16);}SHOW_BOOT_PROGRESS (1);printf ("## Booting image at %08lx .../n", addr);/* Copy header so we can blank CRC field for re-calculation */memmove (&header, (char *)addr, sizeof(image_header_t));/*2、检测内核文件头的签名是否有效。*/if (ntohl(hdr->ih_magic) != IH_MAGIC) {{puts ("Bad Magic Number/n");SHOW_BOOT_PROGRESS (-1);return 1;}}SHOW_BOOT_PROGRESS (2);/*3、通过CRC校验确定文件是否损坏。*/data = (ulong)&header;len= sizeof(image_header_t);checksum = ntohl(hdr->ih_hcrc);hdr->ih_hcrc = 0;if (crc32 (0, (uchar *)data, len) != checksum) {puts ("Bad Header Checksum/n");SHOW_BOOT_PROGRESS (-2);return 1;}SHOW_BOOT_PROGRESS (3);/*4、输出内核文件头的信息。*//* for multi-file images we need the data part, too */print_image_hdr ((image_header_t *)addr);data = addr + sizeof(image_header_t);len= ntohl(hdr->ih_size);if (verify) {puts ("Verifying Checksum ... ");if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {printf ("Bad Data CRC/n");SHOW_BOOT_PROGRESS (-3);return 1;}puts ("OK/n");}SHOW_BOOT_PROGRESS (4);/*5、检验内核是否为此ARCH编译的。*/len_ptr = (ulong *)data;if (hdr->ih_arch != IH_CPU_BLACKFIN){printf ("Unsupported Architecture 0x%x/n", hdr->ih_arch);SHOW_BOOT_PROGRESS (-4);return 1;}SHOW_BOOT_PROGRESS (5);/*6、判断文件类型,对于uclinux内核,其值为IH_TYPE_KERNEL。*/switch (hdr->ih_type) {case IH_TYPE_STANDALONE:name = "Standalone Application";/* A second argument overwrites the load address */if (argc > 2) {hdr->ih_load = htonl(simple_strtoul(argv[2], NULL, 16));}break;case IH_TYPE_KERNEL:name = "Kernel Image";break;case IH_TYPE_MULTI:name = "Multi-File Image";len= ntohl(len_ptr[0]);/* OS kernel is always the first image */data += 8; /* kernel_len + terminator */for (i=1; len_ptr[i]; ++i)data += 4;break;default: printf ("Wrong Image Type for %s command/n", cmdtp->name);SHOW_BOOT_PROGRESS (-5);return 1;}SHOW_BOOT_PROGRESS (6);/** We have reached the point of no return: we are going to* overwrite all exception vector code, so we cannot easily* recover from any failures any more...*//*7、将内核解压缩到文件头中指定的Load Address,从这里也可以知道,下载地址和文件头中的LoadAddress之间应该有足够的空间,否则将造成解压缩的失败。*/iflag = disable_interrupts();switch (hdr->ih_comp) {case IH_COMP_NONE:if(ntohl(hdr->ih_load) == addr) {printf ("XIP %s ... ", name);} else {memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);}break;case IH_COMP_GZIP:printf ("Uncompressing %s ... ", name);if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,(uchar *)data, &len) != 0) {puts ("GUNZIP ERROR - must RESET board to recover/n");SHOW_BOOT_PROGRESS (-6);do_reset (cmdtp, flag, argc, argv);}break;default:if (iflag)enable_interrupts();printf ("Unimplemented compression type %d/n", hdr->ih_comp);SHOW_BOOT_PROGRESS (-7);return 1;}puts ("OK/n");SHOW_BOOT_PROGRESS (7);/*8、由于引导的是内核,跳过本段代码。*/switch (hdr->ih_type) {case IH_TYPE_STANDALONE:if (iflag)enable_interrupts();/* load (and uncompress), but don't start if "autostart"* is set to "no"*/if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) {char buf[32];sprintf(buf, "%lX", len);setenv("filesize", buf);return 0;}appl = (int (*)(int, char *[]))ntohl(hdr->ih_ep);(*appl)(argc-1, &argv[1]);return 0;case IH_TYPE_KERNEL:case IH_TYPE_MULTI:/* handled below */break;default:if (iflag)enable_interrupts();printf ("Can't boot image type %d/n", hdr->ih_type);SHOW_BOOT_PROGRESS (-8);return 1;}SHOW_BOOT_PROGRESS (8);/*9、调用相应的函数进行内核引导。*/switch (hdr->ih_os) {