uboot启动流程详解(1)-_start
2018-02-06 08:58
513 查看
转载地址:http://blog.csdn.net/silent123go/article/details/53141316
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
为了更好的理解上面用到的汇编指令,对uboot进行反汇编。使用命令:
uboot.s就是反汇编出来的文件,以上这段代码对应的反汇编代码如下:
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
请看语句:
流水线操作:取址—>译码—>运行;
把内存中的代码取到CPU中,把e59ff014翻译成对应的命令,ldr pc,[pc,#20],然后运行。所以pc指针并不是指向当前运行的命令,而是指向当前运行的指令加8,加8超前两个指令,一个用来取址,一个用来译码,即:
pc=0x87800004+0x08=0x8780000c, pc= 0x8780000c+0x14(即20)=0x87800020
即把0x87800020地址处的数字0x87800120放到pc指针里面,即直接跳转到0x87800120地址处运行。
这个宏定义的主要作用就是生成 BL1 文件,提到 BL1 文件肯定又会有朋友产生疑问,在这里就这个 BL1 文件给大家简单的介绍一下:
BL1 文件是一段外部代码,存放在 SD 卡或者 nandflash 上,大小为(4K\8K\16K)。除了 BL1 文件,还有 BL0 和 BL2 文件。BL0 文件是存放在 CPU 内部 IROM 中的一段固化代码,CPU 上点之后,首先去运行BL0 文件。BL2 文件是完整的 U-Boot 代码。
这三个文件之间的关系就是:BL0 运行时会将 BL1 拷贝到 CPU 的 IRAM 中,然后执行BL1,BL1 文件执行起来之后会先进行内存的初始化,之后将 BL2 文件拷贝到外部内存中运行。
(1)代码及注释
.globl _start /*声明一个符号可被其它文件引用,相当于声明了一个全局变量, .globl与.global相同*/ _start: b reset /* b是不带返回的跳转(bl是带返回的跳转), 意思是无条件直接跳转到reset标号处执行程序*/ ldr pc, _undefined_instruction /*未定义指令异常向量,ldr的作用是, 将符号_undefined_instruction指向的地址的内容加载到pc*/ ldr pc, _software_interrupt /*软件中断向量*/ ldr pc, _prefetch_abort /*预取指令异常向量*/ ldr pc, _data_abort /*数据操作异常向量*/ ldr pc, _not_used /*未使用*/ ldr pc, _irq /*irq中断向量*/ ldr pc, _fiq /*fiq中断向量*/ #ifdef CONFIG_SPL_BUILD //我的uboot中没有定义这个宏,关于这个宏的介绍,请看下文 _undefined_instruction: .word _undefined_instruction _software_interrupt: .word _software_interrupt _prefetch_abort: .word _prefetch_abort _data_abort: .word _data_abort _not_used: .word _not_used _irq: .word _irq _fiq: .word _fiq _pad: .word 0x12345678 /* now 16*4=64 */ #else .globl _undefined_instruction _undefined_instruction: .word undefined_instruction /*就是在当前地址,即 _undefined_instruction 处存放 undefined_instruction。 通过下面的反汇编代码可以看到,这个地址存放的内容是0x87800120*/ .globl _software_interrupt _software_interrupt: .word software_interrupt .globl _prefetch_abort _prefetch_abort: .word prefetch_abort .globl _data_abort _data_abort: .word data_abort .globl _not_used _not_used: .word not_used .globl _irq _irq: .word irq .globl _fiq _fiq: .word fiq _pad: .word 0x12345678 /* now 16*4=64 */ #endif /* CONFIG_SPL_BUILD */ .global _end_vect _end_vect: .balignl 16,0xdeadbeef /*这句代码使下面的代码开始处16字节对齐, 即当上段的代码运行完后不是16字节对齐,就填充0xdeadbeef,直到使下段 的代码开始处16字节对齐。*/ /************************************************************************* * * Startup Code (reset vector) * * do important init only if we don't start from memory! * setup Memory and board specific bits prior to relocation. * relocate armboot to ram * setup stack * *************************************************************************/ /************************************************* 下面是IRQ中断,放了一个IRQ_STACK_START标号,标号内容为:0x0badc0de, 此内容没有意义,只是为了占一个坑。程序刚刚运行,还没有进入初始化,根本不知 道堆栈指针现在应该放在什么地方,所以一开始,作者做了一个小技巧,填充一个无 效的数字,等初始化以后堆栈指针建立好后,再将实际的堆栈指针写到这里。然而在 我的平台里CONFIG_USE_IRQ这个宏并没有定义!!! *************************************************/ #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ .globl IRQ_STACK_START IRQ_STACK_START: .word 0x0badc0de /* IRQ stack memory (calculated at run-time) */ .globl FIQ_STACK_START FIQ_STACK_START: .word 0x0badc0de #endif /* IRQ stack memory (calculated at run-time) + 8 bytes */ /*下面也是不能确定堆栈指针地址,所以填充无效数字,当堆栈指针确定以后,将其加8填充到这里*/ .globl IRQ_STACK_START_IN IRQ_STACK_START_IN: .word 0x0badc0de1
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
(2)反汇编代码
为了更好的理解上面用到的汇编指令,对uboot进行反汇编。使用命令: arm-fsl-linux-gnueabi-objdump -D u-boot > u-boot.s
uboot.s就是反汇编出来的文件,以上这段代码对应的反汇编代码如下:
u-boot: file format elf32-littlearm Disassembly of section .text: 87800000 <__image_copy_start>: 87800000: ea00000f b 87800044 <reset> 87800004: e59ff014 ldr pc, [pc, #20] ; 87800020 <_undefined_instruction> 87800008: e59ff014 ldr pc, [pc, #20] ; 87800024 <_software_interrupt> 8780000c: e59ff014 ldr pc, [pc, #20] ; 87800028 <_prefetch_abort> 87800010: e59ff014 ldr pc, [pc, #20] ; 8780002c <_data_abort> 87800014: e59ff014 ldr pc, [pc, #20] ; 87800030 <_not_used> 87800018: e59ff014 ldr pc, [pc, #20] ; 87800034 <_irq> 8780001c: e59ff014 ldr pc, [pc, #20] ; 87800038 <_fiq> 87800020 <_undefined_instruction>: 87800020: 87800120 strhi r0, [r0, r0, lsr #2] 87800024 <_software_interrupt>: 87800024: 87800180 strhi r0, [r0, r0, lsl #3] 87800028 <_prefetch_abort>: 87800028: 878001e0 strhi r0, [r0, r0, ror #3] 8780002c <_data_abort>: 8780002c: 87800240 strhi r0, [r0, r0, asr #4] 87800030 <_not_used>: 87800030: 878002a0 strhi r0, [r0, r0, lsr #5] 87800034 <_irq>: 87800034: 87800300 strhi r0, [r0, r0, lsl #6] 87800038 <_fiq>: 87800038: 87800360 strhi r0, [r0, r0, ror #6] 8780003c <_pad>: 8780003c: 12345678 eorsne r5, r4, #125829120 ; 0x7800000 87800040 <IRQ_STACK_START_IN>: 87800040: 0badc0de bleq 863703c0 <__image_copy_start-0x148fc40>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
请看语句:
ldr pc, [pc, #20] ; 87800020 <_undefined_instruction>,当要跳转到_undefined_instruction时,为什么是将当前pc的值加20后再赋给pc呢?
流水线操作:取址—>译码—>运行;
把内存中的代码取到CPU中,把e59ff014翻译成对应的命令,ldr pc,[pc,#20],然后运行。所以pc指针并不是指向当前运行的命令,而是指向当前运行的指令加8,加8超前两个指令,一个用来取址,一个用来译码,即:
pc=0x87800004+0x08=0x8780000c, pc= 0x8780000c+0x14(即20)=0x87800020
即把0x87800020地址处的数字0x87800120放到pc指针里面,即直接跳转到0x87800120地址处运行。
(3) CONFIG_SPL_BUILD介绍
这个宏定义的主要作用就是生成 BL1 文件,提到 BL1 文件肯定又会有朋友产生疑问,在这里就这个 BL1 文件给大家简单的介绍一下: BL1 文件是一段外部代码,存放在 SD 卡或者 nandflash 上,大小为(4K\8K\16K)。除了 BL1 文件,还有 BL0 和 BL2 文件。BL0 文件是存放在 CPU 内部 IROM 中的一段固化代码,CPU 上点之后,首先去运行BL0 文件。BL2 文件是完整的 U-Boot 代码。
这三个文件之间的关系就是:BL0 运行时会将 BL1 拷贝到 CPU 的 IRAM 中,然后执行BL1,BL1 文件执行起来之后会先进行内存的初始化,之后将 BL2 文件拷贝到外部内存中运行。
(4)ARM异常向量表
相关文章推荐
- Spring Boot启动流程详解
- Spring Boot启动流程详解(一)
- Spring Boot启动流程详解(一)
- Spring Boot启动流程详解(一)
- u-boot启动代码start.S详解
- x210v3开发板u-boot-2012.10移植之补充篇---uboot启动流程详解
- u-boot启动代码start.S详解-补充
- 1.移植uboot-分析uboot启动流程(详解)
- u-boot启动代码start.S详解-补充
- 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)
- Spring Boot启动过程(五)之Springboot内嵌Tomcat对象的start教程详解
- uboot启动流程详解(1)-_start
- Spring Boot 启动流程详解(二)
- OK6410 uboot启动流程详解(一)
- 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)
- uboot启动流程详解(4)-cpu_init_crit
- [uboot] (第五章)uboot流程——uboot启动流程
- 【Spring Boot】SpringBoot-启动流程分析
- Linux启动流程和grub详解
- U-Boot的启动流程