u-boot 启动流程
u-boot 的最终目的:引导内核。
1.设置cpu 为SVR模式
2.关wacthdog
3.关mmu
4.读取内核到内存
5.设置内核启动参数
6.跳转到内核
u-boot-2017.11
参考:arch\arm\lib\crt0_64.S 注释
/*
* This file handles the target-independent stages of the U-Boot
* start-up where a C runtime environment is needed. Its entry point
* is _main and is branched into from the target's start.S file.
*
* _main execution sequence is:
*
* 1. Set up initial environment for calling board_init_f().
* This environment only provides a stack and a place to store
* the GD ('global data') structure, both located in some readily
* available RAM (SRAM, locked cache...). In this context, VARIABLE
* global data, initialized or not (BSS), are UNAVAILABLE; only
* CONSTANT initialized data are available. GD should be zeroed
* before board_init_f() is called.
*
* 2. Call board_init_f(). This function prepares the hardware for
* execution from system RAM (DRAM, DDR...) As system RAM may not
* be available yet, , board_init_f() must use the current GD to
* store any data which must be passed on to later stages. These
* data include the relocation destination, the future stack, and
* the future GD location.
*
* 3. Set up intermediate environment where the stack and GD are the
* ones allocated by board_init_f() in system RAM, but BSS and
* initialized non-const data are still not available.
*
* 4a.For U-Boot proper (not SPL), call relocate_code(). This function
* relocates U-Boot from its current location into the relocation
* destination computed by board_init_f().
*
* 4b.For SPL, board_init_f() just returns (to crt0). There is no
* code relocation in SPL.
*
* 5. Set up final environment for calling board_init_r(). This
* environment has BSS (initialized to 0), initialized non-const
* data (initialized to their intended value), and stack in system
* RAM (for SPL moving the stack and GD into RAM is optional - see
* CONFIG_SPL_STACK_R). GD has retained values set by board_init_f().
*
* TODO: For SPL, implement stack relocation on AArch64.
*
* 6. For U-Boot proper (not SPL), some CPUs have some work left to do
* at this point regarding memory, so call c_runtime_cpu_setup.
*
* 7. Branch to board_init_r().
*
* For more information see 'Board Initialisation Flow in README.
*/
arch\arm\cpu\armv7\start.S
bl _main
arch\arm\lib\crt0_64.S
_main
board_init_r //common/board_r.c
initcall_run_list(init_sequence_r)
initr_trace
run_main_loop
main_loop
autoboot_command(s);
run_command_list(s, -1, 0);
rcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON);
parse_stream_outer(&input, flag)
code = run_list(ctx.list_head);
rcode = run_list_real(pi);
rcode = run_pipe_real(pi);
return cmd_process(flag, child->argc, child->argv,&flag_repeat, NULL);
rc = cmd_call(cmdtp, flag, argc, argv); //调用使用U_BOOT_CMD宏定义的一些函数
/*
U_BOOT_CMD(
bootm, CONFIG_SYS_MAXARGS, 1, do_bootm,
"boot application image from memory", bootm_help_text
);*/
do_bootm()
do_bootm_states()
bootm_find_os()
bootm_load_os()
boot_fn = bootm_os_get_boot_func(images->os.os); //do_bootm_linux
boot_selected_os()
do_bootm_linux()
boot_jump_linux()
kernel_entry(0, machid, r2) //最终进入内核,正常不返回。
内核启动流程
最终目的,挂载根文件系统->执行应用程序
1.head.S -> start_kernel
2.一系列初始化
3.解析u-boot传过来的启动参数
3.打开/dev/console ; dup dup 对应于fd=0,1,2 即stdin stdout stderr等
3.mount_root
4.运行/sbin/init
linux-4.14
head.S
start_kernel
setup_arch(&command_line);
mangle_bootargs(command_line);
setup_command_line(command_line); //处理u-boot传进来的参数
rest_init();
kernel_init
kernel_init_freeable
prepare_namespace
ROOT_DEV = name_to_dev_t(root_device_name);
mount_root();
if (!try_to_run_init_process("/sbin/init") ||
!try_to_run_init_process("/etc/init") ||
!try_to_run_init_process("/bin/init") ||
!try_to_run_init_process("/bin/sh"))
内核根据u-boot 传入的参数来挂载rootfs ,然后启动第一个进程/sbin/init。
后续将分析/sbin/init 进程做了些什么。