U-boot-2014.10 transplantation 25th days ---- nand flash Boot (3), uboot2014.10 Transplantation
Hardware Platform: tq2440
Development Environment: Ubuntu-3.11
U-boot: 2014.10
This article allows reprint, please indicate the source: http://blog.csdn.net/fulinus
Before u-boot is started from nand flash, we put the previous asm_led program in the first 4Kbit of the first block of nand flash, because asm_led does not have the system initialization function, therefore, you also need to place the bootstrap program at the 0 address of nand flash. After bootstrap initializes 2440, it jumps to the asm_led program for execution. This is of great significance for understanding how to start from nand flash.
Create a directory:
$ mkdir nand-boot
The nand-boot directory contains the following files:
$ lsmakefile nand-boot.h nand-boot.S
The content of the three files is as follows:
Nand-boot.h:
#define S3C_WATCHDOG_BASE 0x53000000#define S3C_INTERRUPT_BASE 0x4a000000#define SRCPND_OFFSET 0x00#define INTMOD_OFFSET 0x04#define INTMSK_OFFSET 0x08#define PRIORITY_OFFSET 0x0c#define INTPND_OFFSET 0x10#define INTOFFSET_OFFSET 0x14#define SUBSRCPND_OFFSET 0x18#define INTSUBMSK_OFFSET 0x1c#define S3C_CLOCK_POWER_BASE 0x4c000000#define LOCKTIME_OFFSET 0x00#define MPLLCON_OFFSET 0x04#define UPLLCON_OFFSET 0x08#define CLKCON_OFFSET 0x0c#define CLKSLOW_OFFSET 0x10#define CLKDIVN_OFFSET 0x14#define CAMDIVN_OFFSET 0x18#define BWSCON 0x48000000#define MDIV_405 0x7f << 12#define PSDIV_405 0x21#define GPBCON 0x56000010#define GPBDAT 0x56000014#define GPBUP 0x56000018#define OUTPUT 0x01 /* Set GPIO port as output mode*/#define INPUT 0x00 /* Set GPIO port as input mode*/#define LED0 5 /*On TQ2440 board, LED0 use GPB5*/#define LED1 6 /*On TQ2440 board, LED1 use GPB6*/#define LED2 7 /*On TQ2440 board, LED2 use GPB7*/#define LED3 8 /*On TQ2440 board, LED3 use GPB8*/#define DELAY 0X1000000#define BEEP 0 /* On FL2440 board, LED0 use GPB0*//* BWSCON */#define DW8 (0x0)#define DW16 (0x1)#define DW32 (0x2)#define WAIT (0x1<<2)#define UBLB (0x1<<3)#define B1_BWSCON (DW16)#define B2_BWSCON (DW16)#define B3_BWSCON (DW16 + WAIT + UBLB)#define B4_BWSCON (DW16)#define B5_BWSCON (DW16)#define B6_BWSCON (DW32)#define B7_BWSCON (DW32)#define B0_Tacs 0x0#define B0_Tcos 0x0#define B0_Tacc 0x7#define B0_Tcoh 0x0#define B0_Tah 0x0#define B0_Tacp 0x0#define B0_PMC 0x0#define B1_Tacs 0x0#define B1_Tcos 0x0#define B1_Tacc 0x7#define B1_Tcoh 0x0#define B1_Tah 0x0#define B1_Tacp 0x0#define B1_PMC 0x0 #define B2_Tacs 0x0#define B2_Tcos 0x0#define B2_Tacc 0x7#define B2_Tcoh 0x0#define B2_Tah 0x0#define B2_Tacp 0x0#define B2_PMC 0x0#define B3_Tacs 0xc#define B3_Tcos 0x7#define B3_Tacc 0xf#define B3_Tcoh 0x1#define B3_Tah 0x0#define B3_Tacp 0x0#define B3_PMC 0x0#define B4_Tacs 0x0#define B4_Tcos 0x0#define B4_Tacc 0x7#define B4_Tcoh 0x0#define B4_Tah 0x0#define B4_Tacp 0x0#define B4_PMC 0x0#define B5_Tacs 0xc#define B5_Tcos 0x7#define B5_Tacc 0xf#define B5_Tcoh 0x1#define B5_Tah 0x0#define B5_Tacp 0x0#define B5_PMC 0x0#define B6_MT 0x3 /* SDRAM */#define B6_Trcd 0x1#define B6_SCAN 0x1 /* 9bit */#define B7_MT 0x3 /* SDRAM */#define B7_Trcd 0x1 /* 3clk */#define B7_SCAN 0x1 /* 9bit *//* REFRESH parameter */#define REFEN 0x1 /* Refresh enable */#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */#define Trc 0x3 /* 7clk */#define Tchr 0x2 /* 3clk */#if defined(CONFIG_S3C2440)#define Trp 0x2 /* 4clk */#define REFCNT 1012#else#define Trp 0x0 /* 2clk */#define REFCNT 0x0459#endif
Nand-boot.S:
#include "nand-boot.h" .text .align 2 .global _start_start: /* set the cpu to SVC32 mode */ mrs r0, cpsr bic r0, r0, #0x1f orr r0, r0, #0xd3 msr cpsr, r0 /* Disable watchdog */ ldr r0, =S3C_WATCHDOG_BASE mov r1, #0 str r1, [r0] /* Disable Interrupt */ ldr r0, =S3C_INTERRUPT_BASE mov r1, #0xffffffff str r1, [r0, #INTMSK_OFFSET] ldr r1, =0x000007ff str r1, [r0, #INTSUBMSK_OFFSET] /* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0290g/Babjcgjg.html */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache, Invalidate ICache and DCache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ /* disable MMU stuff and caches */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0 /******************************************************************************************* * Init system clock and power, FCLK:HCLK:PCLK = 1:4:8 * Reference to S3C2440 datasheet: Chap 7 Clock&Power Management * * Initialize System Clock FCLK=400MHz HCLK=100MHz PCLK=50MHz * FCLK is used by ARM920T * HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, * the interrupt controller, the LCD controller, the DMA and USB host block. * PCLK is is used for APB bus,which is used by the peripherals such as WDT,IIS,I2C, * PWM timer,MMC interface,ADC,UART,GPIO,RTC and SPI. ******************************************************************************************/ /*Set LOCKTIME as default value 0x00ffffff*/ ldr r0, =S3C_CLOCK_POWER_BASE ldr r1, =0x00ffffff str r1, [r0, #LOCKTIME_OFFSET] /******************************************************************************************* * Reference to S3C2440 datasheet: Chap 7-8 ~ Page 242 * * Set the selection of Dividing Ratio between FCLK,HCLK and PCLK as FCLK:HCLK:PCLK = 1:4:8. * This ratio is determined by HDIVN(here is 2) and PDIVN(here is 1) control register. * Refer to the s3c2440 datasheet *******************************************************************************************/ ldr r0, =S3C_CLOCK_POWER_BASE mov r1, #5 str r1, [r0, #CLKDIVN_OFFSET] /*Set Clock Divider*/ mrc p15, 0, r1, c1, c0, 0 orr r1, r1, #0xc0000000 mcr p15, 0, r1, c1, c0, 0 /*************************************************************************************** * Reference to S3C2440 datasheet: Chap 7-20 ~ Page 254 * * Set MPLLCON(0x4C000004) register as: * [19:12]: MDIV(Main Divider control)=0x7F (value set in MDIV_405) * [9:4]: PDIV(Pre-devider control)=0x02 (value set in PSDIV_405) * [1:0]: SDIV(Post divider control)=0x01 (value set in PSDIV_405) * * MPLL(FCLK) = (2 * m * Fin)/(p * 2^s) * m=(MDIV+8), p=(PDIV+2), s=SDIV * * So FCLK=((2*(127+8)*Fin)) / ((2+2)*2^1) * = (2*135*12MHz)/8 * = 405MHz * For FCLK:HCLK:PCLK=1:4:8, so HCLK=100MHz, PCLK=50MHz ***************************************************************************************/ mov r1, #S3C_CLOCK_POWER_BASE mov r2, #MDIV_405 add r2, r2, #PSDIV_405 str r2, [r1, #MPLLCON_OFFSET]mem_init: /* memory control configuration */ /* make r0 relative the current location so that it */ /* reads SMRDATA out of FLASH rather than memory ! */ ldr r0, =SMRDATA ldr r1, =mem_init sub r0, r0, r1 adr r3, mem_init /* r3 <- current position of code */ add r0, r0, r3 /*r0 =SMRDATA-mem_init+mem_init =SMRDATA*/ ldr r1, =BWSCON /* Bus Width Status Controller */ add r2, r0, #13*40: ldr r3, [r0], #4 str r3, [r1], #4 cmp r2, r0 bne 0b /*Set GPIO5 OUTPUT mode*/ ldr r0, =GPBCON ldr r1, [r0] bic r1, r1, #0xC00 /*Set GPBCON for GPIO5 as 0x00 */ orr r1, r1, #0x0400 /*Set GPBCON for GPIO5 as GPIOOUT, 0x01*/ str r1, [r0] ldr r3, [r2] bic r3, r3, #(1<<LED0) /*Clear bit 5, set GPB5 as low level*/ str r3, [r2] /*Set GPB5,GPB6,GPB7,GPB8 as GPIO OUTPUT mode*/ ldr r0, =GPBCON ldr r1, [r0] bic r1, r1, #0x3Fc00 /*Set GPBCON for GPB5,GPB6,GPB7,GPB8 as 0x00 */ orr r1, r1, #0x15400 /*Set GPBCON for GPB5,GPB6,GPB7,GPB8 as GPIOOUT, 0x01*/ str r1, [r0] /*Set internal pullup resister*/ ldr r0, =GPBUP ldr r1, [r0] orr r1, r1, #0x01E0 /*Set bit 5,6,7,8, disable pullup resister*/ @bic r1, r1, #0x01E0 /*Clear bit 5,6,7,8, enable pullup resister*/ str r1, [r0] loopled: /*Turn off LED0, LED1, LED2, LED3*/ ldr r2, =GPBDAT ldr r3, [r2] orr r3, r3, #0x01E0 /*Set bit 5,6,7,8 as high level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay /*Turn on LED0*/ ldr r3, [r2] bic r3, r3, #(1<<LED0) /*Clear bit 5, set GPB5 as low level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay /*Turn on LED1*/ ldr r3, [r2] bic r3, r3, #(1<<LED1) /*Clear bit 6, set GPB6 as low level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay /*Turn on LED2*/ ldr r3, [r2] bic r3, r3, #(1<<LED2) /*Clear bit 7, set GPB7 as low level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay /*Turn on LED3*/ ldr r3, [r2] bic r3, r3, #(1<<LED3) /*Clear bit 8, set GPB8 as low level*/ str r3, [r2] ldr r0, =DELAY /*Sleep for a while*/ bl delay b loopled /*Loop running LED*/ /* everything is fine now */dead_loop: b dead_loop .ltorg/* the literal pools origin */SMRDATA: .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) .word 0xb2 .word 0x30 .word 0x30delay: sub r0, r0, #1 cmp r0, #0x0 bne delay mov pc, lr
Makefile:
# ***********************************************************************# * File: makefile# * Version: 1.0.0# * Copyright: 2011 (c) Guo Wenxue <guowenxue@gmail.com># * Description: Makefile used to cross compile the ASM and C source code# * ChangeLog: 1, Release initial version on "Mon Mar 21 21:09:52 CST 2011"# *# ***********************************************************************BINAME = nand-bootTEXTBASE = 0x33000000INST_PATH=${PWD}/../../../binCROSS = arm-linux-CC = $(CROSS)gccLD = $(CROSS)ldAR = $(CROSS)arOBJCOPY = $(CROSS)objcopyOBJDUMP = $(CROSS)objdumpSTRIP = $(CROSS)stripREADELF = $(CROSS)readelfCFLAGS = -g -O2 -Wall -nostdinc -nostdlib -fno-builtinAFLAGS = $(CFLAGS) -D__ASSEMBLY__LDFLAGS = -Ttext $(TEXTBASE)SRC_C = $(wildcard *.c)SRC_S = $(wildcard *.S)OBJ_C = $(patsubst %.c,%.o,$(SRC_C)) OBJ_S = $(patsubst %.S,%.o,$(SRC_S)) OBJ_ALL = $(OBJ_C) $(OBJ_S) .PHONY : all all: ${OBJ_ALL} ${LD} $(LDFLAGS) -o ${BINAME}.elf ${OBJ_ALL} ${OBJCOPY} -O binary -S ${BINAME}.elf ${BINAME}.bin rm -f *.elf *.o make install%.o: %.S $(CC) $(AFLAGS) -c -o $@ $<%.o: %.c $(CC) $(CFLAGS) -c -o $@ $<install: cp -f ${BINAME}.bin ${INST_PATH} uninstall: rm -f ${INST_PATH}/${BINAME}.bin clean: rm -f *.elf *.o rm -f ${BINAME}.bin
First, test whether the above program can be run. Set the development board to the nand flash startup mode, because at this time, the 0 address of s3c2440 is mapped to the 4KDRAM in the s3c2440, after the above program is compiled, burn it to the address 0 through J-link commander and run the following command:
$h$speed 12000$loadbin D:\kupan\temp\nand-boot.bin 0$setpc 0$g
The running result led shows the running result, indicating that the program is normal. Next we will burn the nand-boot.bin program to the memory through tftp through the u-boot that we can run earlier, write nand flash to nand flash through u-boot. perform the following operations: 1. First, place the Development Board in Nor flash to start; 2. Install bootstrap through j-link. bin and u-boot.bin files to SDRAM; 3. test whether the server can be connected:
[TQ2440 #] ping 192.168.169.8
Show normal 4. Download The nand-boot.bin to SDRAM via tftp:
[TQ2440 #] tftp 30008000 nand-boot.bin
5. Burn it into nand flash:
[TQ2440 #] nand dump 0Page 00000000 dump: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffOOB: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff[TQ2440 #] nand write 30008000 0 512[TQ2440 #] nand dump 0 Page 00000000 dump: 00 00 0f e1 1f 00 c0 e3 d3 00 80 e3 00 f0 29 e1 53 04 a0 e3 00 10 a0 e3 00 10 80 e5 4a 04 a0 e3 00 10 e0 e3 08 10 80 e5 38 11 9f e5 1c 10 80 e5 00 00 a0 e3 17 0f 07 ee 17 0f 08 ee 10 0f 11 ee 23 0c c0 e3 87 00 c0 e3 02 00 80 e3 01 0a 80 e3 10 0f 01 ee 13 03 a0 e3 ff 14 e0 e3 00 10 80 e5 13 03 a0 e3 05 10 a0 e3 14 10 80 e5 10 1f 11 ee 03 11 81 e3 10 1f 01 ee 13 13 a0 e3 7f 2a a0 e3 21 20 82 e2 04 20 81 e5 dc 00 9f e5 dc 10 9f e5 01 00 40 e0 14 30 4f e2 03 00 80 e0 12 13 a0 e3 34 20 80 e2 04 30 90 e4 04 30 81 e4 00 00 52 e1 fb ff ff 1a b8 00 9f e5 00 10 90 e5 03 1b c1 e3 01 1b 81 e3 00 10 80 e5 00 30 92 e5 20 30 c3 e3 00 30 82 e5 98 00 9f e5 00 10 90 e5 ff 1b c1 e3 55 1b 81 e3 00 10 80 e5 88 00 9f e5 00 10 90 e5 1e 1e 81 e3 00 10 80 e5 7c 20 9f e5 00 30 92 e5 1e 3e 83 e3 00 30 82 e5 01 04 a0 e3 28 00 00 eb 00 30 92 e5 20 30 c3 e3 00 30 82 e5 01 04 a0 e3 23 00 00 eb 00 30 92 e5 40 30 c3 e3 00 30 82 e5 01 04 a0 e3 1e 00 00 eb 00 30 92 e5 80 30 c3 e3 00 30 82 e5 01 04 a0 e3 19 00 00 eb 00 30 92 e5 01 3c c3 e3 00 30 82 e5 01 04 a0 e3 14 00 00 eb e4 ff ff ea fe ff ff ea ff 07 00 00 80 01 00 33 88 00 00 33 10 00 00 56 18 00 00 56 14 00 00 56 10 d1 11 22 00 07 00 00 00 07 00 00 00 07 00 00 40 c7 01 00 00 07 00 00 40 c7 01 00 05 80 01 00 05 80 01 00 59 04 8e 00 b2 00 00 00 30 00 00 00 30 00 00 00 01 00 40 e2 00 00 50 e3 fc ff ff 1a 0e f0 a0 e1 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffOOB: 69 ff 99 00 ff ff ff ff ff ff ff ff ff ff ff ff
We can see that the nand-boot.bin has been written into the nand flash. 6. Set the system to nand flash to start. The running horse lamp is displayed, indicating that the above idea is correct.
Continue tomorrow.