分类: LINUX
2013-09-12 15:53:40
U-Boot版本:U-boot 2008.10 目标板:Mini2440 Nandflash型号: K9F1G08U0B 256M
修改include/configs/mini2440.h。
1)添加命令支持:
#define CONFIG_CMD_ELF
#define CONFIG_CMD_NAND
2)添加nand flash 参数设置:
/*nand flashsettings******************************************************************************************/
#define CFG_NAND_BASE 0 /*Nand Flash控制器在SFR区起始寄存器地址*/
#define CFG_MAX_NAND_DEVICE 1 /*NAND Flash设备最大数*/
#define NAND_MAX_CHIPS 1 /*NAND Flash芯片数*/
#define SECTORSIZE 2048 /*扇区容量2K Bytes*/
#define ADDR_COLUMN 2/*2Byte Column address*/
#define ADDR_PAGE 3 //3字节的页块地址
#define ADDR_COLUMN_PAGE 4 //总共4字节的页块地址
#define NAND_ChipID_UNKNOWN 0x00 //未知芯片的ID号
#define NAND_MAX_FLOORS 4
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
说明:此版的u-boot已自带board_nand_init(),在cpu/arm920t/s3c24x0/nand.c中定义。
因为s3c2410和s3c2440在flash控制器上,有所差别,驱动代码需要改进,主要修改在cpu/arm920t/s3c24x0/nand.c中进行。
cpu/arm920t/s3c24x0/nand.c中修改过程:
先加入 S3C2440 NANDflash 控制器的地址定义,修改后如下:
``````
#if ndef(CONFIG_S3C2440) //针对S3C2410这款SOC
#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 NFECC0 __REGb(NF_BASE +0x14)
#define NFECC1 __REGb(NF_BASE + 0x15)
#define NFECC2 __REGb(NF_BASE +0x16)
#else //S3C2440与S3C2410不太一样
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x4)
#define NFCMD __REGb(NF_BASE +0x8)
#define NFADDR __REGb(NF_BASE + 0xc)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFMECCD0 __REGi(NF_BASE +0x14)
#define NFMECCD1 __REGi(NF_BASE +0x18)
#define NFSECCD __REGi(NF_BASE + 0x1C)
#define NFSTAT __REGb(NF_BASE +0x20)
#define NFSTAT0 __REGi(NF_BASE + 0x24)
#define NFSTAT1 __REGi(NF_BASE + 0x28)
#define NFMECC0 __REGi(NF_BASE + 0x2C)
#define NFMECC1 __REGi(NF_BASE + 0x30)
#define NFSECC __REGi(NF_BASE + 0x34)
#define NFSBLK __REGi(NF_BASE +0x38)
#define NFEBLK __REGi(NF_BASE + 0x3C)
#define S3C2440_NFCONT_nCE (1<<1)
#define S3C2440_ADDR_NALE 0x0c
#define S3C2440_ADDR_NCLE 0x08
#endif
``````
U-Boot.2008.10自带的s3c2410的s3c2410的s3c2410_hwcontrol函数有错。在此函数中,把chip->IO_ADDR_W的值改写了,导致在写数据时出现错误,解决办法是使用一全局变量代替chip->IO_ADDR_W。在s3c2410_hwcontrol函数的上一行定义这个全局变量,然后修改s3c2410_hwcontrol函数,让它支持S3C2440,修改该后如下:
````
ulong IO_ADDR_W =NF_BASE;
static void s3c2410_hwcontrol(structmtd_info *mtd, int cmd, unsigned int ctrl)
{
struct nand_chip *chip = mtd->priv;
DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
/*modified by xxx ,for 2440*********************************************************/
#if !defined(CONFIG_S3C2440)
if (ctrl & NAND_CTRL_CHANGE) {
/*modified by xxx ,for2440*********************************************************/
/*ulong IO_ADDR_W = NF_BASE;*/ /*delete ulong,by xxx ********/
IO_ADDR_W = NF_BASE;
if (!(ctrl & NAND_CLE))
IO_ADDR_W |= S3C2410_ADDR_NCLE;
if (!(ctrl & NAND_ALE))
IO_ADDR_W |= S3C2410_ADDR_NALE;
/*chip->IO_ADDR_W = (void *)IO_ADDR_W;*/ /*BUG,delete byxxx******/
if (ctrl & NAND_NCE)
NFCONF &= ~S3C2410_NFCONF_nFCE;
else
NFCONF |= S3C2410_NFCONF_nFCE;
}
if (cmd != NAND_CMD_NONE)
/*writeb(cmd, chip->IO_ADDR_W);*/ /*modified by xxx************/
writeb(cmd, (void *)chip->IO_ADDR_W);
#else
if (ctrl & NAND_CTRL_CHANGE) {
IO_ADDR_W = NF_BASE;
if (!(ctrl & NAND_CLE))
IO_ADDR_W |= S3C2440_ADDR_NALE;
if (!(ctrl & NAND_ALE))
IO_ADDR_W |= S3C2440_ADDR_NCLE;
/*chip->IO_ADDR_W = (void *)IO_ADDR_W;*/ /*BUG,delete by xxx******/
if (ctrl & NAND_NCE)
NFCONT &= ~S3C2440_NFCONT_nCE;/*Becareful there is NFCONT**********/
else
NFCONT |= S3C2440_NFCONT_nCE;
}
if (cmd != NAND_CMD_NONE)
/*writeb(cmd, chip->IO_ADDR_W);*/ /*modified by xxx************/
writeb(cmd, (void *)IO_ADDR_W);
#endif
}
board_nand_init修改后如下:
····
clk_power->CLKCON |= (1 << 4);
/*add by xxx ,for 2440******************************************************/
#if !defined(CONFIG_S3C2440)
DEBUGN("CONFIG_S3C2410\n");
/* initialize hardware */
twrph0 = 3; twrph1 = 0; tacls = 0;
cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls- 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0- 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1- 1);
NFCONF = cfg;
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e00000c;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
/* hwcontrol always must be implemented */
nand->cmd_ctrl = s3c2410_hwcontrol;
nand->dev_ready = s3c2410_dev_ready;
#else
DEBUGN("CONFIG_S3C2440\n");
/* initialize hardware */
twrph0 = 4; twrph1 = 2; tacls = 0; /*modified by dazhi ,for 2440*****/
/*modified by xxx ,for 2440*************************************************/
cfg =(tacls <<12)|(twrph0<<8)|(twrph1<<4);
NFCONF=cfg;
cfg =(1 <<6)|(1<<4)|(0<<1)|(1<<0);
NFCONT=cfg;
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
/* hwcontrol always must be implemented */
nand->cmd_ctrl = s3c2410_hwcontrol;
nand->dev_ready = s3c2410_dev_ready;
#endif
为了显示芯片型号,将 drivers/mtd/nand/nand_base.c中的nand_get_flash_type函数结尾,修改MTDDEBUG为printf。
在NAND FLASH中保存u-boot 参数,(saveenv功能)
/include/configs/mini2440.h添加:
`````
#define CONFIG_CMD_NAND
#define CONFIG_CMD_ENV
`````
/*#define CONFIG_ENV_IS_IN_FLASH 1 */
#define CONFIG_ENV_IS_IN_NAND 1
#define CONFIG_ENV_OFFSET 0x40000/*参数在nand flash中的起始位置位256K*/
#define CONFIG_ENV_SIZE 0x20000 /*环境变量总大小,128K*/
保存,在Uboot根目录下先清除make clean下,然后make,下载测试。
注:中间可能会出现宏未定义的错误,或者redifined 宏。对于这些错误,没办法,得挨个修改,这是调试技术。
出错的宏最好在 u-boot-2008-10/include/configs/mini2440.h里修改,针对本开发板的软硬件配置modify,避免修改参数范围太大,难于控制。比如CONFIG_NAND_BASE为CFG_NAND_BASE。
下载NAND FLASH移植测试:
将编译好的u-boot.bin通过JTAG烧入Mini2440开发板,重启开发板可以看到:
显示的信息中存在一个 bad CRC的警告信息,这是由于在启动时,uboot会从flash中读取环境变量的信息,通常执行save或saveenv后,下次启动就不会出现此警告了。
在u-boot界面,输入“?nand”命令,查看nand相关的用法:
Jz2440 # ? nand
可以看到一系列nand read、nand write命令,以及命令的使用方法。
1.擦除NAND FLASH测试
在u-boot界面输入nand erase 0 1000:
命令解释:擦除NAND FLASH偏移0个地址后的4K内容(0x1000)
2.读NAND FLASH测试
在u-boot界面输入nand read 30000000 0 1000:
命令解释:读NAND FLASH偏移0个地址大小为4K的内容(0x1000),放到内存的0x30000000处
在u-boot界面使用md命令查看内存内容:
可以看到,内存0x30000000处全是f,说明nand read读到的是上一步擦除后NAND FLASH上的内容,说明上一步擦除NAND FLASH成功,本次读操作也OK。
3.写NAND FLASH测试