cheng029 发表于 2013-3-17 16:44:16

在U-boot上搭建TFTP服务器

   实现这个的整体目的是为了以后实现远程更新u-boot kernel rootfs而设计的。目前已经完全在u-boot实现的TFTP服务器了。先把它贴出来。说明:Uboot3是没有改动的。9UbootTftpServemini是移植好的。u-boot版本为2009.11.交叉工具链版本为:4.4.3测试开发板:mini2440(这些修改都是板级无关的,其它板子应该也是可以的)
一.添加命令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 @@
    " [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-setTFTP 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;         /* Boot File name      */


         这样就可以用这个命令了如下图所示:

         


二.网络层移植
         这次主要是移植的是net/net.c和include/net.h。添加仿照tftpboot的实现函数添加tftpserver函数TftpServerStart。具体的修改如下:

--- 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;   /* 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;/* 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服务器就算是移植成功了。



0 发表于 2013-3-17 16:49:03

不在课堂上沉睡,就在酒桌上埋醉。

chunjihong 发表于 2013-5-16 02:43:18

我的id是假冒的,大家不要相信我是骗子。

iszjw 发表于 2013-5-16 14:36:17

我是个凑数的。。。

李斯特 发表于 2013-5-17 03:09:17

我喜欢孩子,更喜欢造孩子的过程!

dog1888 发表于 2013-5-17 13:12:49

这是什么东东啊

szs 发表于 2013-5-18 00:28:44

爱——不是想出来的,爱——是做出来的!!
页: [1]
查看完整版本: 在U-boot上搭建TFTP服务器