Red de conocimiento informático - Material del sitio web - Cómo grabar U-boot en una tarjeta SD

Cómo grabar U-boot en una tarjeta SD

Para abreviar la historia, comencé a grabar UBOOT en la tarjeta SD y a iniciar UBOOT desde la SD.

De s5pv210_irom_applicationnote_preliminary_20091126.pdf sabemos que el inicio de s5pv210 se divide en tres etapas: BL0, BL1 y BL2. BL0 es el código solidificado de la IROM interna de s5pv210. Este código selecciona desde qué dispositivo de almacenamiento externo cargar el código del segmento BL1 de acuerdo con el estado de configuración del pin OM (de hecho, el código del segmento BL1 es el primer código de 8K escrito por. nuestro UBOOT. Este código contiene una copia completa de la segunda mitad del código UBOOT y borra las funciones de la parte bss. Por supuesto, queremos iniciar desde la tarjeta SD grabada arriba) (Por supuesto, si queremos iniciar UBOOT desde la SD. tarjeta, el pin OM debe configurarse para arrancar desde la tarjeta SD).

Figura 1

Como se puede ver en la figura anterior, al arrancar desde la tarjeta SD, el código cargado por BL0 comienza a cargar el código desde el byte 512. ¿Por qué se hace esto? ? Debido a la necesidad de una futura expansión, el ingeniero de software de Samsung escribió el código BL0 solidificado en la IROM en el byte 512 del BL1 cargado desde la tarjeta SD. Esto es lo que escribió correspondientemente en la posición de UBOOT en la tarjeta SD. se moverá hacia atrás 512 bytes. Aquí hay una descripción de cómo especificar cómo escribir uboot en la tarjeta SD en la ubicación de comando especificada.

Y asegúrese de prestar atención a los siguientes puntos:

Figura 2

Hay 16 bytes de información de encabezado antes de BL1. En otras palabras, se deben agregar 16 bytes de información de encabezado antes de la primera instrucción del UBOOT real, por lo que hay una parte de definición de macro en el código de uboot y podemos ver el siguiente contenido:

[ cpp ] ver copia simple

#if definido (CONFIG_EVT1) amp; definir(CONFIG_FUSED)

.word 0x2000

.word 0x0

.word 0x0

.word 0x0

#endif

.globl _start

_start.b reset

ldr pc, _undefined_instruction

ldr pc, _software_interrupt

ldr pc, _prefetch_abort

donde

.word 0x2000 representa el tamaño BL1 (8K de longitud), .word 0x0 es un byte reservado, .word 0x0 es una suma de comprobación (más adelante mkbl1 La herramienta se utilizará para calcular la suma de verificación de BL1 y completar esta posición), la última palabra 0x0 también es un byte reservado.

Mire la parte de uboot a continuación. Si bl0 lee bl1 normalmente, el código ingresará a la siguiente sección:

[cpp] ver copia simple

/* Leer. información de arranque */

ldr r0, =PRO_ID_BASE <

ldr r1, [r0, #OMR_OFFSET] // Leer el estado de configuración del pin OM

bic r2 , r1,

#ifdef CONFIG_VOGUES

/* PS_HOLD(GPH0_0) está configurado para generar un nivel alto*/

ldr r0, =ELFIN_GPIO_BASE

ldr r1, =0x00000001

str r1, [r0, #GPH0CON_OFFSET]

ldr r1, =0x5500

str r1, [r0, # GPH0PUD_OFFSET]

str r1, [r0, #GPH0CON_OFFSET GPH0PUD_OFFSET]

ldr r1, =0x01

str r1, [r0, #GPH0DAT_OFFSET]

#endif

/* NAND BOOT */

cmp r2, #0x0 @ 512B 4 ciclos

moveq r3, #BOOT_NAND //según El estado de configuración del pin OM asigna un valor de configuración al registro R3, que representa dónde comienza el sistema.

cmp r2, #0x2 @ 2KB 5 ciclos

moveq r3, #BOOT_NAND

cmp r2, #0x4 @ 4KB 5 ciclos 8 bits ECC

moveq r3, #BOOT_NAND

cmp r2, #0x6 @ 4KB ECC de 5 ciclos y 8 bits

moveq r3,

cmp r2 , #0x6 @ 4KB ECC de 5 ciclos y 16 bits

moveq r3, #BOOT_NAND

cmp r2, #0x8 @ OneNAND Mux

moveq r3, # BOOT_ONENAND

/* SD/MMC BOOT */

cmp r2, #0xclt; pre name="code" class="cpp"gt; _TEXT_PHY_BASE /* Establecer puntero de pila temporal*/

sub sp, sp, #12

mov fp, #0 /* No hay un fotograma anterior, por lo que fp=0 */

/* Cuando Ya estamos ejecutando RAM, no necesitamos reubicar U-Boot.

*De hecho, el controlador de memoria debe configurarse antes de que U-Boot pueda ejecutarse en la memoria.

*/

ldr r0, =0xff000fff

bic r1, pc, r0 /* r0 lt - la dirección base actual del código */ <; /p >

ldr r2, _TEXT_BASE /* r1 lt; - la dirección base original en la memoria */

bic r2, r2, r0 /* r0 lt - la dirección base actual del código. */

bic r2, r2, r0 /* r0 lt - dirección base original en memoria - dirección base del código actual */

cmp r1, r2 /* comparar r0, r1 */

beq after_copy /* r0 == r1 luego omite la copia flash */lt;/pregt;lt;brgt;

moveq r3, #BOOT_MMCSD/* NOR BOOT * / cmp r2, #0x14moveq r3, # BOOT_NOR#if 0 /* ¡Android C110 BSP arranca con OneNAND! *//* Para el arranque del segundo dispositivo*//* Error en el BOOTONG de OneNAND*/cmp r2, #0x8moveq r3, #BOOT_SEC_DEV #endif/* Error en el BOOTONG de Uart*/cmp r2, #(0x1lt;lt;4)moveq

r3, #BOOT_SEC_DEVldr r0, =INF_REG_BASEstr r3, [r0, #INF_REG3_OFFSET] //Guarda el valor de configuración en

lt;pregt;lt;/pregt;

lt;pgt;lt;/pgt;

lt;pgt;lt;/pgt;

lt;pregt;lt;/pgt; pregt;lt;/pregt;

lt;pre name="code" class="cpp"gt;

ldr sp, =0xd0035400 //pila donde está la función en el segmento BL1 realiza su operación Aquí modifico la pila a 0xd0035400 porque el código BL0 inicializa su propia pila de código como se muestra en la Figura 2 y la parte más baja del montón del área RW/ZI está en 0xd0035400, esto se hace para no modificar la pila BL0 y. algunas funciones que el código BL0 ha escrito (se usarán a continuación), modifiqué la pila a 0xd0035400

sub sp, sp, #12 /* set stack */

mov fp , #0

bl lowlevel_init /* go setup pll, mux, memoria */ //Aquí estará siempre, memoria, inicialización en serie lt;/pre gt

lt;pgt; ; y luego ejecute lt;/pgt;

lt;pgt;lt;/pgt;

lt;pre name="code" class="cpp"gt ;ldr sp. , _TEXT_PHY_BASE /* Establecer puntero de pila temporal*/ // Debido a DRAM

Se ha inicializado en el paso anterior, por lo que la pila posterior se configurará en la ubicación en DRAM aquí (las funciones en el código BL2 posterior se basan en esta pila)

sub sp, sp, #12

mov fp, #0 /* No hay fotograma anterior, por lo que fp=0 */

/* No necesitamos reubicar U-Boot cuando ya estamos ejecutando en carnero.

* De hecho, el controlador de memoria debe configurarse antes de que U-Boot pueda ejecutarse en la memoria.

*/

ldr r0, =0xff000fff

bic r1, pc, r0 /* r0 lt - la dirección base actual del código */ <; /p >

ldr r2, _TEXT_ BASE /* r1 lt - la dirección base original en la memoria */ // Carga la dirección de ejecución del programa compilado y compárala con la dirección de ejecución del programa actual

bic r2, r2, r0 /* r0 lt; - la dirección base del código actual */

cmp r1, r2 /* comparar r0, r1 */

beq after_copy /* r0 = = r1, luego omita la copia de la memoria flash*/ // Si las dos direcciones son iguales, significa que el programa de código ya se está ejecutando en DRAM y no es necesario copiarlo nuevamente si no son iguales; Significa que el programa no se ha ejecutado en la dirección compilada y el código debe copiarse a la dirección de compilación y finalmente saltar a la dirección de compilación correspondiente para ejecutar el código. El último paso es saltar a la dirección compilada correspondiente para ejecutar el código.

lt;/pregt;lt;pre nombre="código" clase="cpp"gt; ldr r0, =INF_REG_BASE

ldr r1, [r0, #INF_REG3_OFFSET]

cmp r1 , #BOOT_NAND /* 0x0 =gt; El dispositivo de arranque es nand */

beq nand_boot

cmp r1, #BOOT_ONENAND /* 0x1 =gt;

beq onenand_boot

cmp r1, #BOOT_MMCSD /* 0x1 =gt #BOOT_MMCSD

beq mmcsd_boot

cmp r1, #BOOT_NOR

beq nor_boot

cmp r1, #BOOT_SEC_DEV

beq mmcsd_boot

// El código funciona leyendo un registro de usuario previamente almacenado (en este (caso del valor en la tarjeta SD), determine desde qué dispositivo de almacenamiento externo arrancar y luego determine cuál se copiará

// El código funciona leyendo el valor previamente almacenado en el registro de usuario ( en este caso, la tarjeta SD) El valor determina desde qué dispositivo de almacenamiento externo arrancar

~~~~~ Algunos códigos se omiten~~~~~~~~

mmcsd_boot :

#if BORRAR

ldr sp, _TEXT_PHY_BASE <

sub sp, sp, #12

mov fp, #0

#endif

bl movi_bl2_copy //El último código BL1 copiará el resto del código de la tarjeta SD aquí

b after_copylt;/pregt;lt;br gt;

lt;pregt;lt;/pregt;

lt;pre nombre="código" class="cpp"gt;lt;/pregt;