bootm内核的启动

来源:互联网 发布:比价网站源码整站程序 编辑:程序博客网 时间:2024/04/29 03:19

在U-Boot源码阅读(六)大佬的命令这篇文章中,知道了内核的启动是通过命令nand read.i c0008000 80000 500000;bootm c0008000,先把flash的数据读到内存中,然后执行这段内存的命令。看上去bootm和go还是很相近的嘛。但是go仅仅是开始执行而已,并没做任何的操作。而内核的启动需要满足下列条件:

(1)CPU 寄存器的设置。
? R0=0。
? R1=机器类型ID;对于ARM 结构的CPU,其机器类型ID 可以参见linux/arch/arm/tools/mach-types。
? R2=启动参数标记列表在RAM 中起始基地址。
(2)CPU 工作模式。
? 必须禁止中断(IRQs 和FIQs)。
? CPU 必须为SVC 模式。
(3)Cache 和MMU 的设置。
? MMU 必须关闭。
? 指令Cache 可以打开也可以关闭。
? 数据Cache 必须关闭。

bootm命令:

  1. int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  
  2. {  
  3.     ulong   iflag;  
  4.     ulong   addr;  
  5.     ulong   data, len, checksum;  
  6.     ulong  *len_ptr = NULL; /* not to make warning. by scsuh */  
  7.     uint    unc_len = CFG_BOOTM_LEN;  
  8.     int i, verify;  
  9.     char    *name, *s;  
  10.     int (*appl)(intchar *[]);  
  11.     image_header_t *hdr = &header;  
  12.   
  13.     s = getenv ("verify");  
  14.     verify = (s && (*s == 'n')) ? 0 : 1;  
  15.   
  16.     if (argc < 2) {  
  17.         addr = load_addr;  
  18.     } else {  
  19.         addr = simple_strtoul(argv[1], NULL, 16);  
  20.     }  
  21.   
  22. #ifdef CONFIG_ZIMAGE_BOOT   
  23. #define LINUX_ZIMAGE_MAGIC  0x016f2818   
  24.     if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) {  
  25.         printf("Boot with zImage\n");  
  26.         addr = virt_to_phys(addr);  
  27.         hdr->ih_os = IH_OS_LINUX;  
  28.         hdr->ih_ep = ntohl(addr);  
  29.         goto after_header_check;  
  30.     }  
  31. #endif   
  32.   
  33.     SHOW_BOOT_PROGRESS (1);  
  34.     printf ("## Booting image at %08lx ...\n", addr);  
  35.   
  36.     /* Copy header so we can blank CRC field for re-calculation */  
  37. #ifdef CONFIG_HAS_DATAFLASH   
  38.     if (addr_dataflash(addr)){  
  39.         read_dataflash(addr, sizeof(image_header_t), (char *)&header);  
  40.     } else  
  41. #endif   
  42.     memmove (&header, (char *)addr, sizeof(image_header_t));  
  43.   
  44.     if (ntohl(hdr->ih_magic) != IH_MAGIC) {  
  45. #ifdef __I386__ /* correct image format not implemented yet - fake it */   
  46.         if (fake_header(hdr, (void*)addr, -1) != NULL) {  
  47.             /* to compensate for the addition below */  
  48.             addr -= sizeof(image_header_t);  
  49.             /* turnof verify, 
  50.              * fake_header() does not fake the data crc 
  51.              */  
  52.             verify = 0;  
  53.         } else  
  54. #endif  /* __I386__ */   
  55.         {  
  56. #ifdef CONFIG_IMAGE_BOOT   
  57.         printf("Boot with Image\n");  
  58.         addr = virt_to_phys(addr);  
  59.         hdr->ih_os = IH_OS_LINUX;  
  60.         hdr->ih_ep = ntohl(addr);  
  61.         hdr->ih_comp = IH_COMP_NONE;  
  62.         goto after_header_check;  
  63. #endif   
  64.         puts ("Bad Magic Number\n");  
  65.         SHOW_BOOT_PROGRESS (-1);  
  66.         return 1;  
  67.         }  
  68.     }  
  69.     SHOW_BOOT_PROGRESS (2);  
  70.   
  71.     data = (ulong)&header;  
  72.     len  = sizeof(image_header_t);  
  73.   
  74.     checksum = ntohl(hdr->ih_hcrc);  
  75.     hdr->ih_hcrc = 0;  
  76.   
  77.     if (crc32 (0, (uchar *)data, len) != checksum) {  
  78.         puts ("Bad Header Checksum\n");  
  79.         SHOW_BOOT_PROGRESS (-2);  
  80.         return 1;  
  81.     }  
  82.     SHOW_BOOT_PROGRESS (3);  
  83.   
  84. #ifdef CONFIG_HAS_DATAFLASH   
  85.     if (addr_dataflash(addr)){  
  86.         len  = ntohl(hdr->ih_size) + sizeof(image_header_t);  
  87.         read_dataflash(addr, len, (char *)CFG_LOAD_ADDR);  
  88.         addr = CFG_LOAD_ADDR;  
  89.     }  
  90. #endif   
  91.   
  92.   
  93.     /* for multi-file images we need the data part, too */  
  94.     print_image_hdr ((image_header_t *)addr);  
  95.   
  96.     data = addr + sizeof(image_header_t);  
  97.     len  = ntohl(hdr->ih_size);  
  98.   
  99.     if (verify) {  
  100.         puts ("   Verifying Checksum ... ");  
  101.         if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {  
  102.             printf ("Bad Data CRC\n");  
  103.             SHOW_BOOT_PROGRESS (-3);  
  104.             return 1;  
  105.         }  
  106.         puts ("OK\n");  
  107.     }  
  108.     SHOW_BOOT_PROGRESS (4);  
  109.   
  110.     len_ptr = (ulong *)data;  
  111.   
  112.     SHOW_BOOT_PROGRESS (5);  
  113.   
  114.     switch (hdr->ih_type) {  
  115.     case IH_TYPE_STANDALONE:  
  116.         break;  
  117.     case IH_TYPE_KERNEL:  
  118.         name = "Kernel Image";  
  119.         break;  
  120.     case IH_TYPE_MULTI:  
  121.         break;  
  122.     }  
  123.     SHOW_BOOT_PROGRESS (6);  
  124.   
  125.     /* 
  126.      * We have reached the point of no return: we are going to 
  127.      * overwrite all exception vector code, so we cannot easily 
  128.      * recover from any failures any more... 
  129.      */  
  130.   
  131.     iflag = disable_interrupts();  
  132.   
  133. #ifdef CONFIG_AMIGAONEG3SE   
  134.     /* 
  135.      * We've possible left the caches enabled during 
  136.      * bios emulation, so turn them off again 
  137.      */  
  138.     icache_disable();  
  139.     invalidate_l1_instruction_cache();  
  140.     flush_data_cache();  
  141.     dcache_disable();  
  142. #endif   
  143.   
  144.     switch (hdr->ih_comp) {  
  145.     case IH_COMP_NONE:  
  146.         break;  
  147.     case IH_COMP_GZIP: //这里使用gzip对内核进行压缩   
  148.         printf ("   Uncompressing %s ... ", name);  
  149.         if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,  
  150.                 (uchar *)data, &len) != 0) {  
  151.             puts ("GUNZIP ERROR - must RESET board to recover\n");  
  152.             SHOW_BOOT_PROGRESS (-6);  
  153.             do_reset (cmdtp, flag, argc, argv);  
  154.         }  
  155.         break;  
  156.     }  
  157.     puts ("OK\n");  
  158.     SHOW_BOOT_PROGRESS (7);  
  159.   
  160.     switch (hdr->ih_type) {  
  161.     case IH_TYPE_STANDALONE:  
  162.         return 0;  
  163.     case IH_TYPE_KERNEL:  
  164.     case IH_TYPE_MULTI:  
  165.         /* handled below */  
  166.         break;  
  167.     default:  
  168.         return 1;  
  169.     }  
  170.     SHOW_BOOT_PROGRESS (8);  
  171.   
  172. #if defined(CONFIG_ZIMAGE_BOOT) || defined(CONFIG_IMAGE_BOOT)   
  173. after_header_check:  
  174. #endif   
  175.     switch (hdr->ih_os) {  
  176.     default:            /* handled by (original) Linux case */  
  177.     case IH_OS_LINUX:  
  178. #ifdef CONFIG_SILENT_CONSOLE   
  179.         fixup_silent_linux();  
  180. #endif   
  181.         do_bootm_linux  (cmdtp, flag, argc, argv,  
  182.                  addr, len_ptr, verify);  
  183.         break;  
  184.     }  
  185.   
  186.     SHOW_BOOT_PROGRESS (-9);  
  187.     return 1;  
  188. }  
原创粉丝点击