tag 标签: bootm_linux

相关博文
  • 热度 22
    2013-9-6 22:19
    1946 次阅读|
    0 个评论
    /*这个函数进入linux内核 留个比较 有问题还望指正 */ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv , NULL, 16);         printf ("## Loading Ramdisk Image at %08lx ...\n", addr);         /* Copy header so we can blank CRC field for re-calculation 应该是atmel公司定义的一种flash         接着下面一堆代码都是校验 拷贝内存 什么的 移植也不用看  */ #ifdef CONFIG_HAS_DATAFLASH         if (addr_dataflash (addr)) {             read_dataflash (addr, sizeof (image_header_t),                     (char *) header);         } else #endif             memcpy (header, (char *) addr,                 sizeof (image_header_t));         if (ntohl (hdr-ih_magic) != IH_MAGIC) {             printf ("Bad Magic Number\n");             SHOW_BOOT_PROGRESS (-10);             do_reset (cmdtp, flag, argc, argv);         }         data = (ulong) header;         len = sizeof (image_header_t);         checksum = ntohl (hdr-ih_hcrc);         hdr-ih_hcrc = 0;         if (crc32 (0, (unsigned char *) data, len) != checksum) {             printf ("Bad Header Checksum\n");             SHOW_BOOT_PROGRESS (-11);             do_reset (cmdtp, flag, argc, argv);         }         SHOW_BOOT_PROGRESS (10);         print_image_hdr (hdr);         data = addr + sizeof (image_header_t);         len = ntohl (hdr-ih_size); #ifdef CONFIG_HAS_DATAFLASH         if (addr_dataflash (addr)) {             read_dataflash (data, len, (char *) CFG_LOAD_ADDR);             data = CFG_LOAD_ADDR;         } #endif         if (verify) {             ulong csum = 0;             printf ("   Verifying Checksum ... ");             csum = crc32 (0, (unsigned char *) data, len);             if (csum != ntohl (hdr-ih_dcrc)) {                 printf ("Bad Data CRC\n");                 SHOW_BOOT_PROGRESS (-12);                 do_reset (cmdtp, flag, argc, argv);             }             printf ("OK\n");         }         SHOW_BOOT_PROGRESS (11);         if ((hdr-ih_os != IH_OS_LINUX) ||             (hdr-ih_arch != IH_CPU_ARM) ||             (hdr-ih_type != IH_TYPE_RAMDISK)) {             printf ("No Linux ARM Ramdisk Image\n");             SHOW_BOOT_PROGRESS (-13);             do_reset (cmdtp, flag, argc, argv);         } #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)         /*          *we need to copy the ramdisk to SRAM to let Linux boot          */         memmove ((void *) ntohl(hdr-ih_load), (uchar *)data, len);         data = ntohl(hdr-ih_load); #endif /* CONFIG_B2 || CONFIG_EVB4510 */         /*          * Now check if we have a multifile image          */     } else if ((hdr-ih_type == IH_TYPE_MULTI) (len_ptr )) {         ulong tail = ntohl (len_ptr ) % 4;         int i;         SHOW_BOOT_PROGRESS (13);         /* skip kernel length and terminator */         data = (ulong) (len_ptr );         /* skip any additional image length fields */         for (i = 1; len_ptr ; ++i)             data += 4;         /* add kernel length, and align */         data += ntohl (len_ptr );         if (tail) {             data += 4 - tail;         }         len = ntohl (len_ptr );     } else {         /*          * no initrd image          */         SHOW_BOOT_PROGRESS (14);         len = data = 0;     } #ifdef    DEBUG     if (!data) {         printf ("No initrd\n");     } #endif     if (data) {         initrd_start = data;         initrd_end = initrd_start + len;     } else {         initrd_start = 0;         initrd_end = 0;     }     SHOW_BOOT_PROGRESS (15);     debug ("## Transferring control to Linux (at address %08lx) ...\n",            (ulong) theKernel); //下面根据定义 对tag结构体进行赋值。 #if defined (CONFIG_SETUP_MEMORY_TAGS) || \     defined (CONFIG_CMDLINE_TAG) || \     defined (CONFIG_INITRD_TAG) || \     defined (CONFIG_SERIAL_TAG) || \     defined (CONFIG_REVISION_TAG) || \     defined (CONFIG_LCD) || \     defined (CONFIG_VFD)     setup_start_tag (bd);//先设置start tag,然后把params这个指针指向下一个tag的首地址, #ifdef CONFIG_SERIAL_TAG     setup_serial_tag (¶ms); #endif #ifdef CONFIG_REVISION_TAG     setup_revision_tag (¶ms); #endif #ifdef CONFIG_SETUP_MEMORY_TAGS     setup_memory_tags (bd); #endif #ifdef CONFIG_CMDLINE_TAG     setup_commandline_tag (bd, commandline); #endif #ifdef CONFIG_INITRD_TAG     if (initrd_start initrd_end)         setup_initrd_tag (bd, initrd_start, initrd_end); #endif #if defined (CONFIG_VFD) || defined (CONFIG_LCD)     setup_videolfb_tag ((gd_t *) gd); #endif     setup_end_tag (bd); #endif     /* we assume that the kernel is in place */     printf ("\nStarting kernel ...\n\n"); #ifdef CONFIG_USB_DEVICE     {         extern void udc_disconnect (void);         udc_disconnect ();     } #endif     cleanup_before_linux ();//为linux引导做一些准备工作     theKernel (0, bd-bi_arch_number, bd-bi_boot_params);     //这句话来引导内核,bd-bi_arch_number指向机器类型ID,这个ID在board_init函数中设置。bd-bi_boot_params     //指向的是tag的标记的起始地址。 这三个变量分别存在r0,r1,r2中给了linux。 }