U-boot用tftp命令直接烧写到NandFlash V3.0

U-boot用tftp命令直接烧写到NandFlash V3.0

/****************************************************
版本:v3.0
功能:给计数器做了清零,解决 Retry count exceeded; starting again 的问题。发现的新问题,并解决了。现在可以把一个200多k的直接烧写到Nand中了。
不足:可以进一步考虑 Yaffs2文件系统的直接烧写。不过只会分析一下。
*****************************************************/
1、定义一块tftp_nand_buffer[2048];
2、每次store_block调用的时候,首先从tftp_nand_buffer[(tftp_nand_counter & 1) << 10]开始拷贝数据;
3、nand_write_skip_bad(nand, off, &length, buffer);

nand_write_skip_bad:
nand :
off    :写入flash的位置(off + ((tftp_nand_counter-1)*1024))  //里边的off为0.
length:数据长度,为2048
buffer:   数据位置 tftp_nand_buffer

解决tftp_nand_counter清零的问题,改动如下:
diff -ru 6Ubootnand/include/net.h 7UbootTftp/include/net.h
--- 6Ubootnand/include/net.h    2013-03-10 20:45:12.500500278 +0800
+++ 7UbootTftp/include/net.h    2013-03-15 13:33:42.959027263 +0800
@@ -54,7 +54,9 @@
  
 #include <asm/byteorder.h>   /* for nton* / ntoh* stuff */
  
-
+#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
+extern ulong tftp_nand_counter ;
+#endif
 /*
  * The number of receive packet buffers, and the required packet buffer
  * alignment in memory.

diff -ru 6Ubootnand/common/cmd_net.c 7UbootTftp/common/cmd_net.c
--- 6Ubootnand/common/cmd_net.c 2013-03-10 20:45:12.432500274 +0800
+++ 7UbootTftp/common/cmd_net.c 2013-03-15 13:39:17.334305199 +0800
@@ -159,6 +159,11 @@
    int   size;
    ulong addr;
  
+#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
+   tftp_nand_counter = 0;
+#endif
+   //add by kangear for tftp nand
+
    /* pre-set load_addr */
    if ((s = getenv("loadaddr")) != NULL) {
        load_addr = simple_strtoul(s, NULL, 16);

解决Retry count exceeded; starting again 的问题, 改动如下:
diff -ru 6Ubootnand/include/configs/smdk2440.h 7UbootTftp/include/configs/smdk2440.h
--- 6Ubootnand/include/configs/smdk2440.h 2013-03-15 14:27:48.982175390 +0800
+++ 7UbootTftp/include/configs/smdk2440.h 2013-03-15 12:29:45.197981641 +0800
@@ -59,7 +59,7 @@
 //#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
 
 #define CONFIG_NET_MULTI 1
-#define CONFIG_NET_RETRY_COUNT 20
+#define CONFIG_NET_RETRY_COUNT 100 //20  kangear for tftp to nand
 #define CONFIG_DRIVER_DM9000 1 /* we have a dm9000 on-board */
 #define CONFIG_DM9000_BASE 0x20000000
 #define DM9000_IO CONFIG_DM9000_BASE
@@ -76,13 +76,11 @@
 #define CONFIG_ASM_DEBUG          1 /* we use SERIAL 1 on SMDK2410 */
 #define CONFIG_SKIP_LOWLEVEL_INIT 1
 #define CONFIG_SKIP_RELOCATE_UBOOT 1
-
 /*
- * boot size
+ * tftp 烧写到flash中
  */
-#define CONFIG_UBOOT_SIZE (CONFIG_ENV_ADDR-0)
-
-
+#define CONFIG_SYS_DIRECT_FLASH_TFTP 1
+#define CONFIG_TFTP_BLOCKSIZE 1024

算法的优化为这样的:
diff -ru 6Ubootnand/net/tftp.c 7UbootTftp/net/tftp.c
--- 6Ubootnand/net/tftp.c 2013-03-10 20:45:12.448500276 +0800
+++ 7UbootTftp/net/tftp.c 2013-03-15 14:13:35.915403248 +0800
@@ -9,6 +9,11 @@
 #include <net.h>
 #include "tftp.h"
 #include "bootp.h"
+#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
+#include <nand.h>
+ulong tftp_nand_counter = 0;
+static u_char tftp_nand_buffer[2048];
+#endif
 
 #if defined(CONFIG_CMD_NET)
 
@@ -131,7 +136,11 @@
  ulong newsize = offset + len;
 #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
  int i, rc = 0;
-
+ int data_end_flag = 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)
@@ -142,19 +151,44 @@
  }
  }
 
- if (rc) { /* Flash is destination for this packet */
- rc = flash_write ((char *)src, (ulong)(load_addr+offset), len);
+ nand = &nand_info[nand_curr_device];
+ off = (tftp_nand_counter-1)*1024;
+ length = 2048;
+ memcpy((uchar *)(tftp_nand_buffer+((tftp_nand_counter & 1) << 10)), (uchar *)src, 1024);
+ //memcpy((uchar *)tftp_nand_buffer[(tftp_nand_counter & 1) << 10], (uchar *)src, 1024);
+ buffer = (u_char *)tftp_nand_buffer;
+ printf("\nlen = %d, tftp_nand_counter = %d", len, tftp_nand_counter);
+ if(len < 1024)
+ {
+ data_end_flag = 1; //不足1k的。
+ if (0 == tftp_nand_counter)
+ tftp_nand_counter = 1;
+ else if(0 == (tftp_nand_counter & 1))  //在偶数次正好结束的。
+ {
+ buffer = (u_char *)src;
+ off    = tftp_nand_counter*1024;
+ }
+ }
+ if ( rc && ( data_end_flag || (0 != (tftp_nand_counter & 1))) ) { /* Flash is destination for this packet */
+ rc = nand_write_skip_bad(nand, off, &length, buffer);
+ //printf("\nhaha\n");
  if (rc) {
  flash_perror (rc);
  NetState = NETLOOP_FAIL;
  return;
  }
+
  }
  else
 #endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
  {
  (void)memcpy((void *)(load_addr + offset), src, len);
  }
+
+#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
+ tftp_nand_counter ++;
+#endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
+
 #ifdef CONFIG_MCAST_TFTP
  if (Multicast)
  ext2_set_bit(block, Bitmap);

另外:烧写内核(4.XM)还是会出现:
len = 1024, tftp_nand_counter = 398
len = 1024, tftp_nand_counter = 399
Retry count exceeded; starting again
dm9000 i/o: 0x20000000, id: 0x90000a46 
DM9000: running in 16 bit mode
MAC: 00:01:02:03:04:05
operating at 100M full duplex mode


Abort
SMDK2440 # 
解决方法和上边的应该还是同样的,加大CONFIG_NET_RETRY_COUNT应该就能解决。



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁保康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值