因为我们这款cpu指令集是armv7的所以选择这个目录下的start.s,如果不知道自己该看那个目录下的start.s,可以用如下方法
先编译uboot,编译成功后,执行 find -name start.0 即可看见start文件所在目录
然后我们来看看代码,我对代码进行了删减,我们目的在于流程分析,就不分析具体每句话了
reset:
/* Allow the board to save important registers */
b save_boot_params
save_boot_params_ret:
/*
* disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
* except ifin HYP mode already
*/
。。。。。。。。
/*
* Setup vector:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
* Continue touse ROM code vector only in OMAP4 spl)
*/
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
/* Set V=0in CP15 SCTLR register - for VBAR to point to vector */
。。。。。。。。。
/* Set vector address in CP15 VBAR register */
。。。。。。。。。
#endif
/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15
bl cpu_init_crit
#endif
bl _main //进入_main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
archarmlibcrt0.S _main在这个文件里
ENTRY(_main)
/*
* Set up initial C runtime environment and call board_init_f(0).
*/#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
ldr sp, =(CONFIG_SPL_STACK)
#else
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
。。。。。。。
clr_gd:
。。。。。。。
#if defined(CONFIG_SYS_MALLOC_F_LEN)sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN
str sp, [r9, #GD_MALLOC_BASE]#endif/* mov r0, #0 not needed due to above code */
bl board_init_f /*这个函数把uboot拷贝到ram*/#if ! defined(CONFIG_SPL_BUILD)/*
* Set up intermediate environment (new sp and gd) and call
* relocate_code(addr_moni). Trick here is that we'll return
* 'here' but relocated.
*/
。。。。。。
b relocate_code
here:/*
* now relocate vectors
*/
bl relocate_vectors
/* Set up final (full) environment */
bl c_runtime_cpu_setup /* we still call old routine here */#endif#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)# ifdef CONFIG_SPL_BUILD/* Use a DRAM stack for the rest of SPL, if requested */
bl spl_relocate_stack_gd
cmp r0, #0
movne sp, r0# endif
ldr r0, =__bss_start /* this is auto-relocated! */#ifdef CONFIG_USE_ARCH_MEMSET
ldr r3, =__bss_end /* this is auto-relocated! */movr1, #0x00000000 /* prepare zero to clear BSS */
subs r2, r3, r0/* r2 = memset len */
bl memset
#else
ldr r1, =__bss_end /* this is auto-relocated! */movr2, #0x00000000 /* prepare zero to clear BSS */clbss_l:cmp r0, r1/* while not at end of BSS */
strlo r2, [r0] /* clear 32-bit BSS word */
addlo r0, r0, #4 /* move to next */
blo clbss_l
#endif#if ! defined(CONFIG_SPL_BUILD)
bl coloured_LED_init
bl red_led_on
#endif/* call board_init_r(gd_t *id, ulong dest_addr) */movr0, r9/* gd_t */
ldr r1, [r9, #GD_RELOCADDR] /* dest_addr *//* call board_init_r */
ldr pc, =board_init_r /* this is auto-relocated! *//* we should not return here. */#endif
ENDPROC(_main)
我们来看看这个init_sequence_r 为了更加清晰的看到他的流程,我删减了一部分代码
init_fnc_t init_sequence_r[] = {
initr_trace,
initr_reloc,
/* TODO: could x86/PPC have this also perhaps? */#ifdef CONFIG_ARM
initr_caches,
#endif
initr_reloc_global_data,
。。。。。。。
board_init, /* Setup chipselects */#endif/*
* TODO: printing of the clock inforamtion of the board is now
* implemented as part of bdinfo command. Currently only support for
* davinci SOC's is added. Remove this check once all the board
* implement this.
*/
。。。。。。。。
INIT_FUNC_WATCHDOG_RESET
#ifdef CONFIG_SYS_DELAYED_ICACHE
initr_icache_enable,
#endif#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)/*
* Do early PCI configuration _before_ the flash gets initialised,
* because PCU ressources are crucial for flash access on some boards.
*/
initr_pci,
#endif
。。。。。。。
#ifdef CONFIG_ARCH_MISC_INIT
arch_misc_init, /* miscellaneous arch-dependent init */#endif#ifdef CONFIG_MISC_INIT_R
misc_init_r, /* miscellaneous platform-dependent init */#endif
INIT_FUNC_WATCHDOG_RESET
。。。。。。。
#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_AVR32)
|| defined(CONFIG_M68K)
timer_init, /* initialize timer */#endif
INIT_FUNC_WATCHDOG_RESET
/*
* Some parts can be only initialized if all others (like
* Interrupts) are up and running (i.e. the PC-style ISA
* keyboard).
*/
last_stage_init,
#endif#ifdef CONFIG_CMD_BEDBUG
INIT_FUNC_WATCHDOG_RESET
initr_bedbug,
#endif#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
initr_mem,
#endif#ifdef CONFIG_PS2KBD
initr_kbd,
#endif#ifdef CONFIG_FSL_FASTBOOT
initr_check_fastboot,
#endif
run_main_loop,
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
这里满足宏条件的函数都会被执行,最后一个执行的函数是run_main_loop,我继续追踪下去,这个函数 还是在这个文件中board_r.c
staticint run_main_loop(void)
{
#ifdef CONFIG_SANDBOX
sandbox_main_loop_init();
#endif/* main_loop() can return to retry autoboot, if so just run it again */for (;;) //死循环
main_loop();
return0;
}
1
2
3
4
5
6
7
8
9
10
可以看见,这里是单向的,调用了run_main_loop就不会返回了,我们继续看看main_loop();
commonmain.c
/* We come here after U-Boot is initialised and ready to process commands */void main_loop(void)
{
constchar *s;
。。。。。。。。。
puts("#test!!!!!!!!!!!!!!!!!!!!!!!
");
modem_init();
#ifdef CONFIG_VERSION_VARIABLE
setenv("ver", version_string); /* set version variable */#endif /* CONFIG_VERSION_VARIABLE */
cli_init();
run_preboot_environment_command();
#if defined(CONFIG_UPDATE_TFTP)
update_tftp(0UL);
#endif /* CONFIG_UPDATE_TFTP */
s = bootdelay_process(); //uboot读秒,等待用户按键if (cli_process_fdt(&s))
cli_secure_boot_cmd(s);
printf("flag2");
autoboot_command(s); //用户没有按键,执行环境参数命令
cli_loop();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
我们 继续进入到 autoboot_command(s);
void autoboot_command(constchar *s)
{
debug("### main_loop: bootcmd="%s"
", s ? s : "");
if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) {
#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)int prev = disable_ctrlc(1); /* disable Control C checking */#endif
run_command_list(s, -1, 0); //传递过来的命令流s会在这里被解析执行#if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC)
disable_ctrlc(prev); /* restore Control C checking */#endif
}
#ifdef CONFIG_MENUKEYif (menukey == CONFIG_MENUKEY) {
s = getenv("menucmd");
if (s)
run_command_list(s, -1, 0);
}
#endif /* CONFIG_MENUKEY */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
对于命令的解析执行,我们追踪 run_command_list(s, -1, 0);来分析分析
int run_command_list(constchar *cmd, int len, int flag)
{
int need_buff = 1;
char *buff = (char *)cmd; /* cast away const */int rcode = 0;
if (len == -1) {
len = strlen(cmd);
#ifdef CONFIG_SYS_HUSH_PARSER/* hush will never change our string */
need_buff = 0;
#else/* the built-in parser will change our string if it sees
*/
need_buff = strchr(cmd, '
') != NULL;
#endif
}
if (need_buff) {
buff = malloc(len + 1);
if (!buff)
return1;
memcpy(buff, cmd, len);
buff[len] = '