uboot startup process-involving lowlevel_init assembly function

1. Uboot startup process involves functions

The previous article briefly analyzed the beginning of the uboot startup process. From the link script file u-boot.lds, we already know that the entry point is the _start function in the arch/arm/lib/vectors.S file .

_start function : The reset function is called . Inside the reset function: The save_boot_params_ret function is finally called .

save_boot_params_ret function:

① Set the processor to SVC mode and turn off FIQ and IRQ.

② Set the interrupt vector.

③ Initialize CP15 (cpu_init_cp15) and call the cpu_init_crit function.

Among them, the cpu_init_crit function calls the function lowlevel_init function.

This article continues to briefly analyze what the lowlevel_init function (that is, the function called by the cpu_init_crit function) does?

This article continues the analysis of the previous article, the address is as follows:

The uboot startup process involves the reset function_Ling Xiaozhan's Blog-CSDN Blog

2.     Detailed explanation of lowlevel_init function

The lowlevel_init function is defined in the file arch/arm/cpu/armv7/lowlevel_init.S . The content is as follows:

18 ENTRY(lowlevel_init)
19 /*
20 * Setup a temporary stack. Global data is not available yet.
21 */
22 ldr sp, =CONFIG_SYS_INIT_SP_ADDR
23 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
24 #ifdef CONFIG_SPL_DM
25 mov r9, #0
26 #else
27 /*
28 * Set up global data for boards that still need it. This will be
29 * removed soon.
30 */
31 #ifdef CONFIG_SPL_BUILD
32 ldr r9, =gdata
33 #else
34 sub sp, sp, #GD_SIZE
35 bic sp, sp, #7
36 mov r9, sp
37 #endif
38 #endif
39 /*
40 * Save the old lr(passed in ip) and the current lr to stack
41 */
42 push {ip, lr}
43
44 /*
45 * Call the very early init function. This should do only the
46 * absolute bare minimum to get started. It should not:
47 *
48 * - set up DRAM
49 * - use global_data
50 * - clear BSS
51 * - try to start a console
52 *
53 * For boards with SPL this should be empty since SPL can do all 
54 * of this init in the SPL board_init_f() function which is 
55 * called immediately after this.
56 */
57 bl s_init
58 pop {ip, pc}
59 ENDPROC(lowlevel_init)

Line 22 sets sp to point to CONFIG_SYS_INIT_SP_ADDR , CONFIG_SYS_INIT_SP_ADDR in
In the include/configs/mx6ullevk.h file, mx6ullevk.h is defined as follows:

234 #define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
235 #define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE
236
237 #define CONFIG_SYS_INIT_SP_OFFSET \
238 (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
239 #define CONFIG_SYS_INIT_SP_ADDR \
240 (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)

The above macros IRAM_BASE_ADDR and IRAM_SIZE are defined in the file arch/arm/include/asm/arch-mx6/imx-regs.h. They are actually the first address and size of the ocram inside IMX6UL/IM6ULL, as shown below:
71 #define IRAM_BASE_ADDR 0x00900000
......
408 #if !(defined(CONFIG_MX6SX) || defined(CONFIG_MX6UL) || \
409 defined(CONFIG_MX6SLL) || defined(CONFIG_MX6SL))
410 #define IRAM_SIZE 0x00040000
411 #else
412 #define IRAM_SIZE 0x00020000
413 #endif

If the condition in line 408 is true, IRAM_SIZE=0X40000 , but when any one of CONFIG_MX6SX , CONFIG_MX6U , CONFIG_MX6SLL and CONFIG_MX6SL is defined , the condition is not true. CONFIG_MX6UL is defined in the .config file , so the condition is not true, IRAM_SIZE=0X20000=128KB .

The following values ​​can be obtained:
CONFIG_SYS_INIT_RAM_ADDR = IRAM_BASE_ADDR = 0x00900000
CONFIG_SYS_INIT_RAM_SIZE = 0x00020000 =128KB

You also need to know the value of GENERATED_GBL_DATA_SIZE , which is defined in the file include/generated/generic-asm-offsets.h, as follows:
9 #define GENERATED_GBL_DATA_SIZE 256
10 #define GENERATED_BD_INFO_SIZE 80
11 #define GD_SIZE 248

As can be seen, GENERATED_GBL_DATA_SIZE=256.
To sum up, the CONFIG_SYS_INIT_SP_ADDR value is as follows:
CONFIG_SYS_INIT_SP_OFFSET = 0x00020000 – 256 = 0x1FF00
CONFIG_SYS_INIT_SP_ADDR = 0x00900000 + 0X1FF00 = 0X0091FF00

As shown in the figure below, it is the value of the sp pointer:

At this time , sp points to 0X91FF00 , which belongs to the internal ram of IMX6UL/IMX6ULL .
It can be seen from the lowlevel_init.S file :
Line 23 performs 8 -byte alignment on the sp pointer !
Line 34 , the sp pointer minus GD_SIZE , GD_SIZE is also set in generic-asm-offsets.h , the size is
248
Line 35 aligns sp with 8 bytes. At this time, the address of sp is 0X0091FF00-248=0X0091FE08 . At this time , the sp bit is as follows:

lowlevel_init function in lowlevel_init.S file :

Line 36 saves the sp address in the r9 register.
Line 42 pushes ip and lr onto the stack
Line 57 calls the s_init function .
Line 58 , pop the ip and lr pushed onto the stack in line 36 , and assign lr to pc .

Next article analysis:

Function called by lowlevel_init function: s_init function

Function called by save_boot_params_ret function: _main

Guess you like

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