uboot startup process-uboot link script u-boot.lds

1. uboot startup process

In this article, we will analyze the startup process of uboot in detail and clarify how uboot is started. Through sorting out the uboot startup process.

We can grasp where some peripherals are initialized, so that we will know . In addition, by analyzing the uboot startup process, you can understand how the Linux kernel is started.

Note: The prerequisite for analyzing the uboot startup process is that the uboot source code needs to be compiled.

2. Link script u-boot.lds

To analyze the startup process of uboot , you must first find the "entry" and find where the first line of the program is.

The link of the program is determined by the link script, so the entry of the program can be found through the link script. The connection script is in the u-boot.lds file in the root directory of uboot.
Note: If uboot has not been compiled, the link script is arch/arm/cpu/u-boot.lds. But this is not the final link script used. The final link script is generated based on this link script. Compile uboot. After the compilation is completed, the u-boot.lds file will be generated in the uboot root directory.
Only after compiling u-boot will the u-boot.lds file appear in the root directory ! ! !

Open the link script u-boot.lds , the content is as follows:
1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
2 OUTPUT_ARCH(arm)
3 ENTRY(_start)
4 SECTIONS
5 {
6 . = 0x00000000;
7 . = ALIGN(4);
8 .text :
9 {
10 *(.__image_copy_start)
11 *(.vectors)
12 arch/arm/cpu/armv7/start.o (.text*)
13 *(.text*)
14 }
15 . = ALIGN(4);
16 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
17 . = ALIGN(4);
18 .data : {
19 *(.data*)
20 }
21 . = ALIGN(4);
22 . = .;
23 . = ALIGN(4);
24 .u_boot_list : {
25 KEEP(*(SORT(.u_boot_list*)));
26 }
27 . = ALIGN(4);
28 .image_copy_end :
29 {
30 *(.__image_copy_end)
31 }
32 .rel_dyn_start :
33 {
34 *(.__rel_dyn_start)
35 }
36 .rel.dyn : {
37 *(.rel*)
38 }
39 .rel_dyn_end :
40 {
41 *(.__rel_dyn_end)
42 }
43 .end :
44 {
45 *(.__end)
46 }
47 _image_binary_end = .;
48 . = ALIGN(4096);
49 .mmutable : {
50 *(.mmutable)
51 }
52 .bss_start __rel_dyn_start (OVERLAY) : {
53 KEEP(*(.__bss_start));
54 __bss_base = .;
55 }
56 .bss __bss_base (OVERLAY) : {
57 *(.bss*)
58 . = ALIGN(4);
59 __bss_limit = .;
60 }
61 .bss_end __bss_limit (OVERLAY) : {
62 KEEP(*(.__bss_end));
63 }
......
73 .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
74 }

Line 3 is the current entry point of the code: _start , _start is defined in the file arch/arm/lib/vectors.S.
vectors.S looks like this:
/*
 *************************************************************************
 *
 * Vectors have their own section so linker script can map them easily
 *
 *************************************************************************
 */
    .section ".vectors", "ax"
/*
 *************************************************************************
 *
 * Exception vectors as described in ARM reference manuals
 *
 * Uses indirect branch to allow reaching handlers anywhere in memory.
 *
 *************************************************************************
 */

_start:

#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
    .word   CONFIG_SYS_DV_NOR_BOOT_CFG
#endif

    b   reset
    ldr pc, _undefined_instruction
    ldr pc, _software_interrupt
    ldr pc, _prefetch_abort
    ldr pc, _data_abort
    ldr pc, _not_used
    ldr pc, _irq
    ldr pc, _fiq

It can be seen from vectors.S that after _start is the interrupt vector table, which can be obtained from " .section ".vectors", "ax " in the figure . This code is stored in the .vectors section.
u-boot.map is the memory mapping file of uboot . Open u-boot.map:
段 .text 的地址设置为 0x87800000
                0x0000000000000000                . = 0x0
                0x0000000000000000                . = ALIGN (0x4)

.text           0x0000000087800000    0x47aa0
 *(.__image_copy_start)
 .__image_copy_start
                0x0000000087800000        0x0 arch/arm/lib/built-in.o
                0x0000000087800000                __image_copy_start
 *(.vectors)
 .vectors       0x0000000087800000      0x300 arch/arm/lib/built-in.o
                0x0000000087800000                _start
                0x0000000087800020                _undefined_instruction
                0x0000000087800024                _software_interrupt
                0x0000000087800028                _prefetch_abort
                0x000000008780002c                _data_abort
                0x0000000087800030                _not_used
                0x0000000087800034                _irq
                0x0000000087800038                _fiq
                0x0000000087800040                IRQ_STACK_START_IN
From u-boot.map, you can see which address a certain file or function is linked to. In line 958, you can see that __image_copy_start is 0X87800000 , and the starting address of .text is also 0X87800000 .

Continue to link the script u-boot.lds. Line 11 of the u-boot.lds file is the vectors section. The vectors section saves the interrupt table.

From vectors.S , we know that the code of vectors.S is stored in the vectors section.

From the u-boot.map file, we can see that the starting address of the vectors segment is also 0X87800000 , which means that the starting address of the entire uboot is 0X87800000 . This is why the link starting address of our bare metal routine is 0X87800000 . The purpose is to uboot is consistent.

From the link script u-boot.lds, we can see: Line 12 puts the code compiled by arch/arm/cpu/armv7/start.s behind the interrupt vector table.
Line 13 is the text segment, and other code segments are placed here.
There are some "variables" related to addresses in u-boot.lds that we need to pay attention to. We will analyze the u -boot source code later.
It will be used sometimes, and these variables cannot be determined until the final compilation is completed! ! ! For example, the values ​​of these "variables" after I complete the compilation.
As follows:
variable numerical value describe
__image_copy_start 0x87800000 The first address of uboot copy
__image_copy_end 0x8786b03c End address of uboot copy
__rel_dyn_start
0x8786b03c
.rel.dyn segment starting address
__rel_dyn_end
0x8787459c
.rel.dyn segment end address
_image_binary_end
0x8787459c
Mirror end address
__bss_start
0x8786b03c
.bss section starting address
__bss_end
0x878b7314
.bss section end address

The "variable" values ​​in the above table can be found in the u-boot.map file. Except for __image_copy_start , other variable values ​​may change each time you compile. If you modify the uboot code, modify the uboot configuration, and select a different Optimization levels, etc. will affect these values. Therefore, everything is subject to actual value!

Guess you like

Origin blog.csdn.net/wojiaxiaohuang2014/article/details/133394689