Boot Process

From Qi-Hardware
Jump to: navigation, search


[edit] Boot Process for SIE

[edit] Internal ROM

The JZ4725 has an integrated ROM with 4KB in the memory range 0x1FC00000 - 0x1FC01000; this memory is connected to the External Memory Controller (EMC). After a processor reset, the processor runs the program contained in the ROM memory, and depending on the values of the boot_sel[1:0] flags carries out the following operations:

00 Unused
01 Initialization via USB port: Receives a block of data through the USB (device) port and stores it in internal SRAM.
10 Initialization via NAND memory with 512-byte pages at Chip Select 1 (CS1):
11 Initialization via NAND memory with 2048-byte pages at Chip Select 1 (CS1): Reads the first byte from NAND to determine whether the bus is 8- or 16-bit (if bit[7:4] = 0, it is 16-bit), and the number of cycles per page is 2 or 3 (if bit[3:0] = 0, it is 2 cycles). Adjusts the EMC using this information and copies the first 8kB from NAND to the internal SRAM. The NAND for the SIE has 8-bit data, 3 cyles, and 4096 bytes per page, so the first byte should be 0xFF

[edit] NAND Initialization

The next figure shows the initialization process from the RAM to the JZ472X processors. Once the number of bits and number of cycles per page is determined, using this it reads 8KB from NAND starting at the memory position 0x0. If no ECC errors are encountered or those encountered can be corrected, the program jumps to the memory position 0x80000004; if an uncorrectible error is encountered, the program will read backup information from the memory position 0x2000 and if no uncorrectible error exists it jumps to the memory position 0x80000004 of the internal SRAM; otherwise it will carry out initialization from the NOR memory at CS4.

Nand Initialization (based on the JZ4725 processor reference manual).

[edit] U-boot

Just like BEN, SAKC uses the Ingenic-provided U-boot, which has been modified by Qi-Hardware developers in order to adapt it to their platforms.

In both platforms the startup process is the same, the usbboot app is used in order to load the file openwrt-xburst-u-boot.bin, to the NAND, following this tutorial. The source code of u-boot can be obtained following this instructions; the code will be stored in the openwrt-xburst/build_dir/linux-xburst/u-boot-2009.11 folder.

[edit] start.S

The openwrt-xburst-u-boot.bin file is made of two sections: First Stage loader y u-boot (see figure below). The first subroutine ran is the _start, which is defined in /cpu/mips/start.S, this subroutine makes a call to the reset function, defined on the same file, which code is shown next:

  2. 	.globl _start
  3.  	.text
  4.         .word JZ4740_NANDBOOT_CFG /*(0xffffffff) NAND 8 Bits 3 cycles */
  5.          b reset; nop    /* U-boot entry point */
  6.          b reset; nop    /* software reboot */ 
  7. reset:
  8.  	/*
  9.   	 * CU0=UM=EXL=IE=0, BEV=ERL=1, IP2~7=1 	 */
  10.  	li	t0, 0x0040FC04       /*t0 = 0x0040FC04 */
  11.  	mtc0	t0, CP0_STATUS       /*CP0_STAT = 0x0040FC04 Normal mode processor,
  12.                                        disable interrupts, Exception 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*/
  18.   	/* Init Timer */
  19.  	mtc0	zero, CP0_COUNT      /*Address at which processing resumes after an exception*/
  20.  	mtc0	zero, CP0_COMPARE    /**/
  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
  32.   	la	sp, 0x80004000
  33.  	la	t9, nand_boot
  34.  	j	t9
  35.  	nop

In the previous code it can be seen that after the start label, which indicates the text section beginning(The text section is where the instructions that will be executed are stored), the word JZ4740_NANDBOOT_CFG is defined (line 3), which in our case corresponds to 0xffffffff. This guarantees that the first byte stored in the NAND memory will be 0xFF; this indicates to our startup program that the ROM memory we have is an 8-bit 3-cycle memory.

After this, there is an uncoditional branch to the reset subroutine(line 4) where the coprocessor registers STATUS, CAUSE, COUNT and COMPARE, are set. On line 24 a jump to the 1: label is done and the value PC + 8 is stored on RA; on line 28 the value in RA is stored in the global pointer gp; On line 32 the stack pointer (sp) is fixed to the 0x80004000 adress and finally there is a call to the nand_boot function defined in nand_spl/nand_boot_jz4740.c:

[edit] nand_boot()

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

In the following table, the files where the functions used by nand_boot() are declared.

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.
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.

The source code for this file is pretty similar to the one from Hello World, its objective is to initialize the platform's peripherals, plus, loading the u-boot binary file; In order to do this, it copies 512 << 10 (CONFIG_NAND_U_BOOT_SIZE) bytes from the NAND memory adress (CONFIG_NAND_U_BOOT_OFFS (256 << 10)) to a SDRAM memory adress (CONFIG_NAND_U_BOOT_DST 0x80100000). After that, it fixes the Program Counter PC to the adress CONFIG_NAND_U_BOOT_START (0x80100000), after which the u-boot is executed. U-boot is a bootloader that allows to load the kernel image to the RAM memory, using a variety of peripherals, such as, Serial ports, SD card, parallel Flash memories, NAND memories, NOR memories, Ethernet, etc. The kernel image can be stored in different formats; u-boot has its own format for the kernel image storage, which gives information about the OS, the load adress, the starting adress, CRC checksum, compression types, and further description. Each olatform has a configuration file, where hardware characteristics are defined, characteristics such as: NAND and SDRAM parameters, Peripherals and GPIO's Startup, etc. Also, the commands available while running U-boot are enabled, for example, Write commands for non-volatile memories, file loading to RAM memory, etc. This file can be found in the include/configs folder, and it contains a set of environment variables that allow the automation of the kernel image loading process, this variables are:

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 Indicates the time in seconds that the user has to stop the automatic process.

BOOTCOMMAND Contains the command that will be automatically executed when the automatic process is not stopped. In this case(nand read destino, orígen, tamaño) reads 0x200000 bytes starting from memory adress 0x400000 and it copies them to the 0x80600000 adress of the SDRAM and after (bootm) starst the stored image form memory.

BOOTARGS Parameters given to the kernel. In this case, the kernel is told that there is a total of 64M RAM memory available, and that it has to use the serial port ttyS0 set up to 57600 BPS, 8-bit word, none parity and one bit of stop as console, also the kernel is told about the type of the filesystem, which is UBIFS (Unsorted Block Image File System)

BOOTARGSFROMSD This variable shows how to use a filesystem stored in the first partition of a SD card SD (/dev/mmcblk0p1) which is formatted in ext2(rootfstype=ext2). U-boot uses the BOOTARGS variable in order to pass parameters to the kernel, so this variable has no effect at all.

[edit] Kernel Image

Personal tools