Função de montagem lowlevel_init que envolve o processo de inicialização do uboot

1. O processo de inicialização do Uboot envolve funções

O artigo anterior analisou brevemente o início do processo de inicialização do uboot. A partir do arquivo de script de link u-boot.lds, já sabemos que o ponto de entrada é a função _start no arquivo arch/arm/lib/vectors.S .

Função _start : A função reset é chamada . Dentro da função reset: A função save_boot_params_ret é finalmente chamada .

Função save_boot_params_ret:

① Defina o processador para o modo SVC e desligue FIQ e IRQ.

② Defina o vetor de interrupção.

③ Inicialize o CP15 (cpu_init_cp15) e chame a função cpu_init_crit.

Entre eles, a função cpu_init_crit chama a função lowlevel_init.

Este artigo continua a analisar brevemente o que a função lowlevel_init (ou seja, a função chamada pela função cpu_init_crit) faz?

Este artigo dá continuidade à análise do artigo anterior, o endereço é o seguinte:

O processo de inicialização do uboot envolve a função de redefinição_Ling Xiaozhan's Blog-CSDN Blog

2.     Explicação detalhada da função lowlevel_init

A função lowlevel_init é definida no arquivo arch/arm/cpu/armv7/lowlevel_init.S . O conteúdo é o seguinte:

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)

A linha 22 define sp para apontar para CONFIG_SYS_INIT_SP_ADDR , CONFIG_SYS_INIT_SP_ADDR em
No arquivo include/configs/mx6ullevk.h , mx6ullevk.h é definido da seguinte forma:

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)

As macros IRAM_BASE_ADDR e IRAM_SIZE acima são definidas no arquivo arch/arm/include/asm/arch-mx6/imx-regs.h. Na verdade, elas são o primeiro endereço e tamanho do ocram dentro de IMX6UL/IM6ULL, conforme mostrado abaixo:
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

Se a condição na linha 408 for verdadeira , IRAM_SIZE=0X40000 . Quando qualquer um de CONFIG_MX6SX , CONFIG_MX6U , CONFIG_MX6SLL e CONFIG_MX6SL é definido , a condição não é verdadeira. CONFIG_MX6UL é definido no arquivo .config , portanto a condição não é verdadeira, IRAM_SIZE =0X20000=128 KB .

Os seguintes valores podem ser obtidos:
CONFIG_SYS_INIT_RAM_ADDR=IRAM_BASE_ADDR=0x00900000 .
CONFIG_SYS_INIT_RAM_SIZE = 0x00020000 =128 KB .

Você também precisa saber o valor de GENERATED_GBL_DATA_SIZE , que está definido no arquivo include/generated/generic-asm-offsets.h, como segue:
9 #define GENERATED_GBL_DATA_SIZE 256
10 #define GENERATED_BD_INFO_SIZE 80
11 #define GD_SIZE 248

Como pode ser visto, GENERATED_GBL_DATA_SIZE=256.
Resumindo, o valor CONFIG_SYS_INIT_SP_ADDR é o seguinte:
CONFIG_SYS_INIT_SP_OFFSET = 0x00020000 – 256 = 0x1FF00
CONFIG_SYS_INIT_SP_ADDR = 0x00900000 + 0X1FF00 = 0X0091FF00

Conforme mostrado na figura abaixo, é o valor do ponteiro sp:

Neste momento , sp aponta para 0X91FF00 , que pertence à memória RAM interna do IMX6UL/IMX6ULL .
Isso pode ser visto no arquivo lowlevel_init.S :
A linha 23 executa o alinhamento de 8 bytes no ponteiro sp !
Linha 34 , o ponteiro sp menos GD_SIZE , GD_SIZE também é definido em generic-asm-offsets.h , o tamanho é
248 .
A linha 35 alinha sp com 8 bytes. Neste momento, o endereço de sp é 0X0091FF00-248=0X0091FE08 . Neste momento , o bit sp é o seguinte:

Função lowlevel_init no arquivo lowlevel_init.S :

A linha 36 salva o endereço sp no registrador r9 .
A linha 42 coloca ip e lr na pilha
A linha 57 chama a função s_init .
Linha 58 , coloque ip e lr na pilha na linha 36 e atribua lr a pc .

Análise do próximo artigo:

Função chamada pela função lowlevel_init: função s_init

Função chamada pela função save_boot_params_ret: _main

Acho que você gosta

Origin blog.csdn.net/wojiaxiaohuang2014/article/details/133420660
Recomendado
Clasificación