Boot Process/es

From Qi-Hardware
Jump to: navigation, search

Contents

[edit] Proceso de Inicialización de SIE

[edit] ROM Interna

El JZ4725 posee una memoria ROM interna de 4KB localizada en el rango de memoria 0x1FC00000 - 0x1FC01000, esta memoria está conectada al Controlador de Memoria Externa (EMC). Después del reset el procesador ejecuta el programa contenido en la memoria ROM y dependiendo del valor de las señales boot_sel[1:0] realiza las siguientes operaciones:

boot_sel[1:0]
00 no Utilizado
01 Inicio por el puerto USB: Recibe un bloque de datos por el puerto USB (device) y los almacena en la memoria interna SRAM
10 Inicio por una memoria NAND con una página de 512 en CS1:
11 inicio por una memoria NAND con una página de 2048 en CS1: Lee el primer byte de la memoria NAND para determinar si el bus es de 8 o 16 bits (si bit[7:4] = 0 es de 16 bits), y el número de ciclos por página es 2 o 3 (si bit[3:0] = 0 es de 2 ciclos). Ajusta el EMC con esta información y copia los primeros 8kB de la NAND a la SRAM interna. La NAND de SIE es de 8 bits de datos, 3 ciclos, y 4096 bytes por página, por lo que el primer byrte debe ser 0xFF

[edit] inicialización NAND

La siguiente figura muestra el proceso de inicialización desde la RAM para los procesadores JZ472X. una vez determinado el número de bits y el número de ciclos por página; después de esto lee 8KB de la NAND comenzando desde la posiciónde memoria 0x0, Si no se encuentra errores ECC o estos se pueden corregir, el programa hace un salto a la posición de memoria 0x80000004, si se encuentra un error incorregible el programa leerá la información de respaldo en la posición de memoria 0x2000 y si no existe ningún error incorregible salta a la posición de memoria 0x80000004 de la SRAM interna, de lo contrario realizará la inicialización desde la memoria NOR en CS4.


Inicialización desde la NAND (Basado en el manual de procesador JZ4725).


[edit] u-boot

SIE al igual que BEN utiliza el u-boot proporcionado por Ingenic, el cual ha sido modificado por los desarrolladores de Qi-Hardware para adaptarse a sus plataformas.

En ambas plataformas el proceso de inicialización es el mismo, La aplicación usbboot se utiliza para grabar en la NAND el archivo openwrt-xburst-u-boot.bin, siguiendo estas instrucciones. El código fuente de u-boot puede obtenerse siguiendo estas instrucciones; el código quedará almacenado en la carpeta: openwrt-xburst/build_dir/linux-xburst/u-boot-2009.11.


[edit] start.S

El archivo openwrt-xburst-u-boot.bin está compuesto por dos secciones: First Stage loader y u-boot (ver siguiente figura). La primera función en ejecutarse es _start la cual se encuentra definida en /cpu/mips/start.S, esta función hace un llamado a la función reset definida en el mismo archivo, cuyo código se muestra a continuación:

  1. 	.globl _start
  2. 	.text
  3.         .word JZ4740_NANDBOOT_CFG /*(0xffffffff) NAND 8 Bits 3 cycles */
  4.         b reset; nop    /* U-boot entry point */
  5.         b reset; nop    /* software reboot */
  6. reset:
  7. 	/* 
  8. 	 * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1
  9. 	 */
  10. 	li	t0, 0x0040FC04       /*t0 = 0x0040FC04 */
  11. 	mtc0	t0, CP0_STATUS       /*CP0_STAT = 0x0040FC04 Normal mode processor,
  12.                                       disable interrupts, Excepcion level normal, 
  13.                                       kernel mode*/
  14. 	/* IV=1, use the specical interrupt vector (0x200) */
  15. 	li	t1, 0x00800000       
  16. 	mtc0	t1, CP0_CAUSE        /*CP0_CAUSE = 0x00800000 Cause of last exception*/
  17.  
  18. 	/* Init Timer */
  19. 	mtc0	zero, CP0_COUNT      /*Address at which processing resumes after an exception*/
  20. 	mtc0	zero, CP0_COMPARE    /**/
  21.  
  22. 	/* Initialize GOT pointer.
  23. 	*/
  24. 	bal     1f
  25. 	nop
  26. 	.word   _GLOBAL_OFFSET_TABLE_
  27. 	1:
  28. 	move    gp, ra
  29. 	lw      t1, 0(ra)
  30. 	move	gp, t1
  31.  
  32. 	la	sp, 0x80004000
  33. 	la	t9, nand_boot
  34. 	j	t9
  35. 	nop

En el código anterior podemos ver que después de la etiqueta que indica el inicio de la sección text (Sección donde se almacena las instrucciones a ejecutar) se define la palabra JZ4740_NANDBOOT_CFG(línea 3) que en nuestro caso equivale a 0xffffffff, esto garantiza que el primer byte almacenado en la NAND sea 0xFF, con lo que le indicamos al programa de inicio de la ROM que tenemos una memoria de 8 bits y 3 ciclos.

A continuación se hace un salto incondicional a la función reset (línea 4) donde se configuran los registros del co-procesador STATUS, CAUSE, COUNT y COMPARE XXX. En la línea 24 se hace un salto a la etiqueta 1: y se almacena en RA el valor PC + 8; en la linea 28 se almacena el valor de RA en el puntero global gp; en la línea 32 se fija el puntero de la pila (sp) a la dirección 0x80004000 y finalmente se hace un llamado a la función nand_boot definida en nand_spl/nand_boot_jz4740.c:

[edit] nand_boot()

  1. void nand_boot(void)
  2. {
  3. 	void (*uboot)(void);
  4.  
  5. 	/*
  6. 	 * Init hardware
  7. 	 */
  8. 	jz_nand_init();
  9. 	gpio_init();
  10. 	serial_init();
  11.  
  12. 	serial_puts("\n\nNAND Secondary Program Loader\n\n");
  13.  
  14. 	pll_init();
  15. 	sdram_init();
  16.  
  17. #if defined(CONFIG_QI_LB60)
  18.         if(is_usb_boot()) {
  19.                 serial_puts("enter USB BOOT mode\n");
  20.                 usb_boot();
  21.         }
  22. #endif
  23. 	bus_width = 8;
  24. 	row_cycle = 3;
  25.  
  26. 	page_size = CONFIG_NAND_PAGE_SIZE;
  27. 	block_size = CONFIG_NAND_BLOCK_SIZE;
  28. 	page_per_block = CONFIG_NAND_BLOCK_SIZE / CONFIG_NAND_PAGE_SIZE;
  29. 	bad_block_pos = (page_size == 512) ? 5 : 0;
  30. 	oob_size = page_size / 32;
  31. 	ecc_count = page_size / ECC_BLOCK;
  32.  
  33. 	/*
  34. 	 * Load U-Boot image from NAND into RAM
  35. 	 */
  36. 	nand_load(CONFIG_NAND_U_BOOT_OFFS, CONFIG_NAND_U_BOOT_SIZE,
  37. 		  (uchar *)CONFIG_NAND_U_BOOT_DST);
  38.  
  39. 	uboot = (void (*)(void))CONFIG_NAND_U_BOOT_START;
  40.  
  41. 	serial_puts("Starting U-Boot ...\n");
  42.  
  43. 	/*
  44. 	 * Flush caches
  45. 	 */
  46. 	flush_cache_all();
  47.  
  48. 	/*
  49. 	 * Jump to U-Boot image
  50. 	 */
  51. 	(*uboot)();

En la siguiente tabla se muestra en que archivo están declaradas las funciones utilizadas en nand_boot()


Función Archivo Descripción
jz_nand_init nand_spl/board/qi_lb60/nand_boot_jz4740.c Ajuste del timming del EMC para la NAND.
gpio_init board/qi_lb60/qi_lb60.c Inicializa los GPIOs para ser usados como NAND, SDRAM, LCD, SD, USB, Inicia el reloj de los periféricos utilizados.
serial_init cpu/mips/jz_serial.c Inicialización de la UART a 57600BPS, Sin Paridad, 8 bits de datos, bit de Stop.
serial_puts cpu/mips/jz_serial.c Función similar a printf pero la salida la realiza por la UART.
pll_init cpu/mips/jz4740.c Configuración del PLL y de los relojes del sistema y periféricos.
sdram_init cpu/mips/jz4740.c Inicialización de la SDRAM.
is_usb_boot nand_spl/board/qi_lb60/nand_boot_jz4740.c Función que permite utilizar la tecla "U" del teclado para ingresar al modo USB (Solo para BEN)
nand_load nand_spl/board/qi_lb60/nand_boot_jz4740.c Carga el binario de u-boot desde la NAND a la memoria SDRAM (0x80100000)
Proceso de Inicio de SIE.


El código de este archivo es muy similar al de la aplicación Hello World, su función es inicializar los periféricos de la plataforma y adicionalmente cargar el binario del u-boot; para esto último copia 512 << 10 (CONFIG_NAND_U_BOOT_SIZE) bytes desde la posición de memoria de la NAND (CONFIG_NAND_U_BOOT_OFFS (256 << 10)) a una dirección de memoria en la SDRAM (CONFIG_NAND_U_BOOT_DST 0x80100000) , y posteriormente fija el Contador de Programa PC a la dirección CONFIG_NAND_U_BOOT_START (0x80100000), con lo que se inicia la ejecución de u-boot.

U-boot es un bootloader que permite cargar la imágen del kernel a la memoria RAM utilizando una gran variedad de periféricos como: Puerto serie, Memoria SD, Memorias Flash Paraleas, seriales, NAND. NOR, Ethernet. Dicha imágen puede ser almacenada en varios formatos; u-boot posee un formato propio para el almacenamiento de la imágen del kernel que proporciona información sobre el tipo de sistema operativo, la dirección de carga, el punto de entrada, verificación de integridad via CRC, tipos de compresión, y textos descriptivos.

Cada plataforma posee un archivo de configuración donde se definen las características Hardware como: Parámetros de las memorias NAND y SDRAM, inicialización de periféricos y GPIOs, adicionalmente se habilitan los comandos que estarán disponibles en tiempo de ejecución como por ejemplo: comandos para la escritura de memorias no volátiles, carga de archivos a memoria RAM, etc. Este archivo se encuentra en el directorio include/configs y contiene una serie de variables de entorno que permiten la automatización del proceso de carga de la imágen del kernel, estas variables son:

CONFIG_BOOTDELAY		1
CONFIG_BOOTFILE			"uImage"	/* file to load */
CONFIG_BOOTARGS			"mem=64M console=ttyS0,57600n8 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait"
CONFIG_BOOTARGSFROMSD		"mem=64M console=ttyS0,57600n8 rootfstype=ext2 root=/dev/mmcblk0p1 rw rootwait"
CONFIG_BOOTCOMMAND		"nand read 0x80600000 0x400000 0x200000;bootm"

BOOTDELAY Indica el número de segundos que el usuario tiene para detener el proceso de inicio automático.

BOOTCOMMAND Contiene el comando que se ejecuta automáticamente cuando no se detiene el proceso de inicio automático. en este caso (nand read destino, orígen, tamaño) lee 0x200000 bytes comenzando desde la posición de memoria 0x400000 y los copia a la dirección 0x80600000 de la SDRAM y después (bootm) inicia la imágen almacenada en memoria.

BOOTARGS Parámetros que se pasan al kernel. En este caso se le indica al kernel que se cuenta con 64M de memoria RAM, que utilice el puerto serie ttyS0 configurado a 57600 BPS, 8 bits de datos, sin paridad y un bit de stop como consola, y que el sistema de archivos es UBIFS (Unsorted Block Image File System)

BOOTARGSFROMSD Esta variable muestra como utilizar un sistema de archivos almacenado en la primera partición de la SD (/dev/mmcblk0p1) la cual está formateada en ext2(rootfstype=ext2). u-boot utiliza la variable BOOTARGS para pasar parámetros al kernel, por lo que esta variable no tiene efecto alguno.

[edit] Imágen del Kernel

El punto de entrada de l kernel es la función kernel_entry definida en arch/mips/kernel/head.S, la cual hace un llamado a la función start_kernel definida en init/main.c

Personal tools
Namespaces
Variants
Actions
Navigation
interactive
Toolbox
Print/export