Uboot-1.1.2 之bootm命令定义

bootm命令宏定义如下:

U_BOOT_CMD(
  bootm, CFG_MAXARGS, 1, do_bootm,
  "bootm   - boot application image from memoryn",
  "[addr [arg ...]]n    - boot application image stored in memoryn"
  "tpassing arguments 'arg ...'; when booting a Linux kernel,n"
  "t'arg' can be the address of an initrd imagen"
);
 该命令的执行函数是do_bootm函数,参数最大数量为CFG_MAXARGS(一般16)个。
5.2.2 do_bootm函数源码分析
ulong load_addr = CFG_LOAD_ADDR;
// 默认加载地址, 如果用户没有指定地址就使用这个

int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
 ulong iflag;
 ulong addr;
 ulong data, len, checksum;
 ulong  *len_ptr;
 uint unc_len = 0x400000;
 int i, verify;
 char *name, *s;
 int (*appl)(int, char *[]);
 image_header_t *hdr = &header;

 s = getenv ("verify");   // 检查是否需要校验计算
 verify = (s && (*s == 'n')) ? 0 : 1;

 if (argc < 2) {     // 启动参数数量<2
  addr = load_addr;   // 如果没有提供加载地址则直接使用预定义的地址
 } else {
  addr = simple_strtoul(argv[1], NULL, 16); // 取得设定的地址CFG_LOAD_ADDR
 }

 SHOW_BOOT_PROGRESS (1);    // 第一阶段
 printf ("## Booting image at %08lx ...n", addr); // 显示启动地址

 // 从加载地址处拷贝image_header_t结构体数据到header中, 用于计算头部校验
 memmove (&header, (char *)addr, sizeof(image_header_t));  

 if (ntohl(hdr->ih_magic) != IH_MAGIC) {   // 检查摩数值是否符合要求
  puts ("Bad Magic Numbern");
  SHOW_BOOT_PROGRESS (-1);
  return 1;
 }
 SHOW_BOOT_PROGRESS (2);   // 第二阶段

 data = (ulong)&header;     // 接下来对image_header_t头进行校验
 len  = sizeof(image_header_t);

 checksum = ntohl(hdr->ih_hcrc);
 hdr->ih_hcrc = 0;       // 先将CRC校验数据清零
 // 将计算得到的校验值与原校验值比较, 相等则通过
 if (crc32 (0, (char *)data, len) != checksum) { 
  puts ("Bad Header Checksumn");
  SHOW_BOOT_PROGRESS (-2);
  return 1;
 }
 SHOW_BOOT_PROGRESS (3);    // 第三阶段

 /* 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, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
   printf ("Bad Data CRCn");
   SHOW_BOOT_PROGRESS (-3);
   return 1;
  }
  puts ("OKn");
 }
 SHOW_BOOT_PROGRESS (4);   // 第四阶段

 len_ptr = (ulong *)data;
 if (hdr->ih_arch != IH_CPU_ARM) {   // 检查代码是否符合本机的架构(ARM)
  printf ("Unsupported Architecture 0x%xn", hdr->ih_arch);
  SHOW_BOOT_PROGRESS (-4);
  return 1;
 }
 SHOW_BOOT_PROGRESS (5);   // 第五阶段

 switch (hdr->ih_type) {      // 代码的类型
 case IH_TYPE_STANDALONE:   // 标准的可执行程序
  name = "Standalone Application";
  /* A second argument overwrites the load address */
  if (argc > 2) {
   hdr->ih_load = simple_strtoul(argv[2], NULL, 16);
  }
  break;
 case IH_TYPE_KERNEL:     // 内核映像
  name = "Kernel Image";    // 对应引导linux内核来说就是这个
  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 commandn", cmdtp->name);
  SHOW_BOOT_PROGRESS (-5);
  return 1;
 }
 SHOW_BOOT_PROGRESS (6);    // 第六阶段

 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:     // 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 recovern");
   SHOW_BOOT_PROGRESS (-6);
   do_reset (cmdtp, flag, argc, argv);
  }
  break;
#ifdef CONFIG_BZIP2  
 case IH_COMP_BZIP2:      // bzip2格式的压缩文件
  printf ("   Uncompressing %s ... ", name);
  i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),
      &unc_len, (char *)data, len,
      CFG_MALLOC_LEN < (4096 * 1024), 0);
  if (i != BZ_OK) {
   printf ("BUNZIP2 ERROR %d - must RESET board to recovern", i);
   SHOW_BOOT_PROGRESS (-6);
   udelay(100000);
   do_reset (cmdtp, flag, argc, argv);
  }
  break;
#endif /* CONFIG_BZIP2 */
 default:
  if (iflag)
   enable_interrupts();
  printf ("Unimplemented compression type %dn", hdr->ih_comp);
  SHOW_BOOT_PROGRESS (-7);
  return 1;
 }
 puts ("OKn");
 SHOW_BOOT_PROGRESS (7);    // 第七阶段

 switch (hdr->ih_type) {      // 再次检查代码类型, 用于启动
 case IH_TYPE_STANDALONE:   // 如果是标准应用程序
  if (iflag)
   enable_interrupts();
  // 加载文件, 但是如果环境变量中autostart=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:
  break;
 default:
  if (iflag)
   enable_interrupts();
  printf ("Can't boot image type %dn", hdr->ih_type);
  SHOW_BOOT_PROGRESS (-8);
  return 1;
 }
 SHOW_BOOT_PROGRESS (8);     // 第七阶段

 switch (hdr->ih_os) {       // 检查操作系统类型
 default:   /* handled by (original) Linux case */
 case IH_OS_LINUX:       // linux则调用do_bootm_linux执行
     do_bootm_linux  (cmdtp, flag, argc, argv,
        addr, len_ptr, verify);
     break;
 …
 }

 SHOW_BOOT_PROGRESS (-9);
 return 1;
}

转载于:https://www.cnblogs.com/weifuqin530/archive/2008/09/09/1287278.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值