U-boot用tftp命令直接烧写到NandFlash
这个是在《U-boot中用tftp命令直接烧写到flash中》的基础上来做了,NorFlash烧写ok了,就进一步试试NandFlash,但是是NandFlash并没有NorFlash那么简单。不是想写多少就写多少,这正与NorFlash相反。tftp一个包的大小不会是正好是NorFlash一个页的大小。所以这里就会很麻烦。对于这种情况Linux中好像要专门的日志文件系统如yaffs,ubifs来对付这种情况。但是如果不考虑整体效果的话,目前可以让它写进去一个led.bin(164byte)的,就可以一次完整的写进去,指定大小也可以大大地超过这个值。这个思路有了,就简单的将原来的flash_write改为了nand_write_skip_bad。这样就可以测试能否正常了,如果led通过正常运行,就说明这样烧写是可行的。所有改动都是net/tftp.c中,改动内容如下:
--- ../6Ubootnand/net/tftp.c 2013-03-10 20:45:12.448500276 +0800+++ net/tftp.c 2013-03-11 18:12:06.554298534 +0800@@ -9,6 +9,7 @@#include <net.h>#include "tftp.h"#include "bootp.h"+#include <nand.h>#if defined(CONFIG_CMD_NET)@@ -130,8 +131,33 @@ulong offset = block * TftpBlkSize + TftpBlockWrapOffset;ulong newsize = offset + len;#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP- int i, rc = 0;+// int i, rc = 0;+//+// for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; i++) {+// /* start address in flash? */+// if (flash_info[i].flash_id == FLASH_UNKNOWN)+// continue;+// if (load_addr + offset >= flash_info[i].start[0]) {+// rc = 1;+// break;+// }+// }+//+// if (rc) { /* Flash is destination for this packet */+// rc = flash_write ((char *)src, (ulong)(load_addr+offset), len);+// if (rc) {+// flash_perror (rc);+// NetState = NETLOOP_FAIL;+// return;+// }+// }+// else+ int i, rc = 0;+ nand_info_t *nand;+ loff_t off = 0;+ size_t length;+ u_char *buffer;for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; i++) {/* start address in flash? */if (flash_info[i].flash_id == FLASH_UNKNOWN)@@ -141,9 +167,13 @@break;}}-+ nand = &nand_info[nand_curr_device];+ off = 0x0;+ length = 0x40000;+ buffer = (u_char *)src;if (rc) { /* Flash is destination for this packet */- rc = flash_write ((char *)src, (ulong)(load_addr+offset), len);+ //rc = flash_write ((char *)src, (ulong)(load_addr+offset), len);+ rc = nand_write_skip_bad(nand, off, &length, buffer);if (rc) {flash_perror (rc);NetState = NETLOOP_FAIL;
运行这个u-boot,使用tftp命令烧写过程:
U-Boot 2009.11 ( 3月 11 2013 - 18:12:18)DRAM: 128 MBFlash: 2 MBNAND: 256 MiB*** Warning - bad CRC, using default environmentIn: serialOut: serialErr: serialNet: dm9000Hit any key to stop autoboot: 0SMDK2440 # nand erase 0 40000NAND erase: device 0 offset 0x0, size 0x40000Erasing at 0x2000000000004 -- 0% complete.OKSMDK2440 # tftp 0x0 led.bindm9000 i/o: 0x20000000, id: 0x90000a46DM9000: running in 16 bit modeMAC: 00:01:02:03:04:05operating at 100M full duplex modeUsing dm9000 deviceTFTP from server 192.168.1.229; our IP address is 192.168.1.230Filename 'led.bin'.Load address: 0x0Loading: T #doneT Bytes transferred = 164 (a4 hex)SMDK2440 #再往下,是加一个tftp缓存,接到的包都先存起来,到一定数量后(一个页,或者块),再一块写进去。把零的放到前边,再缓存。再写。。。这里边涉及到的算法多一些。要好好理清思绪才能移植好。