.
arch/arm/lib/crt0.S
1 ENTRY(_main)
2
3 /*
4 * Set up initial C runtime environment and call board_init_f(0).
5 */
6
7 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
8 ldr sp, =(CONFIG_SPL_STACK)
9 #else
10 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
11 #endif
12 #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */
13 mov r3, sp
14 bic r3, r3, #7
15 mov sp, r3
16 #else
17 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
18 #endif
19 mov r0, sp
20 bl board_init_f_alloc_reserve
21 mov sp, r0
22 /* set up gd here, outside any C code */
23 mov r9, r0
24 bl board_init_f_init_reserve
25
26 mov r0, #0
27 bl board_init_f
28
29 #if ! defined(CONFIG_SPL_BUILD)
30
31 /*
32 * Set up intermediate environment (new sp and gd) and call
33 * relocate_code(addr_moni). Trick here is that we'll return
34 * 'here' but relocated.
35 */
36
37 ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
38 #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */
39 mov r3, sp
40 bic r3, r3, #7
41 mov sp, r3
42 #else
43 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
44 #endif
45 ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
46 sub r9, r9, #GD_SIZE /* new GD is below bd */
47
48 adr lr, here
49 ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */
50 add lr, lr, r0
51 #if defined(CONFIG_CPU_V7M)
52 orr lr, #1 /* As required by Thumb-only */
53 #endif
54 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
55 b relocate_code
56 here:
57 /*
58 * now relocate vectors
59 */
60
61 bl relocate_vectors
62
63 /* Set up final (full) environment */
64
65 bl c_runtime_cpu_setup /* we still call old routine here */
66 #endif
67 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
68 # ifdef CONFIG_SPL_BUILD
69 /* Use a DRAM stack for the rest of SPL, if requested */
70 bl spl_relocate_stack_gd
71 cmp r0, #0
72 movne sp, r0
73 movne r9, r0
74 # endif
75 ldr r0, =__bss_start /* this is auto-relocated! */
76
77 #ifdef CONFIG_USE_ARCH_MEMSET
78 ldr r3, =__bss_end /* this is auto-relocated! */
79 mov r1, #0x00000000 /* prepare zero to clear BSS */
80
81 subs r2, r3, r0 /* r2 = memset len */
82 bl memset
83 #else
84 ldr r1, =__bss_end /* this is auto-relocated! */
85 mov r2, #0x00000000 /* prepare zero to clear BSS */
86
87 clbss_l:cmp r0, r1 /* while not at end of BSS */
88 #if defined(CONFIG_CPU_V7M)
89 itt lo
90 #endif
91 strlo r2, [r0] /* clear 32-bit BSS word */
92 addlo r0, r0, #4 /* move to next */
93 blo clbss_l
94 #endif
95
96 #if ! defined(CONFIG_SPL_BUILD)
97 bl coloured_LED_init
98 bl red_led_on
99 #endif
100 /* call board_init_r(gd_t *id, ulong dest_addr) */
101 mov r0, r9 /* gd_t */
102 ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */
103 /* call board_init_r */
104 #if defined(CONFIG_SYS_THUMB_BUILD)
105 ldr lr, =board_init_r /* this is auto-relocated! */
106 bx lr
107 #else
108 ldr pc, =board_init_r /* this is auto-relocated! */
109 #endif
110 /* we should not return here. */
111 #endif
112
113 ENDPROC(_main)
- 7번 줄에서
CONFIG_SPL_BUILD
가 정의되어 있지 않아 10번 줄이 수행됩니다. - 10번 줄의
CONFIG_SYS_INIT_SP_ADDR
은include/configs/rpi.h
에CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE - GENERATED_GBL_DATA_SIZE
로 정의되어 있습니다.CONFIG_SYS_SDRAM_BASE
은0x00000000
로CONFIG_SYS_SDRAM_SIZE
은SZ_128M(0x08000000)
로GENERATED_GBL_DATA_SIZE
은208(0xD0)
로 정의되어 있습니다. 즉CONFIG_SYS_INIT_SP_ADDR
의 값은0x07FFFF30
이 됩니다. - 12번 줄에서 raspberry pi3는 armv7m이 아니라서 if문 대신 else문이 수행됩니다.
- 17번 줄에서 하위 3bit을 clear해서 8 byte로 align합니다.
- 19번 줄에서 sp의 주소를 r0에 저장합니다.
- 20번 줄에서 r0값을 가지고
board_init_f_alloc_reserve
로 점프합니다. 여기서도 bl로 점프할꺼면 _main으로 점프해 올때 lr을 왜 저장했을까요? - 21번 줄에서 return된 r0값을 sp에 옮깁니다.
- 23번 줄에서 다시 r0값을 r9으로 잠시 대피시켜 놓습니다.
- 24번 줄에서
board_init_f_init_reserve
로 점프합니다. - 26번 줄에서 r0를 0으로 초기화합니다.
- 27번 줄에서
board_init_f
로 점프합니다.