nand boot的u-boot for sbc2410x
by panasonic.lin@163.com
Nor flash启动的uboot比较简单,下面移植nand boot的u-boot:
第一步:让从nor flash启动的u-boot支持nand flash 的读写;
第二步:从nand启动;
#########################################################################
#########################################################################
第一步步骤:
1打开nand flash驱动的支持。
在include/configs/sbc2410x.h
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
#define CONFIG_CMD_PING
+#define CONFIG_CMD_NAND
#define CONFIG_BOOTDELAY 5
@@ -211,6 +211,39 @@
#if defined(CONFIG_CMD_NAND)
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
+//#define S3C2410_NAND_BASE 0x4E000000
+#define CONFIG_SYS_NAND_BASE 0x4E000000
+
+#define SECTORSIZE 512
+
+#define ADDR_COLUMN 1
+#define ADDR_PAGE 2
+#define ADDR_COLUMN_PAGE 3
+
+#define NAND_ChipID_UNKNOWN 0x00
+#define NAND_MAX_FLOORS 1
+#define NAND_MAX_CHIPS 1
+
+#define NAND_WAIT_READY(nand) NF_WaitRB()
+
+#define NAND_DISABLE_CE(nand) NF_SetCE(NFCE_HIGH)
+#define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW)
+
+
+#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)
+#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)
+#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)
+#define WRITE_NAND(d, adr) NF_Write(d)
+#define READ_NAND(adr) NF_Read()
+/* 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)
+
+#define CONFIG_MTD_NAND_VERIFY_WRITE 1
+#define CONFIG_MTD_NAND_ECC_JFFS2 1
+
#endif /* CONFIG_CMD_NAND */
#define CONFIG_SETUP_MEMORY_TAGS
#########################################################################
#########################################################################
2:在/board/sbc2410x/sbc2410x.c
添加nand flash操作函数原型,注释掉nand_init是因为uboot支持的mtd驱动已经实现了这个函数,并且nand_probe需自己定义,uboot没有这个函数。
#if defined(CONFIG_CMD_NAND)
+
+typedef enum {
+ NFCE_LOW,
+ NFCE_HIGH
+} NFCE_STATE;
+
+static inline void NF_Conf(u16 conf)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFCONF = conf;
+}
+
+static inline void NF_Cmd(u8 cmd)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFCMD = cmd;
+}
+
+static inline void NF_CmdW(u8 cmd)
+{
+ NF_Cmd(cmd);
+ udelay(1);
+}
+
+static inline void NF_Addr(u8 addr)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFADDR = addr;
+}
+
+static inline void NF_SetCE(NFCE_STATE s)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ switch (s) {
+ case NFCE_LOW:
+ nand->NFCONF &= ~(1<<11);
+ break;
+
+ case NFCE_HIGH:
+ nand->NFCONF |= (1<<11);
+ break;
+ }
+}
+
+static inline void NF_WaitRB(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ while (!(nand->NFSTAT & (1<<0)));
+}
+
+static inline void NF_Write(u8 data)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFDATA = data;
+}
+
+static inline u8 NF_Read(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ return(nand->NFDATA);
+}
+
+static inline void NF_Init_ECC(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ nand->NFCONF |= (1<<12);
+}
+
+static inline u32 NF_Read_ECC(void)
+{
+ struct s3c2410_nand * const nand = s3c2410_get_base_nand();
+
+ return(nand->NFECC);
+}
+
+#endif
+/* dongas - support nand driver - end */
+
+#if defined(CONFIG_CMD_NAND)
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void)
@@ -168,7 +255,7 @@
NF_Reset();
}
-
+/*
void nand_init(void)
{
struct s3c2410_nand * const nand = s3c2410_get_base_nand();
@@ -179,6 +266,7 @@
#endif
printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
+*/
#endif
#ifdef CONFIG_CMD_NET
#########################################################################
#########################################################################
3.重新make之后用h-jtag烧写到nor flash,重启板子
U-Boot 2009.11 ( 4??月 16 2010 - 16:43:35)
DRAM: 64 MB
Flash: 2 MB
NAND: 64 MiB
env_relocate[252] malloced ENV at 33f512a0
In: serial
Out: serial
Err: serial
Net: CS8900-0
Hit any key to stop autoboot: 0
[Panasonic@163.com ]# nand info
Device0:NAND64MiB3,3V8bit,sectorsize16KiB
也可以输入help nand获得nand子系统的帮助。
附上补丁patch
https://static.assets-stash.eet-china.com/album/old-resources/2010/4/19/d3a84b87-d2cc-4ff5-9e92-8969363d3c04.rar
#########################################################################
#########################################################################
第二步:完全从nand boot。
这一步比较理解起来比较难,需要看很多资料,做起来却很简单。
1./include/configs/sbc2410x.h
@@ -183,35 +183,60 @@
#ifdef CONFIG_AMD_LV160
#define PHYS_FLASH_SIZE 0x00200000 /* 2MB */
#define CONFIG_SYS_MAX_FLASH_SECT (35) /* max number of sectors on one chip */
-#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x1F0000) /* addr of environment ,sector 35,1f0000-1fffff*/
+//#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x1F0000) /* addr of environment ,sector 35,1f0000-1fffff*/
注释掉CONFIG_ENV_ADDR
#endif
/* timeout values are in ticks */
#define CONFIG_SYS_FLASH_ERASE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
#define CONFIG_SYS_FLASH_WRITE_TOUT (5*CONFIG_SYS_HZ) /* Timeout for Flash Write */
+//#define CONFIG_ENV_IS_IN_FLASH 1
+//#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector,64k */
+//#define CFG_ENV_IS_IN_FLASH 1 /* Environment is in Nor Flash */
+#define CONFIG_ENV_IS_IN_NAND 1 /* Environment is in Nand Flash */
+#define CONFIG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
+#define CONFIG_ENV_OFFSET 0X40000
/*-----------------------------------------------------------------------
* NAND flash settings
*/
-#if defined(CONFIG_CMD_NAND)
+/*
+ * Nandflash Boot
+ */
添加寄存器定义和偏移
+#define CONFIG_S3C2410_NAND_BOOT 1
+#define STACK_BASE 0x33f00000
+#define STACK_SIZE 0x8000
+#define UBOOT_RAM_BASE 0x33f80000 //define the position of uboot in the sdram
+
+/* NAND Flash Controller */ //copy from vivi
+
+#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
+
+#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
-//#define S3C2410_NAND_BASE 0x4E000000
+
#define CONFIG_SYS_NAND_BASE 0x4E000000
#define SECTORSIZE 512
#########################################################################
#########################################################################
2.修改/cpu/arm920t/start.S
@@ -114,10 +114,10 @@
orr r0, r0, #0xd3
msr cpsr, r0
- bl coloured_LED_init
- bl red_LED_on
+ //bl coloured_LED_init
+ //bl red_LED_on
-#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
+#if 0//defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
/*
* relocate exception table
*/
@@ -156,7 +156,7 @@
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
- ldr r1, =0x3ff
+ ldr r1, =0x7ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
@@ -176,6 +176,8 @@
bl cpu_init_crit
#endif
注释掉relocat这一段代码
+#if 0
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
@@ -183,6 +185,8 @@
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
+
+
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
@@ -194,6 +198,79 @@
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+#endif
插入以下代码:
+#ifdef CONFIG_S3C2410_NAND_BOOT
+@ reset NAND
+
+ mov r1, #NAND_CTL_BASE
+ ldr r2, =0xf830 @ initial value
+ str r2, [r1, #oNFCONF]
+ 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 @start address
+ mov r2, #0x30000 @code size
+ bl nand_read_ll
+ 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
+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
/* Set up the stack保留了堆栈设置和清除bss这两段代码 */
stack_setup:
@@ -205,6 +282,7 @@
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
+
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
@@ -215,11 +293,16 @@
cmp r0, r1
ble clbss_l
- ldr pc, _start_armboot
-_start_armboot: .word start_armboot
+ ldr pc, _start_armboot
+_start_armboot: .word start_armboot
+#ifdef CONFIG_S3C2410_NAND_BOOT
+ .align 2
+DW_STACK_START:
+ .word STACK_BASE+STACK_SIZE-4
+#endif
#########################################################################
#########################################################################
3. 在/board/sbc2410x/
添加nand_read.c
@@ -0,0 +1,59 @@
+#include <config.h>
+
+#define __REGb(x) (*(volatile unsigned char *)(x))
+#define __REGi(x) (*(volatile unsigned int *)(x))
+#define NF_BASE 0x4e000000
+#define NFCONF __REGi(NF_BASE + 0x0)
+#define NFCMD __REGb(NF_BASE + 0x4)
+#define NFADDR __REGb(NF_BASE + 0x8)
+#define NFDATA __REGb(NF_BASE + 0xc)
+#define NFSTAT __REGb(NF_BASE + 0x10)
+
+#define BUSY 1
+inline void wait_idle(void) {
+ int i;
+
+ while(!(NFSTAT & BUSY))
+ for(i=0; i<10; i++);
+}
+
+#define NAND_SECTOR_SIZE 512
+#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
+
+/* low level nand read function */
+int
+nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
+{
+ int i, j;
+
+ if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
+ return -1; /* invalid alignment */
+ }
+
+ /* chip Enable */
+ NFCONF &= ~0x800;
+ for(i=0; i<10; i++);
+
+ for(i=start_addr; i < (start_addr + size);) {
+ /* READ0 */
+ NFCMD = 0;
+
+ /* Write Address */
+ NFADDR = i & 0xff;
+ NFADDR = (i >> 9) & 0xff;
+ NFADDR = (i >> 17) & 0xff;
+ NFADDR = (i >> 25) & 0xff;
+
+ wait_idle();
+
+ for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
+ *buf = (NFDATA & 0xff);
+ buf++;
+ }
+ }
+
+ /* chip Disable */
+ NFCONF |= 0x800; /* chip disable */
+
+ return 0;
+}
#########################################################################
#########################################################################
/board/sbc2410x/Makefile
@@ -25,7 +25,7 @@
LIB = $(obj)lib$(BOARD).a
-COBJS := sbc2410x.o flash.o
+COBJS := sbc2410x.o flash.o nand_read.o
SOBJS := lowlevel_init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
#########################################################################
#########################################################################
/board/sbc2410x/flash.c 注释掉nor 的保护,因为环境变量保存在nand中了。
@@ -110,7 +110,7 @@
}
size += flash_info.size;
}
-
+/*
flash_protect (FLAG_PROTECT_SET,
CONFIG_SYS_FLASH_BASE,
CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
@@ -119,7 +119,7 @@
flash_protect (FLAG_PROTECT_SET,
CONFIG_ENV_ADDR,
CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
-
+*/
return size;
}
#########################################################################
#########################################################################
最后,新版uboot的makefile变化了这里,结果导致start.S的nand拷贝自己代码排在了4k空间以后,启动不了。
./u-boot-2009-11-sbc2410x-nand-boot/Makefile
@@ -291,7 +291,7 @@
endif
__OBJS := $(subst $(obj),,$(OBJS))
-__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD))
+__LIBS := $(subst $(obj),,$(LIBBOARD)) $(subst $(obj),,$(LIBS))
#########################################################################
#########################################################################
make后生成u-boot.bin,拷贝到tftp输出文件夹。
启动nor中的uboot
[Panasonic@163.com ]# tftp 30000000 u-boot-nand-boot.bin
Using CS8900-0 device
TFTP from server 192.168.0.1; our IP address is 192.168.0.2
Filename 'u-boot-nand-boot.bin'.
Load address: 0x30000000
Loading: ###########
done
Bytes transferred = 151016 (24de8 hex)
[Panasonic@163.com ]# nand erase 0 42000
NAND erase: device 0 offset 0x0, size 0x42000
Erasing at 0x210000 -- 262144% complete.
OK
[Panasonic@163.com ]# nand write 30000000 0 42000
NAND write: device 0 offset 0x0, size 0x42000
270336 bytes written: OK
#########################################################################
#########################################################################
最后跳线从nand启动
U-Boot 2009.11 ( 4??月 19 2010 - 14:25:22)
DRAM: 64 MB
Flash: 2 MB
NAND: 64 MiB
env_relocate[252] malloced ENV at 33f5d2a0
*** Warning - bad CRC or NAND, using default environment
In: serial
Out: serial
Err: serial
Net: CS8900-0
Hit any key to stop autoboot: 0
[Panasonic@163.com ]# nand info
Device 0: NAND 64MiB 3,3V 8-bit, sector size 16 KiB
[Panasonic@163.com ]# saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x4 -- 262144% complete.
Writing to Nand... done
附上patch
https://static.assets-stash.eet-china.com/album/old-resources/2010/4/19/7e9ff743-40a1-4359-8c13-78a444d540d3.rar
文章评论(0条评论)
登录后参与讨论