实现这个的整体目的是为了以后实现远程更新u-boot kernel rootfs而设计的。目前已经完全在u-boot实现的TFTP服务器了。先把它贴出来。
说明:
Uboot3是没有改动的。
9UbootTftpServemini是移植好的。
u-boot版本为2009.11.
交叉工具链版本为:4.4.3
测试开发板:mini2440(这些修改都是板级无关的,其它板子应该也是可以的)
参考文档《BootLoader TFTP服务器功能的追加》
一.添加命令tftpserver
模仿tftpboot来添加,主要修改common/cmd_net.c和include/net.h。具体的改动如下:
--- Uboot3/common/cmd_net.c 2013-03-09 17:35:54.186849800 +0800 +++ 9UbootTftpServemini/common/cmd_net.c 2013-03-16 16:38:52.017695933 +0800 @@ -54,6 +54,17 @@ "[loadAddress] [[hostIPaddr:]bootfilename]" ); +int do_tftpserver (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + return netboot_common (TFTPSERVER , cmdtp, argc, argv); +} + +U_BOOT_CMD( + tftpserver, 1, 1, do_tftpserver, + "tftpserver-set TFTP server, wait client data.\n", + "[] []" +); + int do_rarpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { return netboot_common (RARP, cmdtp, argc, argv); |
--- Uboot3/include/net.h 2013-03-09 17:35:55.110849761 +0800 +++ 9UbootTftpServemini/include/net.h 2013-03-16 17:02:29.281754689 +0800 @@ -356,7 +357,7 @@ extern int NetRestartWrap; /* Tried all network devices */ #endif -typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP } proto_t; +typedef enum { BOOTP, RARP, ARP, TFTP, TFTPSERVER, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP } proto_t; /* from net/net.c */ extern char BootFile[128]; /* Boot File name */ |
这样就可以用这个命令了如下图所示:
二.网络层移植
--- Uboot3/include/net.h 2013-03-09 17:35:55.110849761 +0800 +++ 9UbootTftpServemini/include/net.h 2013-03-16 17:02:29.281754689 +0800 @@ -329,6 +329,7 @@ extern uchar NetServerEther[6]; /* Boot server enet address */ extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ extern IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */ +extern IPaddr_t NetClientIP; /* Server IP addr (0 = unknown) */ extern volatile uchar * NetTxPacket; /* THE transmit packet */ extern volatile uchar * NetRxPackets[PKTBUFSRX];/* Receive packets */ extern volatile uchar * NetRxPacket; /* Current receive packet */ |
--- Uboot3/net/net.c 2013-03-09 17:35:54.282849796 +0800 +++ 9UbootTftpServemini/net/net.c 2013-03-17 12:26:15.460618862 +0800 @@ -80,6 +80,7 @@ #include <net.h> #include "bootp.h" #include "tftp.h" +#include "tftpserver.h" #include "rarp.h" #include "nfs.h" #ifdef CONFIG_STATUS_LED @@ -138,6 +139,7 @@ { 0, 0, 0, 0, 0, 0 }; IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */ +IPaddr_t NetClientIP; /* Server IP addr (0 = unknown) */ volatile uchar *NetRxPacket; /* Current receive packet */ int NetRxPacketLen; /* Current rx packet length */ unsigned NetIPID; /* IP packet ID */ @@ -279,6 +281,7 @@ static void NetInitLoop(proto_t protocol) { + debug("NetInitLoop ... \n"); static int env_changed_id = 0; bd_t *bd = gd->bd; int env_id = get_env_id (); @@ -389,6 +392,12 @@ TftpStart(); break; + case TFTPSERVER: + puts("net.c/TFTPSERVER...\n"); + /* always use ARP to get server ethernet address */ + TftpServerStart(); + break; + #if defined(CONFIG_CMD_DHCP) case DHCP: BootpTry = 0; @@ -1672,6 +1681,7 @@ /* * IP header OK. Pass the packet to the current handler. */ + NetClientIP = NetReadIP(&ip->ip_src); (*packetHandler)((uchar *)ip +IP_HDR_SIZE, ntohs(ip->udp_dst), ntohs(ip->udp_src), @@ -1715,6 +1725,11 @@ case NFS: #endif case NETCONS: + case TFTPSERVER: + if (NetOurIP == 0) { + puts ("*** ERROR: `ipaddr' not set\n"); + return (1); + } case TFTP: if (NetServerIP == 0) { puts ("*** ERROR: `serverip' not set\n"); |
三.实现tftpserver处理函数
--- 9UbootTftpServemini/net/tftp.c 2013-03-17 14:59:43.660439608 +0800 +++ 9UbootTftpServemini/net/tftpserver.c 2013-03-17 15:36:20.575274671 +0800 @@ -7,7 +7,7 @@ #include <common.h> #include <command.h> #include <net.h> -#include "tftp.h" +#include "tftpserver.h" #include "bootp.h" #if defined(CONFIG_CMD_NET) @@ -44,8 +44,8 @@ * positive. The globals are meant to be set (and restored) by code needing * non-standard timeout behavior when initiating a TFTP transfer. */ -ulong TftpRRQTimeoutMSecs = TIMEOUT; -int TftpRRQTimeoutCountMax = TIMEOUT_COUNT; +static ulong TftpRRQTimeoutMSecs = TIMEOUT; +static TftpRRQTimeoutCountMax = TIMEOUT_COUNT; static IPaddr_t TftpServerIP; static int TftpServerPort; /* The UDP port at their end */ @@ -66,6 +66,8 @@ #define STATE_TOO_LARGE 3 #define STATE_BAD_MAGIC 4 #define STATE_OACK 5 +#define STATE_WAIT 6 +#define STATE_WRQ 7 #define TFTP_BLOCK_SIZE 512 /* default TFTP block size */ #define TFTP_SEQUENCE_SIZE ((ulong)(1<<16)) /* sequence number is 16 bit */ @@ -192,6 +194,15 @@ switch (TftpState) { + case STATE_WRQ: + xp = pkt; + s = (ushort *)pkt; + *s++ = htons(TFTP_ACK); + *s++ = htons(TftpBlock); + pkt = (uchar *)s; + len = pkt - xp; + break; + case STATE_RRQ: xp = pkt; s = (ushort *)pkt; @@ -283,7 +294,7 @@ #endif return; } - if (TftpState != STATE_RRQ && src != TftpServerPort) { + if (TftpState != STATE_WAIT && src != TftpServerPort) { return; } @@ -299,6 +310,12 @@ case TFTP_RRQ: case TFTP_WRQ: + NetServerIP = NetClientIP; + TftpBlock = 0; + TftpState = STATE_WRQ; + TftpServerPort = src; + TftpSend (); + break; case TFTP_ACK: break; default: @@ -492,15 +509,13 @@ #endif NetStartAgain (); } else { - puts ("T "); NetSetTimeout (TftpTimeoutMSecs, TftpTimeout); - TftpSend (); } } void -TftpStart (void) +TftpServerStart (void) { char *ep; /* Environment pointer */ @@ -572,9 +587,9 @@ TftpServerPort = WELL_KNOWN_PORT; TftpTimeoutCount = 0; - TftpState = STATE_RRQ; + TftpState = STATE_WAIT; /* Use a pseudo-random port unless a specific port is set */ - TftpOurPort = 1024 + (get_timer(0) % 3072); + TftpOurPort = WELL_KNOWN_PORT; #ifdef CONFIG_TFTP_PORT if ((ep = getenv("tftpdstp")) != NULL) { @@ -598,7 +613,6 @@ TftpNumchars = 0; #endif - TftpSend (); } #ifdef CONFIG_MCAST_TFTP |
--- Uboot3/net/tftp.h 2013-03-09 17:35:54.282849796 +0800 +++ 9UbootTftpServemini/net/tftpserver.h 2013-03-16 16:53:09.109731467 +0800 @@ -1,12 +1,14 @@ /* - * LiMon - BOOTP/TFTP. + * LiMon - BOOTP/TFTPSERVER. + * + * 2013 BY kangear * * Copyright 1994, 1995, 2000 Neil Russell. * (See License) */ -#ifndef __TFTP_H__ -#define __TFTP_H__ +#ifndef __TFTPSERVER_H__ +#define __TFTPSERVER_H__ /**********************************************************************/ /* @@ -14,8 +16,8 @@ */ /* tftp.c */ -extern void TftpStart (void); /* Begin TFTP get */ +extern void TftpServerStart (void); /* Begin TFTPSERVER get */ /**********************************************************************/ -#endif /* __TFTP_H__ */ +#endif /* __TFTPSERVER_H__ */ |
--- Uboot3/net/Makefile2013-03-09 17:35:54.282849796 +0800 +++ 9UbootTftpServemini/net/Makefile 2013-03-16 17:11:20.817776725 +0800 @@ -35,6 +35,7 @@ COBJS-y += rarp.o COBJS-$(CONFIG_CMD_SNTP) += sntp.o COBJS-y += tftp.o +COBJS-y += tftpserver.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) |
测试一下:
关于上图的打印信息仍然是tftpboot时候的打印信息。可以根据实际情况更改。
启动一下看看:
可以看到是可以启动的。至此tftp服务器就算是移植成功了。