Chinaunix首页 | 论坛 | 博客
  • 博客访问: 49358
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 147
  • 用 户 组: 普通用户
  • 注册时间: 2014-10-13 14:56
个人简介

待到山花烂漫时,依旧是那些经典在微笑 ~__~

文章分类
文章存档

2015年(17)

2014年(2)

我的朋友

分类: 嵌入式

2015-02-10 16:06:46

内核启动:http://blog.chinaunix.net/uid-26202349-id-4829000.html
     可知道,最终会调用bootm命令。
   点击(此处)折叠或打开

  1. bootcmd=nand read C0008000 600000 400000; nand read 30A00000 B00000 180000; bootm C0008000 30A00000
    从参数bootcmd可知道,启动过程,先从nand中读取内核(先跳过这部分)。然后启动内核,bootm.
   解析common/cmd_bootm.c代码
        ------------------------1.命令定义--------------------        

点击(此处)折叠或打开

  1. U_BOOT_CMD(
  2.     bootm,    CFG_MAXARGS,    1,    do_bootm,
  3.     "bootm - boot application image from memory\n",
  4.     "[addr [arg ...]]\n - boot application image stored in memory\n"
  5.     "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
  6.     "\t'arg' can be the address of an initrd image\n"
  7.         ....
  8. );
    ------------------------------2.内核结构体------------------------------------
    点击(此处)折叠或打开
  1. static bootm_headers_t images;        /* pointers to os/initrd/fdt images */
    ------------------------------3.启动内核函数调用------------------------------------
点击(此处)折叠或打开
  1. int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  2. {
  3.     image_header_t    *hdr;
  4.         //内核头部(含内核的加载地址和内核的入口地址)+真正内核=uImage
  5.     ulong        addr;
  6.     ulong        iflag;
  7.     const char    *type_name;
  8.     uint        unc_len = CFG_BOOTM_LEN;
  9.     uint8_t        comp, type, os;

  10.     void        *os_hdr;
  11.     ulong        os_data, os_len;
  12.     ulong        image_start, image_end;
  13.     ulong        load_start, load_end;
  14.     ulong        mem_start;
  15.     phys_size_t    mem_size;

  16.     struct lmb lmb;
  17.     
  18.     memset ((void *)&images, 0, sizeof (images));
  19.         ..

  20.     mem_start = getenv_bootm_low();
  21.     mem_size = getenv_bootm_size();


  22.     /* 内核处理:get kernel image header, start address and length */
  23.     os_hdr = boot_get_kernel (cmdtp, flag, argc, argv,
  24.             &images, &os_data, &os_len);
  25.     if (os_len == 0) {
  26.         puts ("ERROR: can't get kernel image!\n");
  27.         return 1;
  28.     }

  29.     /* get image parameters */
  30.     switch (genimg_get_format (os_hdr)) {
  31.         ...
  32.     }

  33.     image_start = (ulong)os_hdr;
  34.     load_end = 0;
  35.     type_name = genimg_get_type_name (type);


  36.        //判断压缩格式
  37.     switch (comp) {
  38.     case IH_COMP_NONE:
  39.         if (load_start == (ulong)os_hdr) {
  40.             printf (" XIP %s ... ", type_name);
  41.         } else {
  42.             printf (" Loading %s ... ", type_name);

  43.             memmove_wd ((void *)load_start,
  44.                  (void *)os_data, os_len, CHUNKSZ);
  45.         }
  46.         load_end = load_start + os_len;
  47.         puts("OK\n");
  48.         break;
  49.     case IH_COMP_GZIP:
  50.         printf (" Uncompressing %s ... ", type_name);
  51.         if (gunzip ((void *)load_start, unc_len,
  52.                     (uchar *)os_data, &os_len) != 0) {
  53.             puts ("GUNZIP: uncompress or overwrite error "
  54.                 "- must RESET board to recover\n");
  55.             show_boot_progress (-6);
  56.             do_reset (cmdtp, flag, argc, argv);
  57.         }

  58.         load_end = load_start + os_len;
  59.         break;
  60. #ifdef CONFIG_BZIP2
  61.     case IH_COMP_BZIP2:
  62.         printf (" Uncompressing %s ... ", type_name);
  63.         /*
  64.          * If we've got less than 4 MB of malloc() space,
  65.          * use slower decompression algorithm which requires
  66.          * at most 2300 KB of memory.
  67.          */
  68.         int i = BZ2_bzBuffToBuffDecompress ((char*)load_start,
  69.                     &unc_len, (char *)os_data, os_len,
  70.                     CFG_MALLOC_LEN < (4096 * 1024), 0);
  71.         if (i != BZ_OK) {
  72.             printf ("BUNZIP2: uncompress or overwrite error %d "
  73.                 "- must RESET board to recover\n", i);
  74.             show_boot_progress (-6);
  75.             do_reset (cmdtp, flag, argc, argv);
  76.         }

  77.         load_end = load_start + unc_len;
  78.         break;
  79. #endif /* CONFIG_BZIP2 */
  80.     default:
  81.         if (iflag)
  82.             enable_interrupts();
  83.         printf ("Unimplemented compression type %d\n", comp);
  84.         show_boot_progress (-7);
  85.         return 1;
  86.     }
  87.     puts ("OK\n");
  88.     debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end);
  89.     show_boot_progress (7);

  90.     if ((load_start < image_end) && (load_end > image_start)) {
  91.         debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end);
  92.         debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end);

  93.         if (images.legacy_hdr_valid) {
  94.             if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
  95.                 puts ("WARNING: legacy format multi component "
  96.                     "image overwritten\n");
  97.         } else {
  98.             puts ("ERROR: new format image overwritten - "
  99.                 "must RESET the board to recover\n");
  100.             show_boot_progress (-113);
  101.             do_reset (cmdtp, flag, argc, argv);
  102.         }
  103.     }

  104.     show_boot_progress (8);

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

  106. #if defined(CONFIG_ZIMAGE_BOOT)
  107. after_header_check:
  108.     os = hdr->ih_os;
  109. #endif

  110.         //判断操作系统的类型

  111.     switch (os) {
  112.     default:            /* handled by (original) Linux case */
  113.     case IH_OS_LINUX:
  114. #ifdef CONFIG_SILENT_CONSOLE
  115.      fixup_silent_linux();
  116. #endif
  117.      do_bootm_linux (cmdtp, flag, argc, argv, &images); //如果当前镜像为linux内核,则通过do_bootm_linux进行内核引导
  118.      break;

  119.             ...
  120. }
        --------------4.do_bootm_linux启用------------------------------
击(此处)折叠或打开
  1. void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],bootm_headers_t *images)
  2. {
  3.     ulong    initrd_start, initrd_end;
  4.     ulong    ep = 0;
  5.     bd_t    *bd = gd->bd; //获取bd信息
  6.     char    *s;
  7.     int    machid = bd->bi_arch_number; //获取机器码
  8.     void    (*theKernel)(int zero, int arch, uint params); //定义theKernel启动程序指针,内核运行地址
  9.     int    ret;

  10. #ifdef CONFIG_CMDLINE_TAG
  11.     char *commandline = getenv ("bootargs"); //获取bootargs参数
  12. #endif

  13.     /* find kernel entry point */

  14.     if (images->legacy_hdr_valid) {
  15.         ep = image_get_ep (&images->legacy_hdr_os_copy);

  16.     } else {
  17.         puts ("Could not find kernel entry point!\n");
  18.         goto error;
  19.     }
  20.     theKernel = (void (*)(int, int, uint))ep; //将检索到的内核运行地址入口赋值给theKernel

  21.     s = getenv ("machid"); //获取机器码
  22.     if (s) {
  23.         machid = simple_strtoul (s, NULL, 16);
  24.         printf ("Using machid 0x%x from environment\n", machid);
  25.     }


  26.     cleanup_before_linux (); //为内核启动清空先关资源

  27.     theKernel (0, machid, bd->bi_boot_params); //启动内核,一去不复返
  28.                    r0 r1 r2

  29.     /* does not return */
  30.     return;

  31. error:
  32.     do_reset (cmdtp, flag, argc, argv);
  33.     return;
  34. }
------------------------------------------------------------------------------

## Booting kernel from Legacy Image at 40000000 ...
   Image Name:   Linux-2.6.35.7
   Created:      2013-09-15   7:42:33 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4009840 Bytes =  3.8 MB
   Load Address: 20008000
   Entry Point:  20008000                 //ep值
   Verifying Checksum ... OK

阅读(504) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~