U-boot 分析5

来源:互联网 发布:flyme数据同步助手 编辑:程序博客网 时间:2024/06/14 21:34

接下来就进入命令行了,u-boot有好多命令,它们的运行又牵扯到一堆东西。

挑几个觉得会用到的命令看看

1. bootm

<common/cmd_bootm.c>

    987 U_BOOT_CMD(

    988     bootm,  CONFIG_SYS_MAXARGS, 1,  do_bootm,

    989     "boot application image from memory",

    990     "[addr [arg ...]]\n    - boot application image stored in memory\n"

    991     "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"

    992     "\t'arg' can be the address of an initrd image\n"

    993 #if defined(CONFIG_OF_LIBFDT)

    994     "\tWhen booting a Linux kernel which requires a flat device-tree\n"

    995     "\ta third argument is required which is the address of the\n"

    996     "\tdevice-tree blob. To boot that kernel without an initrd image,\n"

    997     "\tuse a '-' for the second argument. If you do not pass a third\n"

    998     "\ta bd_info struct will be passed instead\n"

    999 #endif

   1000 #if defined(CONFIG_FIT)

   1001     "\t\nFor the new multi component uImage format (FIT) addresses\n"

   1002     "\tmust be extened to include component or configuration unit name:\n"

   1003     "\taddr:<subimg_uname> - direct component image specification\n"

   1004     "\taddr#<conf_uname>   - configuration specification\n"

   1005     "\tUse iminfo command to get the list of existing component\n"

   1006     "\timages and configurations.\n"

   1007 #endif

   1008     "\nSub-commands to do part of the bootm sequence.  The sub-commands "

   1009     "must be\n"

   1010     "issued in the order below (it's ok to not issue all sub-commands):\n"

   1011     "\tstart [addr [arg ...]]\n"

   1012     "\tloados  - load OS image\n"

   1013 #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)

   1014     "\tramdisk - relocate initrd, set env initrd_start/initrd_end\n"

   1015 #endif

   1016 #if defined(CONFIG_OF_LIBFDT)

   1017     "\tfdt     - relocate flat device tree\n"

   1018 #endif

   1019     "\tcmdline - OS specific command line processing/setup\n"

   1020     "\tbdt     - OS specific bd_t processing\n"

   1021     "\tprep    - OS specific prep before relocation or go\n"

   1022     "\tgo      - start OS"

   1023 );

         bootm运行的函数是do_bootm()

    584 int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

    585 {

    586     ulong       iflag;

    587     ulong       load_end = 0;

    588     int     ret;

589     boot_os_fn  *boot_fn;

    590 #ifndef CONFIG_RELOC_FIXUP_WORKS

    591     static int relocated = 0;

    593    

    594     if (!relocated) {

    595         int i;

    596         for (i = 0; i < ARRAY_SIZE(boot_os); i++)

    597             if (boot_os[i] != NULL)

    598                 boot_os[i] += gd->reloc_off;

    599         relocated = 1;

    600     }  

    601 #endif  

    603    

    604     if (argc > 1) {

    605         char *endp;

    607         simple_strtoul(argv[1], &endp, 16);

    608        

    616         if ((*endp != 0) && (*endp != ':') && (*endp != '#'))

    617             return do_bootm_subcommand(cmdtp, flag, argc, argv);

    618     }

620     if (bootm_start(cmdtp, flag, argc, argv))

    621         return 1;

    623    

    628     iflag = disable_interrupts();

    630 #if defined(CONFIG_CMD_USB)

    631    

    640     usb_stop();

    641 #endif

    643 #ifdef CONFIG_AMIGAONEG3SE

    644    

    648     icache_disable();

    649     dcache_disable();

    650 #endif

    652     ret = bootm_load_os(images.os, &load_end, 1);

    654     if (ret < 0) {

    655         if (ret == BOOTM_ERR_RESET)

    656             do_reset (cmdtp, flag, argc, argv);

    657         if (ret == BOOTM_ERR_OVERLAP) {

    658             if (images.legacy_hdr_valid) {

    659                 if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)

    660                     puts ("WARNING: legacy format multi component "

    661                         "image overwritten\n");

    662             } else {

    663                 puts ("ERROR: new format image overwritten - "

    664                     "must RESET the board to recover\n");

    665                 show_boot_progress (-113);

    666                 do_reset (cmdtp, flag, argc, argv);

    667             }

    668         }

    669         if (ret == BOOTM_ERR_UNIMPLEMENTED) {

    670             if (iflag)

    671                 enable_interrupts();

    672             show_boot_progress (-7);

    673             return 1;

    674         }

    675     }

    677     lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));

    679     if (images.os.type == IH_TYPE_STANDALONE) {

    680         if (iflag)

    681             enable_interrupts();

    682        

    683         bootm_start_standalone(iflag, argc, argv);

    684         return 0;

    685     }

    687     show_boot_progress (8);

    689 #ifdef CONFIG_SILENT_CONSOLE

    690     if (images.os.os == IH_OS_LINUX)

    691         fixup_silent_linux();

    692 #endif

    694     boot_fn = boot_os[images.os.os];

    696     if (boot_fn == NULL) {

    697         if (iflag)

    698             enable_interrupts();

    699         printf ("ERROR: booting os '%s' (%d) is not supported\n",

    700             genimg_get_os_name(images.os.os), images.os.os);

    701         show_boot_progress (-8);

    702         return 1;

    703     }

    705     arch_preboot_os();

    707     boot_fn(0, argc, argv, &images);

    709     show_boot_progress (-9);

    710 #ifdef DEBUG

    711     puts ("\n## Control returned to monitor - resetting...\n");

    712 #endif

    713     do_reset (cmdtp, flag, argc, argv);

    715     return 1;

    716 }

typedef int boot_os_fn (int flag, int argc, char *argv[],  bootm_headers_t *images);

typedef struct bootm_headers {

        

         image_header_t      *legacy_hdr_os;               

         image_header_t      legacy_hdr_os_copy;      

         ulong                  legacy_hdr_valid;

#if defined(CONFIG_FIT)

         const char        *fit_uname_cfg;     

         void           *fit_hdr_os;    

         const char        *fit_uname_os;       

         int              fit_noffset_os;         

         void           *fit_hdr_rd;    

         const char        *fit_uname_rd;       

         int              fit_noffset_rd;

         void           *fit_hdr_fdt;   

         const char        *fit_uname_fdt;      

         int              fit_noffset_fdt;

#endif

#ifndef USE_HOSTCC

         image_info_t   os;            

         ulong                  ep;            

         ulong                  rd_start, rd_end;

#ifdef CONFIG_OF_LIBFDT

         char          *ft_addr;

#endif

         ulong                  ft_len;               

         ulong                  initrd_start;

         ulong                  initrd_end;

         ulong                  cmdline_start;

         ulong                  cmdline_end;

         bd_t          *kbd;

#endif

         int              verify;               

#define     BOOTM_STATE_START    (0x00000001)

#define     BOOTM_STATE_LOADOS          (0x00000002)

#define     BOOTM_STATE_RAMDISK       (0x00000004)

#define     BOOTM_STATE_FDT                  (0x00000008)

#define     BOOTM_STATE_OS_CMDLINE         (0x00000010)

#define     BOOTM_STATE_OS_BD_T        (0x00000020)

#define     BOOTM_STATE_OS_PREP        (0x00000040)

#define     BOOTM_STATE_OS_GO   (0x00000080)

         int              state;

#ifdef CONFIG_LMB

         struct lmb         lmb;         

#endif

} bootm_headers_t;

590-601

boot_os[]定义如下

static boot_os_fn *boot_os[],重新定义了relocate后的地址

603-618

481 int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

    482 {

    483     int ret = 0;

    484     int state;

    485     cmd_tbl_t *c;

    486     boot_os_fn *boot_fn;

    488     c = find_cmd_tbl(argv[1], &cmd_bootm_sub[0], ARRAY_SIZE(cmd_bootm_sub));

    490     if (c) {

    491         state = (int)c->cmd;

    493        

    494         if (state == BOOTM_STATE_START) {

    495             argc--;

    496             argv++;

    497             return bootm_start(cmdtp, flag, argc, argv);

    498         }

    499     }

    500    

    501     else {

    502         cmd_usage(cmdtp);

    503         return 1;

    504     }

    506     if (images.state >= state) {

    507         printf ("Trying to execute a command out of order\n");

    508         cmd_usage(cmdtp);

    509         return 1;

    510     }

    512     images.state |= state;

    513     boot_fn = boot_os[images.os.os];

    515     switch (state) {

    516         ulong load_end;

    517         case BOOTM_STATE_START:

    518            

    519             break;

    520         case BOOTM_STATE_LOADOS:

    521             ret = bootm_load_os(images.os, &load_end, 0);

    522             if (ret)

    523                 return ret;

    525             lmb_reserve(&images.lmb, images.os.load,

    526                     (load_end - images.os.load));

    527             break;

    528 #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)

    529         case BOOTM_STATE_RAMDISK:

    530         {

    531             ulong rd_len = images.rd_end - images.rd_start;

    532             char str[17];

    534             ret = boot_ramdisk_high(&images.lmb, images.rd_start,

    535                 rd_len, &images.initrd_start, &images.initrd_end);

    536             if (ret)

    537                 return ret;

    539             sprintf(str, "%lx", images.initrd_start);

    540             setenv("initrd_start", str);

    541             sprintf(str, "%lx", images.initrd_end);

    542             setenv("initrd_end", str);

    543         }

    544             break;

    545 #endif

    546 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ)

    547         case BOOTM_STATE_FDT:

    548         {

    549             ulong bootmap_base = getenv_bootm_low();

    550             ret = boot_relocate_fdt(&images.lmb, bootmap_base,

    551                 &images.ft_addr, &images.ft_len);

    552             break;

    553         }  

    554 #endif     

    555         case BOOTM_STATE_OS_CMDLINE:

    556             ret = boot_fn(BOOTM_STATE_OS_CMDLINE, argc, argv, &images);

    557             if (ret)

    558                 printf ("cmdline subcommand not supported\n");

    559             break;

    560         case BOOTM_STATE_OS_BD_T:

    561             ret = boot_fn(BOOTM_STATE_OS_BD_T, argc, argv, &images);

    562             if (ret)

    563                 printf ("bdt subcommand not supported\n");

    564             break;

    565         case BOOTM_STATE_OS_PREP:

    566             ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, &images);

    567             if (ret)

    568                 printf ("prep subcommand not supported\n");

    569             break;

    570         case BOOTM_STATE_OS_GO:

    571             disable_interrupts();

    572             arch_preboot_os();

    573             boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images);

    574             break;

    575     }

    577     return ret;

578 }

好复杂

488

          cmd_tbl_t cmd_bootm_sub[] = {

          U_BOOT_CMD_MKENT(start, 0, 1, (void *)BOOTM_STATE_START, "", ""),

          U_BOOT_CMD_MKENT(loados, 0, 1, (void *)BOOTM_STATE_LOADOS, "", ""),

#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)

          U_BOOT_CMD_MKENT(ramdisk, 0, 1, (void *)BOOTM_STATE_RAMDISK, "", ""),

#endif

#ifdef CONFIG_OF_LIBFDT

          U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)BOOTM_STATE_FDT, "", ""),

#endif

          U_BOOT_CMD_MKENT(cmdline, 0, 1, (void *)BOOTM_STATE_OS_CMDLINE, "", ""),

          U_BOOT_CMD_MKENT(bdt, 0, 1, (void *)BOOTM_STATE_OS_BD_T, "", ""),

          U_BOOT_CMD_MKENT(prep, 0, 1, (void *)BOOTM_STATE_OS_PREP, "", ""),

          U_BOOT_CMD_MKENT(go, 0, 1, (void *)BOOTM_STATE_OS_GO, "", ""),

};

看来能跟在后面的命令有上面几个,这个函数就是要找到匹配的。

#define     BOOTM_STATE_START    (0x00000001)

#define     BOOTM_STATE_LOADOS          (0x00000002)

#define     BOOTM_STATE_RAMDISK       (0x00000004)

#define     BOOTM_STATE_FDT                  (0x00000008)

#define     BOOTM_STATE_OS_CMDLINE         (0x00000010)

#define     BOOTM_STATE_OS_BD_T        (0x00000020)

#define     BOOTM_STATE_OS_PREP        (0x00000040)

#define     BOOTM_STATE_OS_GO   (0x00000080)

490-499

         太长了,不能贴代码了,不然看得人完全看不下去。

         还是用调用关系来说明吧

620行开始

         bootm_start()

                   è bootm_start_lmb()

                            è lmb_init(&images.lmb)

                                     :: 初始化lmb->memory动态可分配内存

                                     :: 初始化lmb->reserved 保留内存空间

                            è getenv_bootm_low()

                                     :: dram start

                            è getenv_bootm_size()

                                     :: dram size

                            è lmb_add()

                                     :: mem_startmem_size区域加入lmb

                                     è lmb_add_region(_rgn, base, size)

                                               :: lmb->memory->region[]赋值,定义内存空间

                                               è lmb_addrs_adjacent(base,size,rgnbase,rgnsize)

                                                        :: 检查内存空间是否可以合并

                                               è lmb_regions_adjacent()

                                                        :: 检查相邻的区域是否可以合并

                                              è lmb_coalesce_regions()

                                                        :: 进行合并操作,向后扩张的方式

                                                        è lmb_remove_region()

                                                                 :: 区域的坐标全向后移

                            è arch_lmb_reserve()

                                     :: arch相关需要保留的内存区域

                            è board_lmb_reserve()

                                     :: 板子相关需要保留的内存区域

                   è boot_get_kernel()

                            :: find kernel image

                            è genimg_get_image()

                                     :: 如果数据在flash中,就把数据从flash中拷贝到内存中

                            è genimg_get_format()

                                     :: img文件中获取格式

                            è image_get_kernel()

                                     :: 注意结构体struct image_header

                                     è image_check_magic()

                                               :: 检查头部幻数,确定类型

                                     è image_check_hcrc()

                                               :: 检查头部CRC

                                     è image_check_dcrc()

                                               :: 检查数据CRC

                                     è image_check_target_arch()

                                               :: 校验img和处理器的类型是否匹配

                   è genimg_get_format()

                            :: 赋值os.type os.comp os.os os.end os.load,这些信息都是记录在hdr

                   è boot_get_ramdisk()

                            :: 同获取kernel文件差不多,获取ramdisk文件

 

do_bootm()

         è bootm_start()

                   :: add memory region and get kernel and ramdisk header

         è disable_interrupts()

                   :: disable interrupts

         è bootm_load_os()

                   :: use memmove_wd() copy img to memory, if the img is compress file, uncompress it to memory

         è lmb_reserve()

                   :: reserve the memory region where img file is

         è enable_interrupts()

                   :: enable interrupts

         è bootm_start_standalone()

                   :: go to the img file entry point, and run

         è arch_preboot_os()

                   :: save regs you want

         è do_bootm_linux()

                   :: it is boot_fn()

                   è getenv()

                            :: get env bootargs

                   :: add other tags

                   è cleanup_before_linux()

                            :: prepare for run linux

                            è disable_interrupts()

                                     :: disable interrupts

                            è icache_disable()

                                     :: disable icache

                            è dcache_disable()

                                     :: disable dcache

                            è cache_flush()

                                     :: flush cache

                   è entry_point()

                            :: go to img file entry point and run

0 0
原创粉丝点击