• 关于uboot中tftp上传内存数据到tftp服务器


    uboot下的tftp下载功能是非常重要和常见的功能。但是偶尔有些特殊需求的人需要使用uboot的tftp具有上传功能。
    默认的uboot没有tftp上传功能,如果需要修改uboot代码。
    使用时键入第4个参数,则不同于3个参数的tftp下载功能。
    #tftp 50400000 xx.bin 10000
    TFTP to server 192.168.0.30; our IP address is 192.168.0.152
    Upload Filename 'xx.bin'.
    Upload from address: 0x50400000, 0.064 MB to be send ...
    Uploading: %#   [ Connected ]

             0.064 MB upload ok.
    这条命令将板子上0x50400000 开始,长度0x10000的数据上传到远程tftp服务器,命名为xx.bin

    这个修改在uboot1.3.4和2008.10版本上测试通过。
    1、修改common/cmd_net.c 
    注释掉

    1. /*
    2. int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
    3. {
    4.     return netboot_common (TFTP, cmdtp, argc, argv);
    5. }
    6. U_BOOT_CMD(
    7.     tftpboot,    3,    1,    do_tftpb,
    8.     "tftpboot- boot image via network using TFTP protocol ",
    9.     "[loadAddress] [[hostIPaddr:]bootfilename] "
    10. );
    11. */

    可以看出默认uboot执行tftp命令其实调用的是tftpboot,uboot果然是看命名的前面几个字母而不是全名。例如print命令只需要键入pri。
    接着添加

    1. int do_tftp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
    2. {
    3.     return netboot_common (TFTP, cmdtp, argc, argv);
    4. }
    5. U_BOOT_CMD(
    6.     tftp,    4,    1,    do_tftp,
    7.     "tftp - download or upload image via network using TFTP protocol ",
    8.     "[loadAddress] [bootfilename] <upload_size> "
    9. );

    然后修改netboot_common成如下代码

    1. static int
    2. netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
    3. {
    4.     extern ulong upload_addr;
    5.     extern ulong upload_size;
    6.     char *s;
    7.     int rcode = 0;
    8.     int size;
    9.     /* pre-set load_addr */
    10.     if ((s = getenv("loadaddr")) != NULL) {
    11.         load_addr = simple_strtoul(s, NULL, 16);
    12.     }
    13.     switch (argc) {
    14.     case 1:
    15.         break;
    16.     case 2:    /* only one arg - accept two forms:
    17.          * just load address, or just boot file name.
    18.          * The latter form must be written "filename" here.
    19.          */
    20.         if (argv[1][0] == '"') {    /* just boot filename */
    21.             copy_filename (BootFile, argv[1], sizeof(BootFile));
    22.         } else {            /* load address    */
    23.             load_addr = simple_strtoul(argv[1], NULL, 16);
    24.         }
    25.         break;
    26.     case 3:    load_addr = simple_strtoul(argv[1], NULL, 16);
    27.         copy_filename (BootFile, argv[2], sizeof(BootFile));
    28.         upload_size = 0;
    29.         
    30.         break;
    31.     
    32.     case 4:
    33.         upload_addr = simple_strtoul(argv[1], NULL, 16);
    34.         upload_size = simple_strtoul(argv[3], NULL, 16);
    35.         copy_filename (BootFile, argv[2], sizeof(BootFile));
    36.         break;
    37.     default: printf ("Usage: %s ", cmdtp->usage);
    38.         show_boot_progress (-80);
    39.         return 1;
    40.     }
    41.     show_boot_progress (80);
    42.     if ((size = NetLoop(proto)) < 0) {
    43.         show_boot_progress (-81);
    44.         return 1;
    45.     }
    46.     show_boot_progress (81);
    47.     /* NetLoop ok, update environment */
    48.     netboot_update_env();
    49.     /* done if no file was loaded (no errors though) */
    50.     if (size == 0) {
    51.         show_boot_progress (-82);
    52.         return 0;
    53.     }
    54.     /* flush cache */
    55.     flush_cache(load_addr, size);
    56.     /* Loading ok, check if we should attempt an auto-start */
    57.     if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
    58.         char *local_args[2];
    59.         local_args[0] = argv[0];
    60.         local_args[1] = NULL;
    61.         printf ("Automatic boot of image at addr 0x%08lX ... ",
    62.             load_addr);
    63.         show_boot_progress (82);
    64.         rcode = do_bootm (cmdtp, 0, 1, local_args);
    65.     }
    66. #ifdef CONFIG_AUTOSCRIPT
    67.     if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
    68.         printf ("Running autoscript at addr 0x%08lX", load_addr);
    69.         s = getenv ("autoscript_uname");
    70.         if (s)
    71.             printf (":%s ... ", s);
    72.         else
    73.             puts (" ... ");
    74.         show_boot_progress (83);
    75.         rcode = autoscript (load_addr, s);
    76.     }
    77. #endif
    78.     if (rcode < 0)
    79.         show_boot_progress (-83);
    80.     else
    81.         show_boot_progress (84);
    82.     return rcode;
    83. }

    2、修改net/tftp.c 为

    1. /*
    2. * Copyright 1994, 1995, 2000 Neil Russell.
    3. * (See License)
    4. * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
    5. */
    6. #include <common.h>
    7. #include <command.h>
    8. #include <net.h>
    9. #include "tftp.h"
    10. #include "bootp.h"
    11. #undef ET_DEBUG
    12. #if defined(CONFIG_CMD_NET)
    13. #define WELL_KNOWN_PORT 69 /* Well known TFTP port # */
    14. #define TIMEOUT 1 /* Seconds to timeout for a lost pkt */
    15. #ifndef CONFIG_NET_RETRY_COUNT
    16. # define TIMEOUT_COUNT 10 /* # of timeouts before giving up */
    17. #else
    18. # define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT * 2)
    19. #endif
    20. /* (for checking the image size) */
    21. #define TBLKS_PER_HASHES 64
    22. #define HASHES_PER_LINE 32 /* Number of "loading" hashes per line */
    23. /*
    24. * TFTP operations.
    25. */
    26. #define TFTP_RRQ 1
    27. #define TFTP_WRQ 2
    28. #define TFTP_DATA 3
    29. #define TFTP_ACK 4
    30. #define TFTP_ERROR 5
    31. #define TFTP_OACK 6
    32. #define STATE_OK 0
    33. #define STATE_ERROR 3
    34. #define STATE_WRQ 6
    35. #define STATE_ACK 7
    36. static IPaddr_t TftpServerIP;
    37. static int TftpServerPort; /* The UDP port at their end */
    38. static int TftpOurPort; /* The UDP port at our end */
    39. static int TftpTimeoutCount;
    40. static ulong TftpBlock; /* packet sequence number */
    41. static ulong TftpLastBlock; /* last packet sequence number received */
    42. static ulong TftpBlockWrap; /* count of sequence number wraparounds */
    43. static ulong TftpBlockWrapOffset; /* memory offset due to wrapping */
    44. static int TftpState;
    45. #define STATE_RRQ 1
    46. #define STATE_DATA 2
    47. #define STATE_TOO_LARGE 3
    48. #define STATE_BAD_MAGIC 4
    49. #define STATE_OACK 5
    50. #define TFTP_BLOCK_SIZE 512 /* default TFTP block size */
    51. #define TFTP_SEQUENCE_SIZE ((ulong)(1<<16)) /* sequence number is 16 bit */
    52. #define DEFAULT_NAME_LEN (8 + 4 + 1)
    53. static char default_filename[DEFAULT_NAME_LEN];
    54. #ifndef CONFIG_TFTP_FILE_NAME_MAX_LEN
    55. #define MAX_LEN 128
    56. #else
    57. #define MAX_LEN CONFIG_TFTP_FILE_NAME_MAX_LEN
    58. #endif
    59. static char tftp_filename[MAX_LEN];
    60. #ifdef CFG_DIRECT_FLASH_TFTP
    61. extern flash_info_t flash_info[];
    62. #endif
    63. ulong upload_addr = CFG_LOAD_ADDR; /* Default upLoad Address */
    64. ulong upload_size = 0;
    65. /* 512 is poor choice for ethernet, MTU is typically 1500.
    66. * Minus eth.hdrs thats 1468. Can get 2x better throughput with
    67. * almost-MTU block sizes. At least try... fall back to 512 if need be.
    68. */
    69. #define TFTP_MTU_BLOCKSIZE 1468
    70. static unsigned short TftpBlkSize=TFTP_BLOCK_SIZE;
    71. static unsigned short TftpBlkSizeOption=TFTP_MTU_BLOCKSIZE;
    72. #ifdef CONFIG_MCAST_TFTP
    73. #include <malloc.h>
    74. #define MTFTP_BITMAPSIZE 0x1000
    75. static unsigned *Bitmap;
    76. static int PrevBitmapHole,Mapsize=MTFTP_BITMAPSIZE;
    77. static uchar ProhibitMcast=0, MasterClient=0;
    78. static uchar Multicast=0;
    79. extern IPaddr_t Mcast_addr;
    80. static int Mcast_port;
    81. static ulong TftpEndingBlock; /* can get 'last' block before done..*/
    82. static void parse_multicast_oack(char *pkt,int len);
    83. static void
    84. mcast_cleanup(void)
    85. {
    86. if (Mcast_addr) eth_mcast_join(Mcast_addr, 0);
    87. if (Bitmap) free(Bitmap);
    88. Bitmap=NULL;
    89. Mcast_addr = Multicast = Mcast_port = 0;
    90. TftpEndingBlock = -1;
    91. }
    92. #endif /* CONFIG_MCAST_TFTP */
    93. static __inline__ void
    94. store_block (unsigned block, uchar * src, unsigned len)
    95. {
    96. ulong offset = block * TftpBlkSize + TftpBlockWrapOffset;
    97. ulong newsize = offset + len;
    98. #ifdef CFG_DIRECT_FLASH_TFTP
    99. int i, rc = 0;
    100. for (i=0; i<CFG_MAX_FLASH_BANKS; i++) {
    101. /* start address in flash? */
    102. if (flash_info[i].flash_id == FLASH_UNKNOWN)
    103. continue;
    104. if ((load_addr + offset >= flash_info[i].start[0]) && (load_addr + offset < flash_info[i].start[0] + flash_info[i].size)) {
    105. rc = 1;
    106. break;
    107. }
    108. }
    109. if (rc) { /* Flash is destination for this packet */
    110. rc = flash_write ((char *)src, (ulong)(load_addr+offset), len);
    111. if (rc) {
    112. flash_perror (rc);
    113. NetState = NETLOOP_FAIL;
    114. return;
    115. }
    116. }
    117. else
    118. #endif /* CFG_DIRECT_FLASH_TFTP */
    119. {
    120. (void)memcpy((void *)(load_addr + offset), src, len);
    121. }
    122. #ifdef CONFIG_MCAST_TFTP
    123. if (Multicast)
    124. ext2_set_bit(block, Bitmap);
    125. #endif
    126. if (NetBootFileXferSize < newsize)
    127. NetBootFileXferSize = newsize;
    128. }
    129. static void TftpSend (void);
    130. static void TftpTimeout (void);
    131. /**********************************************************************/
    132. static void
    133. TftpSend (void)
    134. {
    135. volatile uchar * pkt;
    136. volatile uchar * xp;
    137. int len = 0;
    138. int uplen=0;
    139. volatile ushort *s;
    140. #ifdef CONFIG_MCAST_TFTP
    141. /* Multicast TFTP.. non-MasterClients do not ACK data. */
    142. if (Multicast
    143. && (TftpState == STATE_DATA)
    144. && (MasterClient == 0))
    145. return;
    146. #endif
    147. /*
    148. * We will always be sending some sort of packet, so
    149. * cobble together the packet headers now.
    150. */
    151. pkt = NetTxPacket + NetEthHdrSize() + IP_HDR_SIZE;
    152. switch (TftpState) {
    153. case STATE_RRQ:
    154. case STATE_WRQ:
    155. xp = pkt;
    156. s = (ushort *)pkt;
    157. if(TftpState == STATE_WRQ)
    158. *s++ = htons(TFTP_WRQ);
    159. else *s++ = htons(TFTP_RRQ);
    160. pkt = (uchar *)s;
    161. strcpy ((char *)pkt, tftp_filename);
    162. pkt += strlen(tftp_filename) + 1;
    163. strcpy ((char *)pkt, "octet");
    164. pkt += 5 /*strlen("octet")*/ + 1;
    165. strcpy ((char *)pkt, "timeout");
    166. pkt += 7 /*strlen("timeout")*/ + 1;
    167. sprintf((char *)pkt, "%d", TIMEOUT);
    168. #ifdef ET_DEBUG
    169. printf("send option "timeout %s" ", (char *)pkt);
    170. #endif
    171. pkt += strlen((char *)pkt) + 1;
    172. /* try for more effic. blk size */
    173. if(TftpState == STATE_WRQ)
    174. pkt += sprintf((char *)pkt,"blksize%c%d%c",
    175. 0,TftpBlkSizeOption,0);
    176. else
    177. pkt += sprintf((char *)pkt,"blksize%c%d%c",
    178. 0,TftpBlkSizeOption,0);
    179. #ifdef CONFIG_MCAST_TFTP
    180. /* Check all preconditions before even trying the option */
    181. if (!ProhibitMcast
    182. && (Bitmap=malloc(Mapsize))
    183. && eth_get_dev()->mcast) {
    184. free(Bitmap);
    185. Bitmap=NULL;
    186. pkt += sprintf((char *)pkt,"multicast%c%c",0,0);
    187. }
    188. #endif /* CONFIG_MCAST_TFTP */
    189. len = pkt - xp;
    190. printf("%%");
    191. break;
    192. case STATE_OACK:
    193. #ifdef CONFIG_MCAST_TFTP
    194. /* My turn! Start at where I need blocks I missed.*/
    195. if (Multicast)
    196. TftpBlock=ext2_find_next_zero_bit(Bitmap,(Mapsize*8),0);
    197. /*..falling..*/
    198. #endif
    199. case STATE_DATA:
    200. xp = pkt;
    201. s = (ushort *)pkt;
    202. *s++ = htons(TFTP_ACK);
    203. *s++ = htons(TftpBlock);
    204. pkt = (uchar *)s;
    205. len = pkt - xp;
    206. break;
    207. case STATE_TOO_LARGE:
    208. xp = pkt;
    209. s = (ushort *)pkt;
    210. *s++ = htons(TFTP_ERROR);
    211. *s++ = htons(3);
    212. pkt = (uchar *)s;
    213. strcpy ((char *)pkt, "File too large");
    214. pkt += 14 /*strlen("File too large")*/ + 1;
    215. len = pkt - xp;
    216. break;
    217. case STATE_BAD_MAGIC:
    218. xp = pkt;
    219. s = (ushort *)pkt;
    220. *s++ = htons(TFTP_ERROR);
    221. *s++ = htons(2);
    222. pkt = (uchar *)s;
    223. strcpy ((char *)pkt, "File has bad magic");
    224. pkt += 18 /*strlen("File has bad magic")*/ + 1;
    225. len = pkt - xp;
    226. break;
    227. case STATE_ACK:
    228. xp = pkt;
    229. s = (ushort *)pkt;
    230. *s++ = htons(TFTP_DATA);
    231. *s++ = htons(TftpBlock+1);
    232. pkt = (uchar *)s;
    233. uplen = (upload_size-TftpBlock*TftpBlkSize);
    234. uplen = uplen > TftpBlkSize ? TftpBlkSize : uplen;
    235. memcpy((void*)pkt, (const char*)upload_addr + TftpBlock*TftpBlkSize , uplen);
    236. pkt += uplen;
    237. len = pkt - xp;
    238. break;
    239. default:
    240. return;
    241. }
    242. NetSendUDPPacket(NetServerEther, TftpServerIP, TftpServerPort, TftpOurPort, len);
    243. }
    244. static void tftp_show_transferd(int block, unsigned long wrap)
    245. {
    246. #define SHOW_TRANSFERD(tail) printf (" [%2lu.%03lu MB]%s", ((block-1)* TftpBlkSize + wrap)>>20,
    247. (((block-1) * TftpBlkSize + wrap)&0x0FFFFF)>>10, tail)
    248. if( ((block-1) & (TBLKS_PER_HASHES-1)) == 0)
    249. putc('#');
    250. if( ((block-1) & (TBLKS_PER_HASHES*HASHES_PER_LINE-1)) == 0) {
    251. if((block-1) ==0) {
    252. if(wrap==0) {
    253. puts(" [ Connected ] ");
    254. } else {
    255. SHOW_TRANSFERD(" [BlockCounter Reset] ");
    256. }
    257. } else {
    258. SHOW_TRANSFERD(" ");
    259. }
    260. }
    261. #undef SHOW_TRANSFERD
    262. }
    263. static void
    264. TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
    265. {
    266. ushort proto;
    267. ushort *s;
    268. int i;
    269. if (dest != TftpOurPort) {
    270. #ifdef CONFIG_MCAST_TFTP
    271. if (Multicast
    272. && (!Mcast_port || (dest != Mcast_port)))
    273. #endif
    274. return;
    275. }
    276. if ( !(TftpState==STATE_RRQ || TftpState==STATE_WRQ) && src != TftpServerPort) {
    277. return;
    278. }
    279. if (len < 2) {
    280. return;
    281. }
    282. len -= 2;
    283. /* warning: don't use increment (++) in ntohs() macros!! */
    284. s = (ushort *)pkt;
    285. proto = *s++;
    286. pkt = (uchar *)s;
    287. switch (ntohs(proto)) {
    288. case TFTP_RRQ:
    289. case TFTP_WRQ:
    290. break;
    291. case TFTP_ACK:
    292. TftpServerPort = src;
    293. TftpState=STATE_ACK;
    294. TftpBlock = ntohs(*(ushort *)pkt);
    295. if(TftpLastBlock == TftpBlock) {
    296. putc('%');
    297. } else {
    298. tftp_show_transferd(TftpBlock, TftpBlockWrapOffset);
    299. }
    300. TftpLastBlock = TftpBlock;
    301. NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
    302. if(TftpBlkSize*TftpBlock> upload_size )
    303. {
    304. NetState = NETLOOP_SUCCESS;
    305. TftpState = STATE_OK;
    306. printf (" %lu.%03lu MB upload ok. ", (TftpBlockWrapOffset+upload_size)>>20,
    307. ((TftpBlockWrapOffset+upload_size)&0x0FFFFF)>>10);
    308. break;
    309. }
    310. TftpSend (); /* Send ACK */
    311. break;
    312. default:
    313. break;
    314. case TFTP_OACK:
    315. #ifdef ET_DEBUG
    316. printf("Got OACK: %s %s ", pkt, pkt+strlen(pkt)+1);
    317. #endif
    318. if(TftpState == STATE_WRQ)
    319. {
    320. TftpState = STATE_ACK;
    321. TftpBlock = 0;
    322. }
    323. else
    324. {
    325. TftpState = STATE_OACK;
    326. }
    327. TftpServerPort = src;
    328. /*
    329. * Check for 'blksize' option.
    330. * Careful: "i" is signed, "len" is unsigned, thus
    331. * something like "len-8" may give a *huge* number
    332. */
    333. for (i=0; i+8<len; i++) {
    334. if (strcmp ((char*)pkt+i,"blksize") == 0) {
    335. TftpBlkSize = (unsigned short)
    336. simple_strtoul((char*)pkt+i+8,NULL,10);
    337. #ifdef ET_DEBUG
    338. printf ("Blocksize ack: %s, %d ",
    339. (char*)pkt+i+8,TftpBlkSize);
    340. #endif
    341. break;
    342. }
    343. }
    344. #ifdef CONFIG_MCAST_TFTP
    345. parse_multicast_oack((char *)pkt,len-1);
    346. if ((Multicast) && (!MasterClient))
    347. TftpState = STATE_DATA; /* passive.. */
    348. else
    349. #endif
    350. TftpSend (); /* Send ACK */
    351. break;
    352. case TFTP_DATA:
    353. if (len < 2)
    354. return;
    355. len -= 2;
    356. TftpBlock = ntohs(*(ushort *)pkt);
    357. /*
    358. * RFC1350 specifies that the first data packet will
    359. * have sequence number 1. If we receive a sequence
    360. * number of 0 this means that there was a wrap
    361. * around of the (16 bit) counter.
    362. */
    363. if (TftpBlock == 0) {
    364. TftpBlockWrap++;
    365. TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE;
    366. printf (" %lu MB received ", TftpBlockWrapOffset>>20);
    367. } else {
    368. #if 0
    369. if (((TftpBlock - 1) % 10) == 0) {
    370. putc ('#');
    371. } else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) {
    372. puts (" ");
    373. }
    374. #endif
    375. tftp_show_transferd(TftpBlock, TftpBlockWrapOffset);
    376. }
    377. #ifdef ET_DEBUG
    378. if (TftpState == STATE_RRQ) {
    379. puts ("Server did not acknowledge timeout option! ");
    380. }
    381. #endif
    382. if (TftpState == STATE_RRQ || TftpState == STATE_OACK) {
    383. /* first block received */
    384. TftpState = STATE_DATA;
    385. TftpServerPort = src;
    386. TftpLastBlock = 0;
    387. TftpBlockWrap = 0;
    388. TftpBlockWrapOffset = 0;
    389. #ifdef CONFIG_MCAST_TFTP
    390. if (Multicast) { /* start!=1 common if mcast */
    391. TftpLastBlock = TftpBlock - 1;
    392. } else
    393. #endif
    394. if (TftpBlock != 1) { /* Assertion */
    395. printf (" TFTP error: "
    396. "First block is not block 1 (%ld) "
    397. "Starting again ",
    398. TftpBlock);
    399. NetStartAgain ();
    400. break;
    401. }
    402. }
    403. if (TftpBlock == TftpLastBlock) {
    404. /*
    405. * Same block again; ignore it.
    406. */
    407. putc ('%');
    408. break;
    409. }
    410. TftpLastBlock = TftpBlock;
    411. NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
    412. store_block (TftpBlock - 1, pkt + 2, len);
    413. /*
    414. * Acknoledge the block just received, which will prompt
    415. * the server for the next one.
    416. */
    417. #ifdef CONFIG_MCAST_TFTP
    418. /* if I am the MasterClient, actively calculate what my next
    419. * needed block is; else I'm passive; not ACKING
    420. */
    421. if (Multicast) {
    422. if (len < TftpBlkSize) {
    423. TftpEndingBlock = TftpBlock;
    424. } else if (MasterClient) {
    425. TftpBlock = PrevBitmapHole =
    426. ext2_find_next_zero_bit(
    427. Bitmap,
    428. (Mapsize*8),
    429. PrevBitmapHole);
    430. if (TftpBlock > ((Mapsize*8) - 1)) {
    431. printf ("tftpfile too big ");
    432. /* try to double it and retry */
    433. Mapsize<<=1;
    434. mcast_cleanup();
    435. NetStartAgain ();
    436. return;
    437. }
    438. TftpLastBlock = TftpBlock;
    439. }
    440. }
    441. #endif
    442. TftpSend ();
    443. #ifdef CONFIG_MCAST_TFTP
    444. if (Multicast) {
    445. if (MasterClient && (TftpBlock >= TftpEndingBlock)) {
    446. puts (" Multicast tftp done ");
    447. mcast_cleanup();
    448. NetState = NETLOOP_SUCCESS;
    449. }
    450. }
    451. else
    452. #endif
    453. if (len < TftpBlkSize) {
    454. /*
    455. * We received the whole thing. Try to
    456. * run it.
    457. */
    458. printf (" %lu.%03lu MB download ok. ", ((TftpBlock-1)* TftpBlkSize + TftpBlockWrapOffset)>>20,
    459. (((TftpBlock-1) * TftpBlkSize + TftpBlockWrapOffset)&0x0FFFFF)>>10);
    460. puts (" done ");
    461. NetState = NETLOOP_SUCCESS;
    462. }
    463. break;
    464. case TFTP_ERROR:
    465. printf (" TFTP error: '%s' (%d) ",
    466. pkt + 2, ntohs(*(ushort *)pkt));
    467. puts ("Starting again ");
    468. #ifdef CONFIG_MCAST_TFTP
    469. mcast_cleanup();
    470. #endif
    471. NetStartAgain ();
    472. break;
    473. }
    474. }
    475. static void
    476. TftpTimeout (void)
    477. {
    478. if (++TftpTimeoutCount > TIMEOUT_COUNT) {
    479. puts (" Retry count exceeded; starting again ");
    480. #ifdef CONFIG_MCAST_TFTP
    481. mcast_cleanup();
    482. #endif
    483. NetStartAgain ();
    484. } else {
    485. puts ("T ");
    486. NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
    487. TftpSend ();
    488. }
    489. }
    490. void
    491. TftpStart (void)
    492. {
    493. #ifdef CONFIG_TFTP_PORT
    494. char *ep; /* Environment pointer */
    495. #endif
    496. if(upload_size)
    497. TftpState = STATE_WRQ;
    498. else TftpState = STATE_RRQ;
    499. TftpServerIP = NetServerIP;
    500. if (BootFile[0] == '') {
    501. sprintf(default_filename, "%02lX%02lX%02lX%02lX.img",
    502. NetOurIP & 0xFF,
    503. (NetOurIP >> 8) & 0xFF,
    504. (NetOurIP >> 16) & 0xFF,
    505. (NetOurIP >> 24) & 0xFF );
    506. strncpy(tftp_filename, default_filename, MAX_LEN);
    507. tftp_filename[MAX_LEN-1] = 0;
    508. printf ("*** Warning: no boot file name; using '%s' ",
    509. tftp_filename);
    510. } else {
    511. char *p = strchr (BootFile, ':');
    512. if (p == NULL) {
    513. strncpy(tftp_filename, BootFile, MAX_LEN);
    514. tftp_filename[MAX_LEN-1] = 0;
    515. } else {
    516. *p++ = '';
    517. TftpServerIP = string_to_ip (BootFile);
    518. strncpy(tftp_filename, p, MAX_LEN);
    519. tftp_filename[MAX_LEN-1] = 0;
    520. }
    521. }
    522. #if defined(CONFIG_NET_MULTI)
    523. printf ("Using %s device ", eth_get_name());
    524. #endif
    525. if( TftpState == STATE_WRQ)
    526. {
    527. puts ("TFTP to server "); print_IPaddr (NetServerIP);
    528. }
    529. else
    530. {
    531. puts ("TFTP from server "); print_IPaddr (TftpServerIP);
    532. }
    533. puts ("; our IP address is "); print_IPaddr (NetOurIP);
    534. /* Check if we need to send across this subnet */
    535. if (NetOurGatewayIP && NetOurSubnetMask) {
    536. IPaddr_t OurNet = NetOurIP & NetOurSubnetMask;
    537. IPaddr_t ServerNet = TftpServerIP & NetOurSubnetMask;
    538. if (OurNet != ServerNet) {
    539. puts ("; sending through gateway ");
    540. print_IPaddr (NetOurGatewayIP) ;
    541. }
    542. }
    543. putc (' ');
    544. if( TftpState == STATE_WRQ)
    545. printf ("Upload Filename '%s'.", tftp_filename);
    546. else printf ("Download Filename '%s'.", tftp_filename);
    547. if (NetBootFileSize) {
    548. printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9);
    549. print_size (NetBootFileSize<<9, "");
    550. }
    551. putc (' ');
    552. if( TftpState == STATE_WRQ)
    553. {
    554. printf ("Upload from address: 0x%lx, ", upload_addr);
    555. printf ("%lu.%03lu MB to be send ... ", upload_size>>20, (upload_size&0x0FFFFF)>>10);
    556. printf ("Uploading: *");
    557. }
    558. else
    559. {
    560. printf ("Download to address: 0x%lx ", load_addr);
    561. printf ("Downloading: *");
    562. }
    563. NetSetTimeout (TIMEOUT * CFG_HZ, TftpTimeout);
    564. NetSetHandler (TftpHandler);
    565. TftpServerPort = WELL_KNOWN_PORT;
    566. TftpTimeoutCount = 0;
    567. /* Use a pseudo-random port unless a specific port is set */
    568. TftpOurPort = 1024 + (get_timer(0) % 3072);
    569. #ifdef CONFIG_TFTP_PORT
    570. if ((ep = getenv("tftpdstp")) != NULL) {
    571. TftpServerPort = simple_strtol(ep, NULL, 10);
    572. }
    573. if ((ep = getenv("tftpsrcp")) != NULL) {
    574. TftpOurPort= simple_strtol(ep, NULL, 10);
    575. }
    576. #endif
    577. TftpBlock = 0;
    578. TftpLastBlock = 0;
    579. TftpBlockWrap = 0;
    580. TftpBlockWrapOffset = 0;
    581. /* zero out server ether in case the server ip has changed */
    582. memset(NetServerEther, 0, 6);
    583. /* Revert TftpBlkSize to dflt */
    584. TftpBlkSize = TFTP_BLOCK_SIZE;
    585. #ifdef CONFIG_MCAST_TFTP
    586. mcast_cleanup();
    587. #endif
    588. TftpSend ();
    589. }
    590. #ifdef CONFIG_MCAST_TFTP
    591. /* Credits: atftp project.
    592. */
    593. /* pick up BcastAddr, Port, and whether I am [now] the master-client. *
    594. * Frame:
    595. * +-------+-----------+---+-------~~-------+---+
    596. * | opc | multicast | 0 | addr, port, mc | 0 |
    597. * +-------+-----------+---+-------~~-------+---+
    598. * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then
    599. * I am the new master-client so must send ACKs to DataBlocks. If I am not
    600. * master-client, I'm a passive client, gathering what DataBlocks I may and
    601. * making note of which ones I got in my bitmask.
    602. * In theory, I never go from master->passive..
    603. * .. this comes in with pkt already pointing just past opc
    604. */
    605. static void parse_multicast_oack(char *pkt, int len)
    606. {
    607. int i;
    608. IPaddr_t addr;
    609. char *mc_adr, *port, *mc;
    610. mc_adr=port=mc=NULL;
    611. /* march along looking for 'multicast', which has to start at least
    612. * 14 bytes back from the end.
    613. */
    614. for (i=0;i<len-14;i++)
    615. if (strcmp (pkt+i,"multicast") == 0)
    616. break;
    617. if (i >= (len-14)) /* non-Multicast OACK, ign. */
    618. return;
    619. i+=10; /* strlen multicast */
    620. mc_adr = pkt+i;
    621. for (;i<len;i++) {
    622. if (*(pkt+i) == ',') {
    623. *(pkt+i) = '';
    624. if (port) {
    625. mc = pkt+i+1;
    626. break;
    627. } else {
    628. port = pkt+i+1;
    629. }
    630. }
    631. }
    632. if (!port || !mc_adr || !mc ) return;
    633. if (Multicast && MasterClient) {
    634. printf ("I got a OACK as master Client, WRONG! ");
    635. return;
    636. }
    637. /* ..I now accept packets destined for this MCAST addr, port */
    638. if (!Multicast) {
    639. if (Bitmap) {
    640. printf ("Internal failure! no mcast. ");
    641. free(Bitmap);
    642. Bitmap=NULL;
    643. ProhibitMcast=1;
    644. return ;
    645. }
    646. /* I malloc instead of pre-declare; so that if the file ends
    647. * up being too big for this bitmap I can retry
    648. */
    649. if (!(Bitmap = malloc (Mapsize))) {
    650. printf ("No Bitmap, no multicast. Sorry. ");
    651. ProhibitMcast=1;
    652. return;
    653. }
    654. memset (Bitmap,0,Mapsize);
    655. PrevBitmapHole = 0;
    656. Multicast = 1;
    657. }
    658. addr = string_to_ip(mc_adr);
    659. if (Mcast_addr != addr) {
    660. if (Mcast_addr)
    661. eth_mcast_join(Mcast_addr, 0);
    662. if (eth_mcast_join(Mcast_addr=addr, 1)) {
    663. printf ("Fail to set mcast, revert to TFTP ");
    664. ProhibitMcast=1;
    665. mcast_cleanup();
    666. NetStartAgain();
    667. }
    668. }
    669. MasterClient = (unsigned char)simple_strtoul((char *)mc,NULL,10);
    670. Mcast_port = (unsigned short)simple_strtoul(port,NULL,10);
    671. printf ("Multicast: %s:%d [%d] ", mc_adr, Mcast_port, MasterClient);
    672. return;
    673. }
    674. #endif /* Multicast TFTP */
    675. #endif
     
     
  • 相关阅读:
    iOS如何隐藏状态栏,包括网络标志、时间标志、电池标志等
    xcrun: error: active developer path
    我们很少有机会看到一个人的所有面
    默妹(二)
    Bootstrap3的响应式缩略图幻灯轮播效果设计
    纯CSS3实现图片展示特效
    解决div设置浮动,高度消失
    解决css设置背景透明,文字不透明
    从零开始学习jQuery (六) jquery中的AJAX使用
    如何利用开源思想开发一个SEO友好型网
  • 原文地址:https://www.cnblogs.com/lidabo/p/5719247.html
Copyright © 2020-2023  润新知