移植 u-boot 1.1.6 到 embest edukit-III s3c2410 开发板

来源:互联网 发布:搜索引擎优化期末考试 编辑:程序博客网 时间:2024/06/05 10:10

一、先实现可从nand flash启动

1.在u-boot-1.2.0/Makefile中

diff -urNu-boot-1.2.0.orig/Makefile u-boot-1.2.0/Makefile
---u-boot-1.2.0.orig/Makefile 2007-01-0707:13:11.000000000 +0800
+++u-boot-1.2.0/Makefile 2007-09-1912:09:20.000000000 +0800
@@ -125,7+125,7 @@
 CROSS_COMPILE = powerpc-linux-
 endif
 ifeq ($(ARCH),arm)
-CROSS_COMPILE = arm-linux-
+CROSS_COMPILE =/usr/local/arm/arm-2007q1/bin/arm-none-linux-gnueabi-
 endif 

这是需要修改的第一段代码

其实就是把/u-boot-1.2.0/Makefile程序第125行改了,其实就是设定交叉编译器,这段代码是很好的学习材料

这就是一个补丁的制作过程

diff:以u-boot-1.2.0/Makefile为目标文件,以u-boot-1.2.0.orig/Makefile为源文件

 

2.在u-boot-1.2.0/board/smdk2410/中

Makefile

diff -urN u-boot-1.2.0.orig/board/smdk2410/Makefileu-boot-1.2.0/board/smdk2410/Makefile
---u-boot-1.2.0.orig/board/smdk2410/Makefile 2007-01-0707:13:11.000000000 +0800
+++u-boot-1.2.0/board/smdk2410/Makefile 2007-09-1912:22:24.000000000 +0800
@@ -25,7 +25,7 @@
 
 LIB = $(obj)lib$(BOARD).a
 
-COBJS := smdk2410.o flash.o
+COBJS := smdk2410.o flash.onand_read.o
 SOBJS :=lowlevel_init.o
 
 SRCS := $(SOBJS:.o=.S)$(COBJS:.o=.c)

 

lowlevel_init.S


diff -urNu-boot-1.2.0.orig/board/smdk2410/lowlevel_init.Su-boot-1.2.0/board/smdk2410/lowlevel_init.S
---u-boot-1.2.0.orig/board/smdk2410/lowlevel_init.S 2007-01-0707:13:11.000000000 +0800
+++u-boot-1.2.0/board/smdk2410/lowlevel_init.S 2007-09-1912:22:08.000000000 +0800
@@ -123,7 +123,7 @@
 #define Trp   0x0 
 #define Trc   0x3 
 #define Tchr   0x2 
-#define REFCNT   1113 
+#defineREFCNT   1268 
 
 
 _TEXT_BASE:

 

新建文件nand_read.c


diff -urNu-boot-1.2.0.orig/board/smdk2410/nand_read.cu-boot-1.2.0/board/smdk2410/nand_read.c
---u-boot-1.2.0.orig/board/smdk2410/nand_read.c 1970-01-0108:00:00.000000000 +0800
+++u-boot-1.2.0/board/smdk2410/nand_read.c 2007-09-1912:24:13.000000000 +0800
@@ -0,0 +1,77 @@
+
+
+#include<config.h>
+
+#ifdef CONFIG_S3C2410_NAND_BOOT
+
+#define __REGb(x) (*(volatile unsigned char*)(x))
+#define __REGi(x) (*(volatile unsigned int*)(x))
+#defineNF_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) {
+    inti;
+
+   while(!(NFSTAT & BUSY))
+     for(i=0; i<10; i++);
+}
+
+#define NAND_SECTOR_SIZE 512
+#defineNAND_BLOCK_MASK  (NAND_SECTOR_SIZE- 1)
+
+
+int
+nand_read_ll(unsigned char *buf, unsigned long start_addr, intsize)
+{
+    int i,j;
+
+    if((start_addr & NAND_BLOCK_MASK) || (size& NAND_BLOCK_MASK)) {
+       return -1; 
+    }
+
+   
+    NFCONF&= ~0x800;
+    for(i=0;i<10; i++);
+
+   for(i=start_addr; i < (start_addr + size);) {
+     
+     NFCMD = 0;
+
+     
+     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++;
+     }
+    }
+
+   
+    NFCONF |=0x800; 
+
+    return0;
+}
+
+#endif

 

smdk2410.c

diff -urN u-boot-1.2.0.orig/board/smdk2410/smdk2410.cu-boot-1.2.0/board/smdk2410/smdk2410.c
---u-boot-1.2.0.orig/board/smdk2410/smdk2410.c 2007-01-0707:13:11.000000000 +0800
+++u-boot-1.2.0/board/smdk2410/smdk2410.c 2007-09-1912:21:39.000000000 +0800
@@ -36,10 +36,10 @@
 #define M_MDIV 0xC3
 #define M_PDIV 0x4
 #define M_SDIV 0x1
-#elif FCLK_SPEED==1  
-#define M_MDIV 0xA1
-#define M_PDIV 0x3
-#define M_SDIV 0x1
+#elifFCLK_SPEED==1  
+#define M_MDIV 0x5C
+#define M_PDIV 0x4
+#defineM_SDIV 0x0
 #endif
 
 #define USB_CLOCK 1
@@ -87,7 +87,7 @@
 
  
  gpio->GPACON =0x007FFFFF;
- gpio->GPBCON = 0x00044555;
+ gpio->GPBCON =0x000055A;
  gpio->GPBUP= 0x000007FF;
  gpio->GPCCON =0xAAAAAAAA;
  gpio->GPCUP =0x0000FFFF;
@@ -99,7 +99,7 @@
  gpio->GPFUP =0x000000FF;
  gpio->GPGCON =0xFF95FFBA;
  gpio->GPGUP =0x0000FFFF;
- gpio->GPHCON = 0x002AFAAA;
+ gpio->GPHCON =0x0016FAAA;
  gpio->GPHUP= 0x000007FF;

 

3.在u-boot-1.2.0/cpu/arm920t中

start.S(第一层汇编程序入口)

diff -urN u-boot-1.2.0.orig/cpu/arm920t/start.Su-boot-1.2.0/cpu/arm920t/start.S
---u-boot-1.2.0.orig/cpu/arm920t/start.S 2007-01-0707:13:11.000000000 +0800
+++ u-boot-1.2.0/cpu/arm920t/start.S 2007-09-1912:37:00.000000000 +0800
@@ -27,7 +27,7 @@
 
 #include<config.h>
 #include<version.h>
-
+#include<s3c2410.h>
 
 
  ldr r0,=INTSUBMSK
  str r1,[r0]
 # endif
@@ -161,6 +161,7 @@
 #endif
 
 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
+#ifndefCONFIG_S3C2410_NAND_BOOT
 relocate:    
  adr r0,_start  
  ldr r1,_TEXT_BASE  
@@ -177,8 +178,67 @@
  stmia r1!,{r3-r10}  
  cmp r0,r2   
  ble copy_loop
+#else
+relocate:
+copy_myself:
+ @ reset NAND
+ mov r1,#S3C2410_NAND_BASE
+ ldr r2,=0xf830  @ initial valueenable
+ 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
+1: add r3, r3, #0x1
+ cmp r3, #0xa
+ blt 1b
+2: ldr r2, [r1,#oNFSTAT] @ wait ready
+ tst r2, #0x1
+ beq 2b
+ ldr r2, [r1, #oNFCONF]
+ orr r2, r2,#0x800  @ disable chip
+ str r2, [r1, #oNFCONF]
+

+ ldr r0,_TEXT_BASE   
+ sub r0, r0,#CFG_MALLOC_LEN  
+ sub r0, r0,#CFG_GBL_DATA_SIZE 
+#ifdef CONFIG_USE_IRQ
+ sub r0, r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+ sub sp, r0,#12   
+
+ @ copy u-boot to RAM
+ ldr r0, _TEXT_BASE
+ mov    r1, #0x0
+ mov r2, #CFG_UBOOT_SIZE
+ bl nand_read_ll
+
+ tst r0, #0x0
+ beq ok_nand_read
+
+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 done_nand_read
+ bne go_next
+notmatch:
+1: b 1b
+done_nand_read:
+#endif
 #endif 
 
+#ifndefCONFIG_S3C2410_NAND_BOOT
  
 stack_setup:
  ldr r0,_TEXT_BASE  


@@ -188,6 +248,7 @@
  sub r0, r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
 #endif
  sub sp, r0,#12  
+#endif
 
 clear_bss:
  ldr r0,_bss_start  

 

4.在u-boot-1.2.0/include/Configs/smdk2410.h中

diff -urN u-boot-1.2.0.orig/include/configs/smdk2410.hu-boot-1.2.0/include/configs/smdk2410.h
---u-boot-1.2.0.orig/include/configs/smdk2410.h 2007-01-0707:13:11.000000000 +0800
+++u-boot-1.2.0/include/configs/smdk2410.h 2007-09-1912:42:45.000000000 +0800
@@ -82,6 +82,8 @@
    /
    /
    /
+   CFG_CMD_NET | /
+   CFG_CMD_PING |/
    CFG_CMD_REGINFO | /
    CFG_CMD_DATE | /
    CFG_CMD_ELF)
@@ -91,10 +93,10 @@
 
 #define CONFIG_BOOTDELAY 3
 
-
+#defineCONFIG_ETHADDR  08:00:3e:26:0a:5b
 #defineCONFIG_NETMASK         255.255.255.0
-#defineCONFIG_IPADDR  10.0.0.110
-#defineCONFIG_SERVERIP  10.0.0.1
+#defineCONFIG_IPADDR  192.168.1.110
+#defineCONFIG_SERVERIP  192.168.1.216
 
 
 
@@ -108,7 +110,7 @@
  * Miscellaneous configurable options
  */
 #define CFG_LONGHELP    
-#define CFG_PROMPT  "SMDK2410# " 
+#define CFG_PROMPT  "U-boot#" 
 #define CFG_CBSIZE  256  
 #define CFG_PBSIZE(CFG_CBSIZE+sizeof(CFG_PROMPT)+16)
 #define CFG_MAXARGS  16  
@@ -178,4 +180,8 @@
 #define CFG_ENV_IS_IN_FLASH 1
 #defineCFG_ENV_SIZE  0x10000 
 
+
+#define CONFIG_S3C2410_NAND_BOOT
+#defineCFG_UBOOT_SIZE  0x20000
+
 #endif

5.在u-boot-1.2.0/include/s3c2410.h

diff -urN u-boot-1.2.0.orig/include/s3c2410.hu-boot-1.2.0/include/s3c2410.h
--- u-boot-1.2.0.orig/include/s3c2410.h 2007-01-0707:13:11.000000000 +0800
+++ u-boot-1.2.0/include/s3c2410.h 2007-09-1912:38:31.000000000 +0800
@@ -38,12 +38,6 @@
 #defineS3C2410_ECCSIZE  512
 #define S3C2410_ECCBYTES 3
 
-typedef enum {
- S3C24X0_UART0,
- S3C24X0_UART1,
- S3C24X0_UART2
-} S3C24X0_UARTS_NR;
-
 
 #defineS3C24X0_MEMCTL_BASE  0x48000000
 #defineS3C24X0_USB_HOST_BASE  0x49000000
@@ -64,10 +58,23 @@
 #defineS3C24X0_SPI_BASE  0x59000000
 #defineS3C2410_SDI_BASE  0x5A000000
 
+#defineoNFCONF   0x00
+#defineoNFCMD   0x04
+#defineoNFADDR   0x08
+#defineoNFDATA   0x0C
+#defineoNFSTAT   0x10
+#defineoNFECC   0x14
+
+#ifndef __ASSEMBLER__
 
 
 #include<s3c24x0.h>
 
+typedef enum {
+ S3C24X0_UART0,
+ S3C24X0_UART1,
+ S3C24X0_UART2
+} S3C24X0_UARTS_NR;
 
 static inline S3C24X0_MEMCTL * constS3C24X0_GetBase_MEMCTL(void)
 {
@@ -224,4 +231,7 @@
   rINTPND;/
    }
 
+
+#endif
+
 #endif

二、再实现支持nand flash 读写的部分(可以去掉2440的部分):
U-Boot 1.1.6中对NANDFlash的支持有新旧两套代码,新代码在drivers/nand目录下,旧代码在drivers/nand_legacy目录下。文档doc/README.nand对这两套代码有所说明:使用旧代码需要定义更多的宏,而新代码移植自Linux内核2.6.12,它更加智能,可以自动识别更多型号的NANDFlash。目前之所以还保留旧的代码,是因为两个目标板NETTA、NETTA_ISDN使用JFFS文件系统,它们还依赖于旧代码。当相关功能移植到新代码之后,旧的代码将从U-Boot中去除。

要让U-Boot支持NAND Flash,首先在配置文件include/configs/100ask24x0.h的宏CONFIG_COMMANDS中增加CFG_CMD_NAND,如下:

#define CONFIG_COMMANDS /

(CONFIG_CMD_DFL | /

CFG_CMD_CACHE | /

CFG_CMD_PING | /

CFG_CMD_NAND| /

……

然后选择使用哪套代码:在配置文件中定义宏CFG_NAND_LEGACY则使用旧代码,否则使用新代码。

使用旧代码时,需要实现drivers/nand_legacy/nand_legacy.c中使用到的各种宏,比如:

#define NAND_WAIT_READY(nand)/* 等待Nand Flash的状态为“就绪”,代码依赖于具体的开发板 */

#define WRITE_NAND_COMMAND(d, adr)/* 写NAND Flash命令,代码依赖于具体的开发板 */


本书使用新代码,下面讲述移植过程。

代码的移植没有现成的文档,可以在配置文件include/configs/100ask24x0.h的宏CONFIG_COMMANDS中增加CFG_CMD_NAND后,就编译代码,然后一个一个地解决出现的错误。编译结果中出现的错误和警告如下:

nand.h:412: error: `NAND_MAX_CHIPS' undeclared here (not in a function)

nand.c:35: error: `CFG_MAX_NAND_DEVICE' undeclared here (not in a function)

nand.c:38: error: `CFG_NAND_BASE' undeclared here (not in a function)

nand.c:35: error: storage size of `nand_info' isn't known

nand.c:37: error: storage size of `nand_chip' isn't known

nand.c:38: error: storage size of `base_address' isn't known

nand.c:37: warning: 'nand_chip' defined but not used

nand.c:38: warning: 'base_address' defined but not used

在配置文件include/configs/100ask24x0.h中增加如下3个宏就可以解决上述错误。在Flash的驱动程序中,设备是逻辑上的概念,表示一组相同结构、访问函数相同的Flash芯片。在本书所用开发板中,只有一个NAND Flash芯片,所以设备数为1,芯片数也为1。

#define CFG_NAND_BASE 0/* 无实际意义:基地址,这在board_nand_init中重新指定 */

#define CFG_MAX_NAND_DEVICE 1/* NAND Flash“设备”的数目为1 */

#define NAND_MAX_CHIPS 1/* 每个NAND Flash“设备”由1个NAND Flash“芯片”组成 */


修改配置文件后再次编译,现在只有一个错误了,“board_nand_init函数未定义”:

nand.c:50: undefined reference to `board_nand_init'


调用board_nand_init函数的过程为:NANDFlash的初始化入口函数是nand_init,它在lib_arm/board.c的start_armboot函数中被调用;nand_init函数在drivers/nand/nand.c中实现,它调用相同文件中的nand_init_chip函数;nand_init_chip函数首先调用board_nand_init函数来初始化NAND Flash设备,最后才是统一的识别过程。

从board_nand_init函数的名称就可以知道它是平台/开发板相关的函数,需要自己编写。本书在cpu/arm920t/s3c24x0目录下新建一个文件nand_flash.c,在里面针对S3C2410、S3C2440实现了统一的board_nand_init函数。

在编写board_nand_init函数的之前,需要针对S3C2410、S3C2440 NAND Flash控制器的不同定义一些数据结构和函数:

(1)在include/s3c24x0.h文件中增加S3C2440_NAND数据结构。

/* NAND FLASH (see S3C2440 manual chapter 6, www.100ask.net) */

typedef struct {

S3C24X0_REG32 NFCONF;

S3C24X0_REG32 NFCONT;

S3C24X0_REG32 NFCMD;

S3C24X0_REG32 NFADDR;

S3C24X0_REG32 NFDATA;

S3C24X0_REG32 NFMECCD0;

S3C24X0_REG32 NFMECCD1;

S3C24X0_REG32 NFSECCD;

S3C24X0_REG32 NFSTAT;

S3C24X0_REG32 NFESTAT0;

S3C24X0_REG32 NFESTAT1;

S3C24X0_REG32 NFMECC0;

S3C24X0_REG32 NFMECC1;

S3C24X0_REG32 NFSECC;

S3C24X0_REG32 NFSBLK;

S3C24X0_REG32 NFEBLK;

} /*__attribute__((__packed__))*/ S3C2440_NAND;

(2)在include/s3c2410.h文件中仿照S3C2410_GetBase_NAND函数定义S3C2440_GetBase_NAND函数。

/* for s3c2440, www.100ask.net */

static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)

{

return (S3C2440_NAND * const)S3C2410_NAND_BASE;

}


既然新的NANDFlash代码是从Linux内核2.6.12中移植来的,那么cpu/arm920t/s3c24x0/nand_flash.c文件也可以仿照内核中,对S3C2410、S3C2440的NANDFlash进行初始化的drivers/mtd/nand/s3c2410.c文件来编写。为了方便阅读,先把cpu/arm920t/s3c24x0/nand_flash.c文件的代码全部列出来,再讲解:

01 /*

02 * s3c2410/s3c2440的NAND Flash控制器接口, www.100ask.net

03 * 修改自Linux内核2.6.13文件drivers/mtd/nand/s3c2410.c

04 */

05

06 #include <common.h>

07

08 #if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)

09 #include <s3c2410.h>

10 #include <nand.h>

11

12 DECLARE_GLOBAL_DATA_PTR;

13

14 #define S3C2410_NFSTAT_READY (1<<0)

15 #define S3C2410_NFCONF_nFCE (1<<11)

16

17 #define S3C2440_NFSTAT_READY (1<<0)

18 #define S3C2440_NFCONT_nFCE (1<<1)

19

20

21 /* S3C2410:NAND Flash的片选函数 */

22 static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)

23 {

24 S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

25

26 if (chip == -1) {

27 s3c2410nand->NFCONF |= S3C2410_NFCONF_nFCE;/* 禁止片选信号 */

28 } else {

29 s3c2410nand->NFCONF &= ~S3C2410_NFCONF_nFCE;/* 使能片选信号 */

30 }

31 }

32

33 /* S3C2410:命令和控制函数

34 *

35 * 注意,这个函数仅仅根据各种命令来修改“写地址”IO_ADDR_W 的值(这称为tglx方法),

36 * 这种方法使得平台/开发板相关的代码很简单。

37 * 真正发出命令是在上一层NAND Flash的统一的驱动中实现,

38 * 它首先调用这个函数修改“写地址”,然后才分别发出控制、地址、数据序列。

39 */

40 static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)

41 {

42 S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

43 struct nand_chip *chip = mtd->priv;

44

45 switch (cmd) {

46 case NAND_CTL_SETNCE:

47 case NAND_CTL_CLRNCE:

48 printf("%s: called for NCE/n", __FUNCTION__);

49 break;

50

51 case NAND_CTL_SETCLE:

52 chip->IO_ADDR_W = (void *)&s3c2410nand->NFCMD;

53 break;

54

55 case NAND_CTL_SETALE:

56 chip->IO_ADDR_W = (void *)&s3c2410nand->NFADDR;

57 break;

58

59 /* NAND_CTL_CLRCLE: */

60 /* NAND_CTL_CLRALE: */

61 default:

62 chip->IO_ADDR_W = (void *)&s3c2410nand->NFDATA;

63 break;

64 }

65 }

66

67 /* S3C2410:查询NAND Flash状态

68 *

69 * 返回值:0 – 忙, 1 – 就绪

70 */

71 static int s3c2410_nand_devready(struct mtd_info *mtd)

72 {

73 S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

74

75 return (s3c2410nand->NFSTAT & S3C2410_NFSTAT_READY);

76 }

77

78

79 /* S3C2440:NAND Flash的片选函数 */

80 static void s3c2440_nand_select_chip(struct mtd_info *mtd, int chip)

81 {

82 S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

83

84 if (chip == -1) {

85 s3c2440nand->NFCONT |= S3C2440_NFCONT_nFCE;/* 禁止片选信号 */

86 } else {

87 s3c2440nand->NFCONT &= ~S3C2440_NFCONT_nFCE;/* 使能片选信号 */

88 }

89 }

90

91 /* S3C2440:命令和控制函数,与s3c2410_nand_hwcontrol函数类似 */

92 static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)

93 {

94 S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

95 struct nand_chip *chip = mtd->priv;

96

97 switch (cmd) {

98 case NAND_CTL_SETNCE:

99 case NAND_CTL_CLRNCE:

100 printf("%s: called for NCE/n", __FUNCTION__);

101 break;

102

103 case NAND_CTL_SETCLE:

104 chip->IO_ADDR_W = (void *)&s3c2440nand->NFCMD;

105 break;

106

107 case NAND_CTL_SETALE:

108 chip->IO_ADDR_W = (void *)&s3c2440nand->NFADDR;

109 break;

110

111 /* NAND_CTL_CLRCLE: */

112 /* NAND_CTL_CLRALE: */

113 default:

114 chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;

115 break;

116 }

117 }

118

119 /* S3C2440:查询NAND Flash状态

120 *

121 * 返回值:0 – 忙, 1 – 就绪

122 */

123 static int s3c2440_nand_devready(struct mtd_info *mtd)

124 {

125 S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

126

127 return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY);

128 }

129

130 /*

131 * Nand flash硬件初始化:

132 * 设置NAND Flash的时序, 使能NAND Flash控制器

133 */

134 static void s3c24x0_nand_inithw(void)

135 {

136 S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

137 S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

138

139 #define TACLS 0

140 #define TWRPH0 4

141 #define TWRPH1 2

142

143 if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)

144 {

145 /* 使能NAND Flash控制器,初始化ECC,使能片选信号,设置时序 */

146 s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);

147 }

148 else

149 {

150 /* 设置时序 */

151 s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);

152 /* 初始化ECC,使能NAND Flash控制器,使能片选信号 */

153 s3c2440nand->NFCONT = (1<<4)|(0<<1)|(1<<0);

154 }

155 }

156

157 /*

158 * 被drivers/nand/nand.c调用, 初始化NAND Flash硬件,初始化访问接口函数

159 */

160 void board_nand_init(struct nand_chip *chip)

161 {

162 S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

163 S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

164

165 s3c24x0_nand_inithw();/* Nand flash硬件初始化 */

166

167 if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410) {

168 chip->IO_ADDR_R = (void *)&s3c2410nand->NFDATA;

169 chip->IO_ADDR_W = (void *)&s3c2410nand->NFDATA;

170 chip->hwcontrol = s3c2410_nand_hwcontrol;

171 chip->dev_ready = s3c2410_nand_devready;

172 chip->select_chip = s3c2410_nand_select_chip;

173 chip->options = 0;/* 设置位宽等,位宽为8 */

174 } else {

175 chip->IO_ADDR_R = (void *)&s3c2440nand->NFDATA;

176 chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;

177 chip->hwcontrol = s3c2440_nand_hwcontrol;

178 chip->dev_ready = s3c2440_nand_devready;

179 chip->select_chip = s3c2440_nand_select_chip;

180 chip->options = 0;/* 设置位宽等,位宽为8 */

181 }

182

183 chip->eccmode = NAND_ECC_SOFT;/* ECC较验方式:软件ECC */

184 }

185

186 #endif

文件中分别针对S3C2410、S3C2440实现了NAND Flash最底层访问函数,并进行了一些硬件的设置(比如时序、使能NANDFlash控制器等)。新的代码对NANDFlash的封装做得很好,只要向上提供底层初始化函数board_nand_init来设置好平台/开发板相关的初始化、提供底层接口即可。

最后,只要将新建的nand_flash.c文件编入U-Boot中就可以擦除、读写NAND Flash了。如下修改cpu/arm920t/s3c24x0/Makefile文件即可:

COBJS = i2c.o interrupts.o serial.o speed.o /

usb_ohci.o

改为:

COBJS = i2c.o interrupts.o serial.o speed.o /

usb_ohci.o nand_flash.o

现在,可以使用新编译的u-boot.bin烧写内核映像到NAND Flash去了,请参考15.2.6。

原创粉丝点击