支持了nand flash启动并不是说支持了以后对nand flash的读写操作,支持nand flash启动只需要在重定位时(把代码从nand flash拷贝到SDRAM的函数copy_code_to_sdram)x写出一个nand flash的读函数nand_read_ll(),吧代码从nand flash复制到sdram里面去就可以了,
1、修改UBOOT支持NAND FLASH
(1)初始修改
修改:include/configs/smdk2440.h: #define CONFIG_CMD_NAND(2)make编译出错
出现不完整的类型
72行用到结构体nand的成员nfconf
由于CONFIG_S3C2410这个没定义,因而相应的结构体也不会存在
但是CONFIG_S3C2440有定义,因而相应的结构体存在
(3)s3c2440_nand.c
把drivers\mtd\nand\s3c2410_nand.c复制为s3c2440_nand.c
选择编译s3c2440_nand.c而不编译s3c2410_nand.c
修改Makefile
把
修改为
里面用到宏CONFIG_NAND_S3C2410
看配置文件inclde\configs\smdk2440.h里面有定义CONFIG_NAND_S3C2410
用宏开关决定2440还是2410
(4)board.c中对nand flash的操作
里面有nand_init函数
里面有nand_init_chip函数
这里IO_ADDR_R和IO_ADDR_W是nfconf寄存器的地址,而board_nand_init是单板相关的nand_init函数。
(5)s3c2440_nand.c
board_nand_init在s3c2440_nand.c里面,设置clkcon寄存器中的nand flash位并使能它。
下面是时间参数的设置,根据nand flash手册确定时序值,要把cfg的参数从适应2410改为适应2440,然后再把参数设置的值写到寄存器里面去。下面减1的原因是如twrph0想保持4个时钟,根据 可知twrph0设为3的话,就保持3+1个时钟。
IO_ADDR_R和IO_ADDR_W是nfconf寄存器的地址
select_chip函数设置为NULL ,这select_chip函数应该会在其他函数中设置,猜想在s3c2410_hwcontrol函数中设置,
下面的s3c2440_nand结构体指针nand 指向0x4E000000,是nand flash控制器的基地址。看2410芯片手册的的nand flash控制器的nfconf寄存器,下面中的程序是读出寄存器nfconf的值,然后把第11位清为0,也就是选中了nand flash。
对于2410来说
对于2440的选中是nfcont寄存器bit1选中
(6)对nand flash的操作
u-boot的大部分代码是移至内核的
(7)取消选中上面已经提及,但是发命令,发地址没有看到
在board.c里面(分析过程)
nand_initnand_init_chip
单板相关的初始化
board_nand_init //设置nand_chip结构体, 提供底层的操作函数(片选函数,发地址、发命令函数、读写数据和判断状态)
识别nand flash
nand_scan//扫描后肯定会用到前面的操作函数,根据扫描过程来确认一下提供的函数是否完整nand_scan_ident
nand_set_defaults 设置默认函数,select_chip函数之前设置为NULL,现在使用默认函数,但由于默认的片选函数存在问题,所以需要自己写这个函数。
chip->select_chip = nand_select_chip;
chip->cmdfunc = nand_command;
读字节函数的选择,我们的nand flash是8位的
chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
nand_get_flash_type 获得flash的类型
chip->select_chip 选中芯片
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);发出复位命令
cmdfuncs就是函数3c2440_hwcontrol,NAND_CMD_RESET是命令,左边的-1是页内的地址,右边的-1是指那一页。其实-1是表示不发。
nand_command() 函数调用 chip->cmd_ctrl
chip->cmd_ctrl 函数调用s3c2440_hwcontrol
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); 发出读ID的命令0x90,地址是0x00
*maf_id = chip->read_byte(mtd);读厂家ID
*dev_id = chip->read_byte(mtd);读设备ID
(8)s3c2440_hwcontrol函数分析
选中芯片函数单独写,这里面的内容改为下面的内容
如果是CLE的话就发命令,如果是ALE就发地址。把dat写到nfcmd寄存器或nfaddr寄存器。这些寄存器只用到了8位,所以用writeb这个函数。
(9)片选函数
参考默认的片选函数
nfcont寄存器的bit1是片选选择位
2、修改的文件
s3c2440_nand.c
Makefile
include\configs\smdk2440.h
3、实验
烧写到nand flash里面去,设置为nand启动,在nor flash的0地址有u-boot.用nand erase命令擦除地址0开始的80000字节数据。然后用nand write命令把nor flash的0地址上的程序烧写到nand flash的0地址上面去,烧写80000.用nand read命令查看烧写是否成功,nand read 30000000 0 80000是从nand flash 的0地址读取80000数据到地址为0x30000000的地方.读出来后用cmp命令比较一下cmp.b 0 30000000 80000,这里0地址是nor flash,0x3000000是从nand flash读出来的地方。比较80000
nor flash启动的时候,可以操作nor flash,也可以操作nand flash。但是设置为nand flash启动的话,nor flash无法访问,因为nand flash启动后,0地址对应的是片内内存,无法访问nor flash.