tag 标签: do_bootm

相关博文
  • 热度 19
    2013-9-6 22:19
    1546 次阅读|
    0 个评论
    /*uboot一般都是调用do_bootm命令来引导内核,这个命令基本上就是判断类型 然后跳转到do_bootm_linux函数 也是做了一些简单注释 关键我也是简单看了一下 留个笔记  有问题还望指正*/ ulong load_addr = CFG_LOAD_ADDR;        /* Default Load Address */ //CFG_LOAD_ADDR 这个宏一般在smdk2410定义 ,为内核的入口地址,就是内核执行的第一个函数的地址, //这个地址首先被赋给uimage的64字节结构体的hdr-ih_ep,然后又赋给了kernel这个函数指针,最后通过 //theKernel (0, bd-bi_arch_number, bd-bi_boot_params);这个函数来进入linux内核。 int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv );     image_header_t *hdr = header;     s = getenv ("verify");     verify = (s (*s == 'n')) ? 0 : 1;     if (argc 2) {         addr = load_addr;     } else {         addr = simple_strtoul(argv , NULL, 16);     } //如果argc小于2 说明就输入了一个bootm参数 没有参数 则使用默认地址     SHOW_BOOT_PROGRESS (1);     printf ("## Booting image at %08lx ...\n", addr);     /* Copy header so we can blank CRC field for re-calculation 。。。。crc校验*/ #ifdef CONFIG_HAS_DATAFLASH     if (addr_dataflash(addr)){         read_dataflash(addr, sizeof(image_header_t), (char *)header);     } else #endif     memmove (header, (char *)addr, sizeof(image_header_t));     if (ntohl(hdr-ih_magic) != IH_MAGIC) { #ifdef __I386__    /* correct image format not implemented yet - fake it */         if (fake_header(hdr, (void*)addr, -1) != NULL) {             /* to compensate for the addition below */             addr -= sizeof(image_header_t);             /* turnof verify,              * fake_header() does not fake the data crc              */             verify = 0;         } else              #endif    /* __I386__ */         {         puts ("Bad Magic Number\n");         SHOW_BOOT_PROGRESS (-1);         return 1;         }     }     SHOW_BOOT_PROGRESS (2);     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); #ifdef CONFIG_HAS_DATAFLASH     if (addr_dataflash(addr)){         len  = ntohl(hdr-ih_size) + sizeof(image_header_t);         read_dataflash(addr, len, (char *)CFG_LOAD_ADDR);         addr = CFG_LOAD_ADDR;     } #endif     /* 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);     len_ptr = (ulong *)data; #if defined(__PPC__)     if (hdr-ih_arch != IH_CPU_PPC) #elif defined(__ARM__)//hdr为uimage64字节结构体变量。     if (hdr-ih_arch != IH_CPU_ARM) #elif defined(__I386__)     if (hdr-ih_arch != IH_CPU_I386) #elif defined(__mips__)     if (hdr-ih_arch != IH_CPU_MIPS) #elif defined(__nios__)     if (hdr-ih_arch != IH_CPU_NIOS) #elif defined(__M68K__)     if (hdr-ih_arch != IH_CPU_M68K) #elif defined(__microblaze__)     if (hdr-ih_arch != IH_CPU_MICROBLAZE) #elif defined(__nios2__)     if (hdr-ih_arch != IH_CPU_NIOS2) #elif defined(__blackfin__)     if (hdr-ih_arch != IH_CPU_BLACKFIN) #elif defined(__avr32__)     if (hdr-ih_arch != IH_CPU_AVR32) #else # error Unknown CPU type #endif     {         printf ("Unsupported Architecture 0x%x\n", hdr-ih_arch);         SHOW_BOOT_PROGRESS (-4);         return 1;     }     SHOW_BOOT_PROGRESS (5); //判断文件类型 此处应该为kernel 各种类型在includ/image.h中有解释 。     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 , NULL, 16));         }         break;     case IH_TYPE_KERNEL://kernel         name = "Kernel Image";         break;     case IH_TYPE_MULTI:         name = "Multi-File Image";         len  = ntohl(len_ptr );         /* OS kernel is always the first image */         data += 8; /* kernel_len + terminator */         for (i=1; len_ptr ; ++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...      */     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 (hdr-ih_comp) {     case IH_COMP_NONE:         if(ntohl(hdr-ih_load) == addr) {             printf ("   XIP %s ... ", name);         } else { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)             size_t l = len;             void *to = (void *)ntohl(hdr-ih_load);             void *from = (void *)data;             printf ("   Loading %s ... ", name);             while (l 0) {                 size_t tail = (l CHUNKSZ) ? CHUNKSZ : l;                 WATCHDOG_RESET();                 memmove (to, from, tail);                 to += tail;                 from += tail;                 l -= tail;             } #else    /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */             memmove ((void *) ntohl(hdr-ih_load), (uchar *)data, len); #endif    /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */         }         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; #ifdef CONFIG_BZIP2     case IH_COMP_BZIP2:         printf ("   Uncompressing %s ... ", name);         /*          * If we've got less than 4 MB of malloc() space,          * use slower decompression algorithm which requires          * at most 2300 KB of memory.          */         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 recover\n", 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 %d\n", hdr-ih_comp);         SHOW_BOOT_PROGRESS (-7);         return 1;     }     puts ("OK\n");     SHOW_BOOT_PROGRESS (7);     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 ;             sprintf(buf, "%lX", len);             setenv("filesize", buf);             return 0;         }         appl = (int (*)(int, char * );         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); //判断操作系统 有linux vxworks等然后跳转到对应的执行函数中去     switch (hdr-ih_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,                  addr, len_ptr, verify);//这个函数在lib_arm/中的armlinux.c中         break;     case IH_OS_NETBSD:         do_bootm_netbsd (cmdtp, flag, argc, argv,                  addr, len_ptr, verify);         break; #ifdef CONFIG_LYNXKDI     case IH_OS_LYNXOS:         do_bootm_lynxkdi (cmdtp, flag, argc, argv,                  addr, len_ptr, verify);         break; #endif     case IH_OS_RTEMS:         do_bootm_rtems (cmdtp, flag, argc, argv,                  addr, len_ptr, verify);         break; #if (CONFIG_COMMANDS CFG_CMD_ELF)     case IH_OS_VXWORKS:         do_bootm_vxworks (cmdtp, flag, argc, argv,                   addr, len_ptr, verify);         break;     case IH_OS_QNX:         do_bootm_qnxelf (cmdtp, flag, argc, argv,                   addr, len_ptr, verify);         break; #endif /* CFG_CMD_ELF */ #ifdef CONFIG_ARTOS     case IH_OS_ARTOS:         do_bootm_artos  (cmdtp, flag, argc, argv,                  addr, len_ptr, verify);         break; #endif     }     SHOW_BOOT_PROGRESS (-9); #ifdef DEBUG     puts ("\n## Control returned to monitor - resetting...\n");     do_reset (cmdtp, flag, argc, argv); #endif     return 1; }