.
arch/arm/cpu/armv7/start.S
1 /*************************************************************************
2 *
3 * Startup Code (reset vector)
4 *
5 * Do important init only if we don't start from memory!
6 * Setup memory and board specific bits prior to relocation.
7 * Relocate armboot to ram. Setup stack.
8 *
9 *************************************************************************/
10
11 .globl reset
12 .globl save_boot_params_ret
13 #ifdef CONFIG_ARMV7_LPAE
14 .global switch_to_hypervisor_ret
15 #endif
16
17 reset:
18 /* Allow the board to save important registers */
19 b save_boot_params
20 save_boot_params_ret:
21 #ifdef CONFIG_ARMV7_LPAE
22 /*
23 * check for Hypervisor support
24 */
25 mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
26 and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
27 cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT)
28 beq switch_to_hypervisor
29 switch_to_hypervisor_ret:
30 #endif
31 /*
32 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
33 * except if in HYP mode already
34 */
35 mrs r0, cpsr
36 and r1, r0, #0x1f @ mask mode bits
37 teq r1, #0x1a @ test for HYP mode
38 bicne r0, r0, #0x1f @ clear all mode bits
39 orrne r0, r0, #0x13 @ set SVC mode
40 orr r0, r0, #0xc0 @ disable FIQ and IRQ
41 msr cpsr,r0
42
43 /*
44 * Setup vector:
45 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
46 * Continue to use ROM code vector only in OMAP4 spl)
47 */
48 #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
49 /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
50 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
51 bic r0, #CR_V @ V = 0
52 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register
53
54 /* Set vector address in CP15 VBAR register */
55 ldr r0, =_start
56 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
57 #endif
58
59 /* the mask ROM code should have PLL and others stable */
60 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
61 bl cpu_init_cp15
62 #ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
63 bl cpu_init_crit
64 #endif
65 #endif
66
67 bl _main
- 11번 줄에서 외부에서도
reset
라벨을 호출할 수 있도록global
로 선언합니다. - 12번 줄에서 마찬가지로
save_boot_params_ret
라벨을 선언합니다. - 13번 줄의
CONFIG_ARMV7_LPAE
이 정의되어 있기 때문에 14번 줄의switch_to_hypervisor_ret
도 위와 같이 선언합니다. - 17번 줄에서
reset
라벨이 시작됩니다. - 19번 줄에서
save_boot_params
로 점프합니다. - 20번 줄의
save_boot_params_ret
에서 다시 시작합니다. - 21번 줄의
CONFIG_ARMV7_LPAE
은 선언되어ifdef
이 수행됩니다. - 25번 줄에서
- 26번 줄에서 r0와
CPUID_ARM_VIRT_MASK
값을AND
한 결과를 r0에 저장합니다.CPUID_ARM_VIRT_MASK
값은arch/arm/include/asm/armv7.h
에(0xF << CPUID_ARM_VIRT_SHIFT)
로 정의되어 있습니다. - 27번 줄에서
CPUID_ARM_VIRT_SHIFT
은arch/arm/include/asm/armv7.h
에 12로 정의되어 있습니다. 즉 r0값과 2^12값을 비교합니다. - 28번 줄에서는 27번 줄의 값이 같이 않으면
switch_to_hypervisor
로 점프하지만 아무런 역할을 하지 않습니다. - 35번 줄에서
cpsr
레지스터 값을 r0에 저장합니다. - 36번 줄에서 모드 bit만 남겨 r1에 저장합니다.
- 37번 줄에서 현재 모드가 hypervisor 모드인지 확인합니다.
- 38번 줄에서 만약 현재 모드가 hypervisor모드가 아니라면 r0에서 모드 bit을 모두 0으로 클리어합니다.
- 39번 줄에서 만약 현재 모드가 hypervisor모드가 아니라면 r0에 0x13을 써 supervisor 설정값을 씁니다.
- 40번 줄에서 현재 모드가 hypervisor모드라면 FIQ와 IRQ를 disable하는 설정값을 r0에 씁니다.
- 41번 줄에서 r0값을
cpsr
에 씁니다. - 48번 줄에서 둘다 선언되어 있지 않아 if문이 수행됩니다.
- 50번 줄에서 System Control Register를 r0로 읽어 옵니다.
- 51번 줄에서 r0값에서 CR_V값을 0으로 합니다. CR_V값은
arch/arm/include/asm/system.h
에(1 << 13)
로 설정되어 있습니다. 이 bit는 exception vectors의 base address를 선택합니다. 만약 0이면 base address는 0x00000000이고 1이면 0xFFFF0000입니다. 0이라면 base address는 remap될 수 있습니다. - 52번 줄에서 r0의 값을 다시 SCTLR에 씁니다.
- 55번 줄에서 _start라벨의 주소를 r0로 읽어 옵니다.
- 56번 줄에서 r0의 값을 CP15의 VBAR에 저장해 놓습니다.
- 60번 줄의 CONFIG_SKIP_LOWLEVEL_INIT이 선언되어 있어 if문이 수행되지 않습니다.
- 67번 줄에서 _main으로 점프합니다. BL 명령어는 B 명령어와 유사하지만 링크 레지스터 LR에 복귀 주소를 저장합니다.