ldr r2, [r1, #oNFCONF]
bic r2, r2, #0x800 @ enable chip
str r2, [r1, #oNFCONF]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1
nand2:
ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq nand2
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]
@ get read to call C functions (for nand_read())
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0
@ copy U-Boot to RAM
ldr r0, =TEXT_BASE
mov r1, #0x0
mov r2, #0x20000
bl nand_read_ll 这个函数在nand_read.c中实现
tst r0, #0x0
beq ok_nand_read
bad_nand_read:
loop2: b loop2 @ infinite loop
ok_nand_read:
@ verify
mov r0, #0
ldr r1, =TEXT_BASE
mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes,这句话的意思在start.S中已注释。
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq stack_setup
bne go_next
notmatch:
loop3: b loop3 @ infinite loop
#endif @ CONFIG_S3C2410_NAND_BOOT
注:实现比较简单,同学要仔细推敲NAND工作原理,如看不懂,老师会在同学完成实验后给予讲解。其中@为注释部分,可不必写入。
(1) 用命令行模式找到_start_armboot: .word start_armboot后加入:
.align 2(前面用TAB键空出)
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
在include/configs/qt2410e.h头文件中添加nandflash的初始化信息:
(1) 找到#define CFG_ENV_IS_IN_FLASH 1并将其用//注释掉。
//#define CFG_ENV_IS_IN_FLASH 1
(2) 后面添加如下宏定义:
#define CFG_ENV_IS_IN_NAND 1
#define CFG_ENV_OFFSET 0x020000
#define CFG_NAND_BASE 0x4E000000
#define CMD_SAVEENV
#define CFG_NAND_LEGACY
#define CFG_MONITOR_BASE PHYS_SDRAM_1
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#define CFG_NAND_BASE 0x4E000000
/* NandFlash控制器在SFR区起始寄存器地址 */
#define CFG_MAX_NAND_DEVICE 1
/* 支持的最在Nand Flash数据 */
#define SECTORSIZE 512
/* 1页的大小 */
#define NAND_SECTOR_SIZE SECTORSIZE
#define NAND_BLOCK_MASK 511
/* 页掩码 */
#define ADDR_COLUMN 1
/* 一个字节的Column地址 */
#define ADDR_PAGE 3
/* 3字节的页块地址!!!!!*/
#define ADDR_COLUMN_PAGE 4
/* 总共4字节的页块地址!!!!! */
#define NAND_ChipID_UNKNOWN 0x00
/* 未知芯片的ID号 */
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
/* Nand Flash命令层底层接口函数 */
#define WRITE_NAND_COMMAND(d, adr) {rNFCMD = d;}
#define WRITE_NAND_ADDRESS(d, adr) {rNFADDR = d;}
#define WRITE_NAND(d, adr) {rNFDATA = d;}
#define READ_NAND(adr) (rNFDATA)
#define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));}
#define NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);}
#define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}
/* the following functions are NOP's because S3C24X0 handles this in hardware 一定要加上 */
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
/* 允许Nand Flash写校验 */
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
/*
* Nandflash Boot
*/
#define CONFIG_S3C2410_NAND_BOOT 1
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x8000
#define UBOOT_RAM_BASE 0x33f80000
/* NAND Flash Controller */
#define NAND_CTL_BASE 0x4E000000
#define bINT_CTL(Nb) __REG(INT_CTL_BASE + (Nb))
/* Offset */
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x0c
#define oNFSTAT 0x10
#define oNFECC 0x14
#define rNFCONF (*(volatile unsigned int *)0x4e000000)