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: /*********************************************************** #define CONFIG_COMMANDS CFG_CMD_NAND| CFG_CMD_DATE| ????然后,增加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驱动分析?(CSDN)或者?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 红色为新增。 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) {
} ????然后增加S3C2440_NAND_BASE的基址 #define S3C2410_NAND_BASE #define S3C2440_NAND_BASE ????红色为新增芯片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 ????命令解释:读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 ????重启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)转载请指明出处。 原文地址:http://www.100ask.net/forum/showtopic-3697.aspx ? 免费视频下载地址: 第1期共33个视频,免费,下载后可以直接观看,下载地址: 第二期视频主要是驱动深入讲解,精华啊! 第二期视频需要收费的哦,具体见韦东山老师淘宝店铺: http://100ask.taobao.com/ ? 书籍资料下载: 《嵌入式Linux应用开发完全手册》及相关资源电炉可以下载: http://www.verycd.com/topics/2828590/ ??????嵌入式linux应用开发完全手册光盘里的驱动和例子源代码.rar详情 嵌入式linux应用开发完全手册.pdf详情 ? 如果能买一块韦东山老师的开发板,加上视频讲解,加上书,那学起来就太Easy了! 淘宝店铺上http://100ask.taobao.com/全套都有了!!! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |