uboot移植(十)移植 NAND FLASH

通过查看帮助文档 doc/README.nand,要支持 NAND,需要配置 CONFIG_CMD_NAND

我们修改 smdkv210.h,把 CONFIG_CMD_ONENAND 屏蔽掉,同时加上 CONFIG_CMD_NAND

uboot移植(十)移植 NAND FLASH

编译出错
uboot移植(十)移植 NAND FLASH

没有定义 CONFIG_SYS_MAX_NAND_DEVICE,最大 NAND 设备数,我们的板子只有 1 NAND,将其
定义为
1
uboot移植(十)移植 NAND FLASH

再次编译,出错
uboot移植(十)移植 NAND FLASH

未定义 NAND 的基地址,查看 S5PV210 手册, NAND 的基地址为 0xB0E00000,在 smdkv210.h 中定义
uboot移植(十)移植 NAND FLASH

再次编译,还是出错
uboot移植(十)移植 NAND FLASH

env_onenand.c onenand 相关的,我们不需要编译,查看 u-boot-2014.04/common/Makefile
uboot移植(十)移植 NAND FLASH

env_nand.o env_onenand.o,我们需要把环境变量保存到 NAND,因此我们需要定义
CONFIG_ENV_IS_IN_NAND,同时屏蔽掉 CONFIG_ENV_IS_IN_ONENAND
uboot移植(十)移植 NAND FLASH

再次编译
uboot移植(十)移植 NAND FLASH

没有定义 board_nand_init, 看名字就知道这是单板相关的 NAND 初始化函数。 通过搜索 u-boot 源码
发现在
u-boot-2014.04/drivers/mtd/nand/s3c2410_nand.c 中定义了这个函数,我们仿照
s3c2410_nand.c 编写 s5pv210_nand.c,拷贝 s3c2410_nand.c s5pv210_nand.c

uboot移植(十)移植 NAND FLASH

同时查看 u-boot-2014.04drivers/mtd/nand/Makefile,看下怎么将 s5pv210_nand.c 编译进 u-boot
uboot移植(十)移植 NAND FLASH

只有定义了 CONFIG_NAND_S3C2410 就会编译 s3c2410_nand.c,我们仿照添加一行
uboot移植(十)移植 NAND FLASH

并且在 smdkv210.h 中定义 CONFIG_NAND_S5PV210
uboot移植(十)移植 NAND FLASH

s5pv210_nand.c 中的 s3c2410 全部替换为 s5pv210,然后我们参考裸机编程中的 NAND 一节来修改S5pv210_nand.c
首先我们需要用到nand相关的寄存器操作,在arch/arm/include/asm/arch-s5pc1xx/cpu.h中添加NAND的基地址
uboot移植(十)移植 NAND FLASH

紧接着在下面添加宏
uboot移植(十)移植 NAND FLASH

然后在 arch/arm/include/asm/arch-s5pc1xx/下创建文件 nand_reg.h,定义 NAND 的寄存器结构体
uboot移植(十)移植 NAND FLASH

然后在 s5pv210_nand.c 中添加头文件  #include <asm/arch/nand_reg.h>

参考前面裸机编程中 NAND 操作,在 board_nand_init 进行相关的初始化, 增加函数
s5pv210_nand_select_chip,这个片选函数最终将调用 s5pv210_hwcontrol, 修改 s5pv210_hwcontrol
函数,这个函数主要做一些硬件相关的操作,比如发命令、发地址、片选。 具体请看代码。
编译成功, 由于增加了
NAND 驱动, u-boot.bin 的大小已经变为 215KB
uboot移植(十)移植 NAND FLASH

我们需要修改 u-boot-spl.bin 中的 copy_bl2_to_ram 中的拷贝大小
215K / 512 = 215 x 1024 / 512 = 430
我们之间将拷贝大小修改为 500 ,拷贝 250KB
uboot移植(十)移植 NAND FLASH
再次编译, 将 smdkv210-spl.bin u-boot.bin 烧写的 SD 卡,从 SD 卡启动开发板
uboot移植(十)移植 NAND FLASH

打印警告: Warning - bad CRC, using default environment
这是由于我们在 smdkv210.h 中指定了将环境变量保存到 NANDu-boot 启动的时候会从指定的地址
读取环境变量

uboot移植(十)移植 NAND FLASH

如果读取失败,则使用默认的环境变量,默认的环境变量就是我们通过 CONFIG_这样的宏在单板配
置文件中的定义的。 比如之前定义的
CONFIG_IPADDR
我们执行
saveenv 将环境变量保存到 NAND 中,下次启动就不会有那样的警告了
uboot移植(十)移植 NAND FLASH

执行 reset 复位
uboot移植(十)移植 NAND FLASH

现在来测试一下 NAND 读写是否正确无误,我们先通过 tftp 下载一个文件到内存
uboot移植(十)移植 NAND FLASH

然后擦除 NAND 0x80000 地址开始的一块
uboot移植(十)移植 NAND FLASH

然后将内存 0x20000000 开始的 0x800 字节的数据写入 NAND 0x80000 地址
uboot移植(十)移植 NAND FLASH

然后从 NAND 0x80000 地址读取 0x800 字节数据到内存的 0x20002000 地址
uboot移植(十)移植 NAND FLASH

然后使用 cmp 命令,比较 0x20000000 0x20002000 开始的 0x800 字节数据是否相同
uboot移植(十)移植 NAND FLASH

Total of 2048 byte(s) were the same
我们读写了 0x800 个字节,即 2048 个字节,全部正确无误。