uboot 启动Linux内核使用bootz命令。当然还有其它的启动命令,例如,bootm命令等等。
本文只分析 bootz命令启动 Linux内核的过程中涉及的几个重要函数。具体分析 do_bootm_states 函数执行过程。
本文继上一篇文章,地址如下:
bootz启动 Linux内核过程中涉及的 bootz_start 函数-CSDN博客
bootz 命令的执行函数为 do_bootz函数。而 do_bootz函数主要调用如下函数:
bootz_start 函数,bootm_disable_interrupts 函数,设置 images.os.os ,do_bootm_states 函数。
- BOOTM_STATE_OS_PREP
- BOOTM_STATE_OS_FAKE_GO
- BOOTM_STATE_OS_GO
- BOOTM_STATE_START
- int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
- int states, bootm_headers_t *images, int boot_progress)
- {
- boot_os_fn *boot_fn;
- ulong iflag = 0;
- int ret = 0, need_boot_fn;
-
- images->state |= states;
- ............
- /* From now on, we need the OS boot function */
- if (ret)
- return ret;
- boot_fn = bootm_os_get_boot_func(images->os.os);
- need_boot_fn = states & (BOOTM_STATE_OS_CMDLINE |
- BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
- BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
- if (boot_fn == NULL && need_boot_fn) {
- if (iflag)
- enable_interrupts();
- printf("ERROR: booting os '%s' (%d) is not supported\n",
- genimg_get_os_name(images->os.os), images->os.os);
- bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
- return 1;
- }
- ............
- if (!ret && (states & BOOTM_STATE_OS_PREP))
- ret = boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images);
-
- #ifdef CONFIG_TRACE
- /* Pretend to run the OS, then run a user command */
- if (!ret && (states & BOOTM_STATE_OS_FAKE_GO)) {
- char *cmd_list = getenv("fakegocmd");
-
- ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_FAKE_GO,
- images, boot_fn);
- if (!ret && cmd_list)
- ret = run_command_list(cmd_list, -1, flag);
- }
- #endif
-
- /* Check for unsupported subcommand. */
- if (ret) {
- puts("subcommand not supported\n");
- return ret;
- }
-
- /* Now run the OS! We hope this do not return */
- if (!ret && (states & BOOTM_STATE_OS_GO))
- ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
- images, boot_fn);
-
- .............
- return ret;
- }
- int boot_selected_os(int argc, char * const argv[], int state, bootm_headers_t *images, boot_os_fn *boot_fn)
- {
- arch_preboot_os();
- boot_fn(state, argc, argv, images);
-
- /* Stand-alone may return when 'autostart' is 'no' */
- if (images->os.type == IH_TYPE_STANDALONE ||
- state == BOOTM_STATE_OS_FAKE_GO) /* We expect to return */
- return 0;
- bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
- #ifdef DEBUG
- puts("\n## Control returned to monitor - resetting...\n");
- #endif
- return BOOTM_ERR_RESET;
- }
do_bootm_linux 函数简化代码如下,这里只列出此处会执行到代码:
- int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
- int states, bootm_headers_t *images, int boot_progress)
- {
- boot_os_fn *boot_fn;
- ulong iflag = 0;
- int ret = 0, need_boot_fn;
-
- images->state |= states;
- .............
-
- if (!ret && (states & BOOTM_STATE_OS_GO))
- ret = boot_selected_os(argc, argv, BOOTM_STATE_OS_GO,
- images, boot_fn);
- .............
- return ret;
- }