- /*******************************************************************/
- /* bootm - boot application image from image in memory */
- /*******************************************************************/
- 引导应用程序在内存中的镜像。
- common/cmd_bootm.c
- int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
- {
- ulong iflag;
- ulong load_end = 0;
- int ret;
- boot_os_fn *boot_fn;
- /* determine if we have a sub command */检查是否有子命令
- if (argc > 1) {
- char *endp;
- simple_strtoul(argv[1], &endp, 16); //调用字符串转无符号整形的函数,endp指向尾字符。
- /* endp pointing to NULL means that argv[1] was just a
- * valid number, pass it along to the normal bootm processing 以空字符结尾则当作是合法的数,作为正常引导的参数
- *
- * If endp is ":" or "#" assume a FIT identifier so pass
- * along for normal processing.
- *
- * Right now we assume the first arg should never be "-"
- */
- if ((*endp != 0) && (*endp != ":") && (*endp != "#")) //是否有子命令。一般不会有,所以这个路径不会执行。
- return do_bootm_subcommand(cmdtp, flag, argc, argv);
- }
- if (bootm_start(cmdtp, flag, argc, argv)) //bootm_start的分析见下一篇文章。这个函数执行成功返回0,失败返回1。这个函数主要用于获取镜像的信息并存入images。
- return 1;
- /*
- * 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();//禁用中断。
- ret = bootm_load_os(images.os, &load_end, 1);//将镜像的数据从images.os.image_start复制到images.os.load 打印:Loading Kernel Image ... OK
- if (ret < 0) {//上个函数调用失败才会进入这个路径
- if (ret == BOOTM_ERR_RESET)
- do_reset (cmdtp, flag, argc, argv);
- if (ret == BOOTM_ERR_OVERLAP) {
- if (images.legacy_hdr_valid) {
- if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI)
- puts ("WARNING: legacy format multi component "
- "image overwritten/n");
- } else {
- puts ("ERROR: new format image overwritten - "
- "must RESET the board to recover/n");
- show_boot_progress (-113);
- do_reset (cmdtp, flag, argc, argv);
- }
- }
- if (ret == BOOTM_ERR_UNIMPLEMENTED) {
- if (iflag)
- enable_interrupts();
- show_boot_progress (-7);
- return 1;
- }
- }
- lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));//由于没有定义CONFIG_LMB,这个函数调用被定义为一个空的宏。
- if (images.os.type == IH_TYPE_STANDALONE) {//处理单独的程序镜像。显然引导内核时不会进入这个路径。
- if (iflag)
- enable_interrupts();
- /* This may return when "autostart" is "no" */
- bootm_start_standalone(iflag, argc, argv);
- return 0;
- }
- show_boot_progress (8);
- boot_fn = boot_os[images.os.os];//根据操作系统的类型获取引导操作系统的函数, boot_os代码如下。
- if (boot_fn == NULL) {
- if (iflag)
- enable_interrupts();
- printf ("ERROR: booting os "%s" (%d) is not supported/n",
- genimg_get_os_name(images.os.os), images.os.os);
- show_boot_progress (-8);
- return 1;
- }
- arch_preboot_os();//禁用中断,重设中断向量
- boot_fn(0, argc, argv, &images);//调用do_bootm_linux,分析在下面。
- show_boot_progress (-9);
- #ifdef DEBUG
- puts ("/n## Control returned to monitor - resetting.../n");
- #endif
- do_reset (cmdtp, flag, argc, argv);
- return 1;
- }
|