韦东山Linux嵌入式课程社区
直播中

董方帅

7年用户 192经验值
擅长:816319
私信 关注

U-Boot NAND FLASH移植

U-Boot NAND FLASH移植

——西伯利亚的风

       为了使u-boot支持NAND FLASH,实现u-boot读写NAND FLASH,我们需要根据开发板的具体情况修改u-boot,增加NAND FLASH驱动。

一、移植环境

1.u-boot版本1.1.6

2.开发板Jz2440(ARM9 S3C2440

                          NAND K9F2G08

                       SDRAM K4S561632 * 2)

3.Linux: ubuntu 9.10



二、移植思想

根据u-boot的框架,大致可以确定移植需要做的工作:

1.修改配置文件smdk2410.h,启用NAND FLASH设备

2.如有需要,根据实际情况增加开发板相关的NAND FLASH设备的底层驱动

3.根据出现的问题、错误进行细微调整



三、移植步骤

1.修改配置文件

    参考韦老师的书《嵌入式Linux应用开发完全手册》,开始我们的移植工作。首先在配置文件smdk2410.h(路径:include/configs/smdk2410.h)的宏CONFIG_COMMANDS中增加CFG_CMD_NAND:

/***********************************************************
* Command definition
***********************************************************/

#define CONFIG_COMMANDS
(CONFIG_CMD_DFL|
CFG_CMD_CACHE|

CFG_CMD_NAND|
/*CFG_CMD_EEPROM |*/
/*CFG_CMD_I2C|*/
/*CFG_CMD_USB|*/
CFG_CMD_REGINFO|
CFG_CMD_PING|

CFG_CMD_DATE|
CFG_CMD_ELF)



    然后,增加NAND FLASH的一些宏,启用NAND FLASH设备。在配置文件smdk2410.h(路径:include/configs/smdk2410.h)中增加以下有关NAND FLASH的宏定义:

/*NAND FLASH config*/

#define CFG_NAND_BASE                         0

#define CFG_MAX_NAND_DEVICE           1

#define NAND_MAX_CHIPS                      1




    至此,第一阶段“修改配置文件smdk2410.h,启用NAND FLASH设备”工作已经完成,我们编译看看会出现什么问题。在u-boot根目录make,结果如下:

In function `nand_init':

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

make: *** [u-boot] Error 1


    看来board_nand_init未定义。根据分析可知,board_nand_init在函数nand_init()中被调用。查看nand_init()发现,缺少函数board_nand_init()的定义。根据函数名,可以推断出主要是完成开发板上的NAND FLASH的初始化。

    关于board_nand_init()函数以及u-boot中NAND FLASH的数据结构,函数调用关系,后续会有详细的分析文章,这里先实现移植。(分析请看U-Boot NAND FLASH驱动分析 http://www.100ask.net/forum/showtopic-3698.aspx



2.增加NAND FLASH底层驱动

    board_nand_init()主要实现开发板上NAND FLASH芯片K9F2G08的底层驱动。包括芯片时序设置,底层函数的实现。

附件中Jz2440_nand.c就是已经移植好的NAND FLASH底层驱动,我们将它加入到u-boot中与CPU相关的文件夹cpu/arm920t/s3c24x0/,并修改当前文件夹下的Makefile(路径:cpu/arm920t/s3c24x0/Makefile):

COBJS = i2c.o interrupts.o serial.o speed.o
              u***_ohci.o Jz2440_nand.o

红色为新增。



3.解决其他错误

    增加驱动后,再次编译,出现错误:

In function `s3c2440_nand_select_chip':

undefined reference to `S3C2440_GetBase_NAND'


    提示函数S3C2440_GetBase_NAND()未定义,参考S3C2410_GetBase_NAND(),在s3c2410.h(路径:include/s3c2410.h)中增加函数

static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)

{


return (S3C2440_NAND * const)S3C2440_NAND_BASE;

}


    然后增加S3C2440_NAND_BASE的基址

#define S3C2410_NAND_BASE
0x4E000000

#define S3C2440_NAND_BASE
0x4E000000

    红色为新增芯片s3c2440中nand 控制器的寄存器基址,查看s3c2440的芯片手册可以知道。

    再次编译,通过!



四、NAND FLASH移植测试


    将编译好的u-boot.bin通过OpenJtag烧入Jz2440开发板,重启开发板可以看到:

U-Boot 1.1.6 (Mar 28 2012 - 21:26:29)

DRAM:    64 MB

Flash:      512 kB

NAND:    256 MiB


    显示NAND FLASH大小为256MB。

    在u-boot界面,输入“?nand”命令, 查看nand相关的用法:

Jz2440 # ? nand

nand info              - show available NAND devices

nand device [dev]  - show or set current device

nand read[.jffs2]   - addr off|partition size

nand write[.jffs2]……


    可以看到一系列nand read、nand write命令,以及命令的使用方法。



1.擦除NAND FLASH测试

    在u-boot界面输入nand erase 0 1000:

Jz2440 # nand erase 0 1000

NAND erase: device 0 offset 0x0, size 0x1000

Erasing at 0x0 -- 3200% complete.

OK

    命令解释:擦除NAND FLASH偏移0个地址后的4K内容(0x1000)



2.读NAND FLASH测试

    在u-boot界面输入nand read 30000000 0 1000:

Jz2440 # nand read 30000000 0 1000

NAND read: device 0 offset 0x0, size 0x1000
4096 bytes read: OK


    命令解释:读NAND FLASH偏移0个地址 大小为4K的内容(0x1000),放到内存的0x30000000处

    在u-boot界面使用md命令查看内存内容:

Jz2440 # md 30000000

30000000: ffffffff ffffffff ffffffff ffffffff    ................

30000010: ffffffff ffffffff ffffffff ffffffff    ................

30000020: ffffffff ffffffff ffffffff ffffffff    ................

30000030: ffffffff ffffffff ffffffff ffffffff    ................

30000040: ffffffff ffffffff ffffffff ffffffff    ……


    可以看到,内存0x30000000处全是f,说明nand read读到的是上一步擦除后NAND FLASH上的内容,说明上一步擦除NAND FLASH成功,本次读操作也OK。



3.写NAND FLASH测试

    我们通过nand write写一个小程序leds(运行地址加载地址都是0)到NAND FLASH的0地址,开发板复位后,如果开机启动运行leds,说明写成功,否则写失败。

使用串口loadb命令将编译好的leds.bin下载到内存0x30000000中去。(具体下载教程请看本论坛另一篇文章:U-Boot使用loadb下载程序——基于Linux下kermit(附测试代码)http://www.100ask.net/forum/showtopic-3627.aspx


    然后使用nand write,将程序从内存写到NAND FLASH的0地址。

    注意:在写NAND FLASH之前先要擦除相应区域,否则会写失败。


    擦除4K空间:

Jz2440 # nand erase 0 1000

NAND erase: device 0 offset 0x0, size 0x1000

Erasing at 0x0 -- 3200% complete.

OK


    写NAND FLASH

Jz2440 # nand write 30000000 0 1000

NAND write: device 0 offset 0x0, size 0x1000
4096 bytes written: OK


    重启Jz2440开发板,可以看到LED在缓慢闪烁了,说明写NAND FLASH 成功!


    命令解释:将内存030000000地址处的内容写4K(0x1000)到NAND FLASH 偏移0地址处,前提条件是已经通过loadb命令将leds程序下载到了内存的0x30000000地址处。

由于将leds程序写在了NAND FLASH的0地址,而0地址又是u-boot的存放地址。写完之后,leds将u-boot程序破坏了,所以一上电就执行leds的闪灯程序,不再启动u-boot。如果想使用u-boot,请重新使用OpenJtag烧写u-boot到开发板。



五、移植yaffs注意问题


        NAND支持yaffs读写,《嵌入式Linux应用开发完全手册》书上讲的很清楚了,有具体的移植步骤,原理讲解,非常详细,具体参看书《嵌入式Linux应用开发完全手册》P283页。这里有两点问题,需要特别注意:



1.页对齐问题

    使用“nand write”命令写NAND FLASH时,每页大小是2K,但是如果使用“nand write.yaffs” 命令写 NAND FLASH,每页大小是2K+64字节。(Jz2440开发板上的NAND FLASH是2K(页) + 64字节(OOB)),也就是说,写文件时,写NAND FLASH空间的大小是2K+64字节的整数倍,否则会报错。



2.文件格式问题

    本来想用“nand write.yaffs”将leds.bin烧写进NAND FLASH,看是否写成功,但是发现写完重启开发板,led总是没有反应,试过几次后,恍然大悟:“nand write.yaffs”命令写的是yaffs文件系统格式的文件,而leds.bin不符合yaffs格式,故数据写进NAND FLASH后,数据被打乱,运行不了。所以使用leds.bin测试时,只能验证yaffs写功能,无法看到写的结果。看来自己想错了,呵呵~



六、总结

    至此,对NAND FLASH的移植、测试结束。

    移植是一项非常耗时间的工作,移植NAND FLASH差不多花了一整天的时间,详细研读了《嵌入式Linux应用开发完全手册》中NAND FLASH的移植说明,翻遍了u-boot中关于NAND FLASH的源码,查阅了大量网上NAND FLASH移植的文章。终于移植成功,同时也明白了u-boot中NAND FLASH 的数据结构,函数调用关系,苦心没有白费。

    留一个问题给初学者:u-boot中是如何知道NAND FLASH的容量大小的?要知道配置文件smdk2410.h(路径:include/configs/smdk2410.h)中根本就没有提及NAND FLASH的大小。正在学习NAND FLASH有兴趣的同学请回答。



七、参考文献

    《嵌入式Linux应用开发完全手册》第15.2.5节 (P276)


八、附件

1.移植好NAND FLASH的U-Boot烧写文件u-boot.bin


2.u-boot中NAND FLASH驱动Jz2440_nand.c


3.测试代码leds




                                              声明:本文为个人原创,边移植边写,完全来自实践。本文首先发表在百问网(www.100ask.net)转载请指明出处。

回帖(13)

王媛媛

2019-7-3 07:04:57
回复 2楼thisway.diy的帖子

开始排版不是很好,今天又重新调整了下格式,这样大家看起来比较顺眼,呵呵~
举报

庞哲

2019-7-3 07:10:43
回复 2楼thisway.diy的帖子

有了老大的鼓励,我会再接再厉的!希望老大多多指导!:Z
举报

韦明

2019-7-3 07:23:02
移植时不用考虑大小页和nand flash具体命令的修改吗?
举报

李子蕙

2019-7-3 07:29:14
回复 5楼Assassin的帖子

这里的移植不用考虑,因为U-boot已经起来,它很智能,能够自动识别你的NAND FLASH的大小页,还能知道你NAND FLASH的容量,所以就不用考虑 大小页和nand flash具体命令的修改了。
http://www.100ask.net/forum/showtopic-3698.aspx
这里是分析,你看看,希望能帮到你。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分