Skip to contentSkip to conversation

Add tftpput command for uploading files over network

PATCH New Simon Glass 4 participants 25 messages Oct 22, 2011 – Oct 30, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover Add tftpput command for uploading files over network

The tftpboot command permits reading of files over a network interface using the Trivial FTP protocol. This patch series adds the ability to transfer files the other way.

Why is this useful?

- Uploading boot time data to a server
- Uploading profiling information
- Uploading large mounts of data for comparison / checking on a host (e.g. use tftpput and ghex2 instead of the 'md' command)

Mostly the existing code can be re-used and I have tried to avoid too much refactoring or cleaning up.

The feature is activated by the CONFIG_CMD_TFTPPUT option.

This has been very lightly tested on a Seaboard with a USB network adaptor. I don't think it handles block number overflow.

Simon Glass (8):
Move simple_itoa to vsprintf
Add setenv_uint() and setenv_addr()
tftpput: Rename TFTP to TFTPGET
tftpput: move common code into separate functions
tftpput: support selecting get/put for tftp
tftpput: add save_addr and save_size global variables
tftpput: implement tftp logic
tftpput: add tftpput command

 README                   |    2 +
 common/cmd_net.c         |   31 +++++++-
 common/cmd_nvedit.c      |   31 ++++++++
 common/hush.c            |   15 ----
 include/common.h         |    5 +
 include/config_cmd_all.h |    1 +
 include/net.h            |    8 +-
 lib/vsprintf.c           |   16 ++++
 net/bootp.c              |    2 +-
 net/net.c                |   22 +++---
 net/tftp.c               |  189 +++++++++++++++++++++++++++++++++-------------
 net/tftp.h               |    2 +-
 12 files changed, 238 insertions(+), 86 deletions(-)
Signature · 1 line
1.7.3.1
#1 lore raw

PATCH 1/8 Move simple_itoa to vsprintf

This function is generally useful and shouldn't hide away in hush. It has been moved as is.

---
 common/hush.c    |   15 ---------------
 include/common.h |    1 +
 lib/vsprintf.c   |   16 ++++++++++++++++
 3 files changed, 17 insertions(+), 15 deletions(-)
common/hush.c +0 -15
index 85a6030..9bdb499 100644
@@ -17,7 +17,6 @@
  *      Erik W. Troan, which they placed in the public domain.  I don't know
  *      how much of the Johnson/Troan code has survived the repeated rewrites.
  * Other credits:
- *      simple_itoa() was lifted from boa-0.93.15
  *      b_addchr() derived from similar w_addchar function in glibc-2.2
  *      setup_redirect(), redirect_opt_num(), and big chunks of main()
  *        and many builtins derived from contributions by Erik Andersen
@@ -922,20 +921,6 @@ static int b_addqchr(o_string *o, int ch, int quote)
 	return b_addchr(o, ch);
 }
 
-/* belongs in utility.c */
-char *simple_itoa(unsigned int i)
-{
-	/* 21 digits plus null terminator, good for 64-bit or smaller ints */
-	static char local[22];
-	char *p = &local[21];
-	*p-- = '\0';
-	do {
-		*p-- = '0' + i % 10;
-		i /= 10;
-	} while (i > 0);
-	return p + 1;
-}
-
 #ifndef __U_BOOT__
 static int b_adduint(o_string *o, unsigned int i)
 {
include/common.h +1 -0
index eb19a44..55f772d 100644
@@ -702,6 +702,7 @@ void	panic(const char *fmt, ...)
 int	sprintf(char * buf, const char *fmt, ...)
 		__attribute__ ((format (__printf__, 2, 3)));
 int	vsprintf(char *buf, const char *fmt, va_list args);
+char *simple_itoa(ulong i);
 
 /* lib/strmhz.c */
 char *	strmhz(char *buf, unsigned long hz);
lib/vsprintf.c +16 -0
index 79dead3..e497a86 100644
@@ -7,6 +7,8 @@
 /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
 /*
  * Wirzenius wrote this portably, Torvalds fucked it up :-)
+ *
+ * from hush: simple_itoa() was lifted from boa-0.93.15
  */
 
 #include <stdarg.h>
@@ -738,3 +740,17 @@ void __assert_fail(const char *assertion, const char *file, unsigned line,
 	panic("%s:%u: %s: Assertion `%s' failed.", file, line, function,
 	      assertion);
 }
+
+char *simple_itoa(ulong i)
+{
+	/* 21 digits plus null terminator, good for 64-bit or smaller ints */
+	static char local[22];
+	char *p = &local[21];
+
+	*p-- = '\0';
+	do {
+		*p-- = '0' + i % 10;
+		i /= 10;
+	} while (i > 0);
+	return p + 1;
+}
Signature · 1 line
1.7.3.1
#2 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

In reply to Simon Glass

It seems we put numbers and addresses into environment variables a lot. We should have some functions to do this.

---
 common/cmd_nvedit.c |   29 +++++++++++++++++++++++++++++
 include/common.h    |    2 ++
 2 files changed, 31 insertions(+), 0 deletions(-)
common/cmd_nvedit.c +29 -0
index 101bc49..da7028c 100644
@@ -377,6 +377,35 @@ int setenv(const char *varname, const char *varvalue)
 		return _do_env_set(0, 3, (char * const *)argv);
 }
 
+/**
+ * Set an environment variable to an integer value
+ *
+ * @param varname	Environmet variable to set
+ * @param value		Value to set it to
+ * @return 0 if ok, 1 on error
+ */
+int setenv_ulong(const char *varname, ulong value)
+{
+	char *str = simple_itoa(value);
+
+	return setenv(varname, str);
+}
+
+/**
+ * Set an environment variable to an address in hex
+ *
+ * @param varname	Environmet variable to set
+ * @param addr		Value to set it to
+ * @return 0 if ok, 1 on error
+ */
+int setenv_addr(const char *varname, const void *addr)
+{
+	char str[17];
+
+	sprintf(str, "%x", (uintptr_t)addr);
+	return setenv(varname, str);
+}
+
 int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	if (argc < 2)
include/common.h +2 -0
index 55f772d..99c2a37 100644
@@ -294,6 +294,8 @@ int inline setenv    (const char *, const char *);
 #else
 int	setenv	     (const char *, const char *);
 #endif /* CONFIG_PPC */
+int setenv_ulong(const char *varname, ulong value);
+int setenv_addr(const char *varname, const void *addr);
 #ifdef CONFIG_ARM
 # include <asm/mach-types.h>
 # include <asm/setup.h>
Signature · 1 line
1.7.3.1
#3 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

common/cmd_nvedit.c int setenv(const char *varname, const char *varvalue) · line 392

Quoted 6 lines · Simon Glass
common/cmd_nvedit.c +6 -0
+int setenv_ulong(const char *varname, ulong value)
+{
+ ? ? ? char *str = simple_itoa(value);
+
+ ? ? ? return setenv(varname, str);
+}

could be a one liner, but works either way

common/cmd_nvedit.c int setenv(const char *varname, const char *varvalue)

Quoted 3 lines
common/cmd_nvedit.c +3 -0
+int setenv_addr(const char *varname, const void *addr)
+{
+ ? ? ? char str[17];

char str[sizeof(addr) * 2 + 1];

Quoted 1 line

+ ? ? ? sprintf(str, "%x", (uintptr_t)addr);

i wonder if we should use %p and drop the cast
-mike

#4 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Hi Mike

Quoted 9 lines · Mike Frysinger

common/cmd_nvedit.c int setenv(const char *varname, const char *varvalue) · line 392

Quoted 6 lines · Simon Glass
common/cmd_nvedit.c +6 -0
+int setenv_ulong(const char *varname, ulong value)
+{
+ ? ? ? char *str = simple_itoa(value);
+
+ ? ? ? return setenv(varname, str);
+}

could be a one liner, but works either way

OK, was trying to separate that out deliberately.

Quoted 6 lines

common/cmd_nvedit.c int setenv(const char *varname, const char *varvalue)

Quoted 4 lines
common/cmd_nvedit.c +3 -0
+int setenv_addr(const char *varname, const void *addr)
+{
+ ? ? ? char str[17];

char str[sizeof(addr) * 2 + 1];

Yes of course!

Quoted 6 lines
Quoted 2 lines

+ ? ? ? sprintf(str, "%x", (uintptr_t)addr);

i wonder if we should use %p and drop the cast
-mike

Is %p supposed to print a 0x before it or not? I saw some discussion about this. I vote for %p no, and %#p yes.

I will tidy these up for v3.

Regards,
Simon

#5 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Quoted 8 lines · Simon Glass
Quoted 4 lines · Mike Frysinger
Quoted 1 line · Simon Glass

+ ? ? ? sprintf(str, "%x", (uintptr_t)addr);

i wonder if we should use %p and drop the cast

Is %p supposed to print a 0x before it or not? I saw some discussion about this. I vote for %p no, and %#p yes.

%p does not currently output a leading 0x. it should (imo), and i'll prob send a patch to fix that.

but %x doesn't output a leading 0x either :).
-mike

#6 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Hi Mike,

Quoted 7 lines · Mike Frysinger
Quoted 6 lines · Simon Glass
Quoted 4 lines · Mike Frysinger
Quoted 1 line · Simon Glass

+ ? ? ? sprintf(str, "%x", (uintptr_t)addr);

i wonder if we should use %p and drop the cast

Quoted 9 lines
Quoted 2 lines

Is %p supposed to print a 0x before it or not? I saw some discussion about this. I vote for %p no, and %#p yes.

%p does not currently output a leading 0x. ?it should (imo), and i'll prob send a patch to fix that.

but %x doesn't output a leading 0x either :).
-mike

OK, well to be consistent with glibc we should probably add 0x as you say.

isn't it intended that env variables without a leading 0x in the value be interpreted as hex still? Iwc do I really want the 0x?

Regards,
Simon

#7 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Dear Simon Glass,

Quoted 3 lines · In message <CAPnjgZ1+nTaAjYxq5Nh3i7XTh+RhPC9edVtHF34YNPA2PJcCuw@mail.gmail.com>…

isn't it intended that env variables without a leading 0x in the value be interpreted as hex still? Iwc do I really want the 0x?

Yes, this is intended. No, we do NOT want to see the 0x in such cases.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The only time the world beats a path to your door is when you are  in
the bathroom.
#8 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Quoted 6 lines · Wolfgang Denk
Quoted 2 lines · Simon Glass

isn't it intended that env variables without a leading 0x in the value be interpreted as hex still? Iwc do I really want the 0x?

Yes, this is intended. ?No, we do NOT want to see the 0x in such cases.

ok, so we'll want to stick with %x like you already have Simon. i disagree, but not enough to fight over it ;).
-mike

#9 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Hi Mike,

Quoted 5 lines · Mike Frysinger
Quoted 4 lines · Wolfgang Denk
Quoted 2 lines · Simon Glass

isn't it intended that env variables without a leading 0x in the value be interpreted as hex still? Iwc do I really want the 0x?

Quoted 7 lines
Quoted 2 lines

Yes, this is intended. ?No, we do NOT want to see the 0x in such cases.

ok, so we'll want to stick with %x like you already have Simon. ?i disagree, but not enough to fight over it ;).
-mike

OK. But I can use %p if you don't send your patch. How about %#p to display 0x? It would be incompatible with glibc, but seems more sensible. Then we could use this in quite a few places in U-Boot I suspect.

Regards,
Simon

#10 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Quoted 9 lines · Simon Glass
Quoted 8 lines · Mike Frysinger
Quoted 6 lines · Wolfgang Denk
Quoted 2 lines · Simon Glass

isn't it intended that env variables without a leading 0x in the value be interpreted as hex still? Iwc do I really want the 0x?

Yes, this is intended. ?No, we do NOT want to see the 0x in such cases.

Quoted 7 lines
Quoted 2 lines

ok, so we'll want to stick with %x like you already have Simon. ?i disagree, but not enough to fight over it ;).

OK. But I can use %p if you don't send your patch. How about %#p to display 0x? It would be incompatible with glibc, but seems more sensible. Then we could use this in quite a few places in U-Boot I suspect.

i think wolfgang's point is that he doesn't want "0x" in env vars. i don't think he made any statement about %p in general.

also, %#p works the same under u-boot as under glibc. it's just that %#p generates a gcc warning.
-mike

#11 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Hi Mike,

Quoted 13 lines · Mike Frysinger
Quoted 12 lines · Simon Glass
Quoted 10 lines · Mike Frysinger
Quoted 6 lines · Wolfgang Denk
Quoted 2 lines · Simon Glass

isn't it intended that env variables without a leading 0x in the value be interpreted as hex still? Iwc do I really want the 0x?

Yes, this is intended. ?No, we do NOT want to see the 0x in such cases.

ok, so we'll want to stick with %x like you already have Simon. ?i disagree, but not enough to fight over it ;).

Quoted 7 lines
Quoted 4 lines

OK. But I can use %p if you don't send your patch. How about %#p to display 0x? It would be incompatible with glibc, but seems more sensible. Then we could use this in quite a few places in U-Boot I suspect.

i think wolfgang's point is that he doesn't want "0x" in env vars. ?i don't think he made any statement about %p in general.

Yes I got that.

Quoted 5 lines

also, %#p works the same under u-boot as under glibc. ?it's just that %#p generates a gcc warning.
-mike

No I meant that for me glibc displays 0x whether or not I put # in there...seems wrong to me.

Regards,
Simon

#12 lore raw

PATCH 2/8 Add setenv_uint() and setenv_addr()

Quoted 6 lines · Simon Glass
Quoted 2 lines · Mike Frysinger

also, %#p works the same under u-boot as under glibc. ?it's just that %#p generates a gcc warning.

No I meant that for me glibc displays 0x whether or not I put # in there...seems wrong to me.

i don't think so. it's long done this, as does gcc and the Linux kernel. fixing u-boot to operate the same way as the rest of the ecosystem makes sense to me.
-mike

#13 lore raw

PATCH 3/8 tftpput: Rename TFTP to TFTPGET

In reply to Simon Glass

This is a better name for this protocol. Also remove the typedef to keep checkpatch happy, and move zeroing of NetBootFileXferSize a little earlier since TFTPPUT will need to change this.

---
 common/cmd_net.c |    8 ++++----
 include/net.h    |    8 +++++---
 net/net.c        |   18 ++++++++----------
 3 files changed, 17 insertions(+), 17 deletions(-)
common/cmd_net.c +4 -4
index 872f4a6..f610385 100644
@@ -28,7 +28,7 @@
 #include <command.h>
 #include <net.h>
 
-static int netboot_common (proto_t, cmd_tbl_t *, int , char * const []);
+static int netboot_common(enum proto_t, cmd_tbl_t *, int, char * const []);
 
 int do_bootp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -43,7 +43,7 @@ U_BOOT_CMD(
 
 int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	return netboot_common (TFTP, cmdtp, argc, argv);
+	return netboot_common(TFTPGET, cmdtp, argc, argv);
 }
 
 U_BOOT_CMD(
@@ -167,8 +167,8 @@ static void netboot_update_env (void)
 #endif
 }
 
-static int
-netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[])
+static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
+		char * const argv[])
 {
 	char *s;
 	char *end;
include/net.h +5 -3
index d5d37b6..3dfe073 100644
@@ -347,8 +347,10 @@ extern int		NetState;		/* Network loop state		*/
 
 extern int		NetRestartWrap;		/* Tried all network devices	*/
 
-typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-	       TFTPSRV } proto_t;
+enum {
+	BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
+	TFTPSRV
+};
 
 /* from net/net.c */
 extern char	BootFile[128];			/* Boot File name		*/
@@ -374,7 +376,7 @@ extern int NetTimeOffset;			/* offset time from UTC		*/
 #endif
 
 /* Initialize the network adapter */
-extern int	NetLoop(proto_t);
+extern int NetLoop(enum proto_t);
 
 /* Shutdown adapters and cleanup */
 extern void	NetStop(void);
net/net.c +8 -10
index 5e67886..ce07ed6 100644
@@ -224,7 +224,7 @@ static ulong	timeDelta;
 /* THE transmit packet */
 volatile uchar *NetTxPacket;
 
-static int net_check_prereq(proto_t protocol);
+static int net_check_prereq(enum proto_t protocol);
 
 static int NetTryCount;
 
@@ -310,8 +310,7 @@ void ArpTimeoutCheck(void)
 	}
 }
 
-static void
-NetInitLoop(proto_t protocol)
+static void NetInitLoop(enum proto_t protocol)
 {
 	static int env_changed_id;
 	bd_t *bd = gd->bd;
@@ -340,8 +339,7 @@ NetInitLoop(proto_t protocol)
  *	Main network processing loop.
  */
 
-int
-NetLoop(proto_t protocol)
+int NetLoop(enum proto_t protocol)
 {
 	bd_t *bd = gd->bd;
 
@@ -405,10 +403,11 @@ restart:
 
 	case 0:
 		NetDevExists = 1;
+		NetBootFileXferSize = 0;
 		switch (protocol) {
-		case TFTP:
+		case TFTPGET:
 			/* always use ARP to get server ethernet address */
-			TftpStart();
+			TftpStart(protocol);
 			break;
 #ifdef CONFIG_CMD_TFTPSRV
 		case TFTPSRV:
@@ -470,7 +469,6 @@ restart:
 			break;
 		}
 
-		NetBootFileXferSize = 0;
 		break;
 	}
 
@@ -1728,7 +1726,7 @@ NetReceive(volatile uchar *inpkt, int len)
 
 /**********************************************************************/
 
-static int net_check_prereq(proto_t protocol)
+static int net_check_prereq(enum proto_t protocol)
 {
 	switch (protocol) {
 		/* Fall through */
@@ -1759,7 +1757,7 @@ static int net_check_prereq(proto_t protocol)
 #if defined(CONFIG_CMD_NFS)
 	case NFS:
 #endif
-	case TFTP:
+	case TFTPGET:
 		if (NetServerIP == 0) {
 			puts("*** ERROR: `serverip' not set\n");
 			return 1;
Signature · 1 line
1.7.3.1
#14 lore raw

PATCH 4/8 tftpput: move common code into separate functions

In reply to Simon Glass

We want to show block markers on completion of get and put, so move this common code into separate functions.

---
 net/tftp.c |   70 ++++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 40 insertions(+), 30 deletions(-)
net/tftp.c +40 -30
index da8eeaa..4ad85a5 100644
@@ -195,6 +195,42 @@ static void TftpTimeout(void);
 
 /**********************************************************************/
 
+static void show_block_marker(void)
+{
+	ulong pos = TftpBlock * TftpBlkSize + TftpBlockWrapOffset;
+
+#ifdef CONFIG_TFTP_TSIZE
+	if (TftpTsize) {
+		while (TftpNumchars <
+			/* TODO: needs to be different for put */
+			pos * 50 / TftpTsize) {
+			putc('#');
+			TftpNumchars++;
+		}
+	}
+#endif
+	else {
+		if (((TftpBlock - 1) % 10) == 0)
+			putc('#');
+		else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0)
+			puts("\n\t ");
+	}
+}
+
+/* The TFTP get or put is complete */
+static void tftp_complete(void)
+{
+#ifdef CONFIG_TFTP_TSIZE
+	/* Print hash marks for the last packet received */
+	while (TftpTsize && TftpNumchars < 49) {
+		putc('#');
+		TftpNumchars++;
+	}
+#endif
+	puts("\ndone\n");
+	NetState = NETLOOP_SUCCESS;
+}
+
 static void
 TftpSend(void)
 {
@@ -400,21 +436,8 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
 				TftpBlkSize * TFTP_SEQUENCE_SIZE;
 			printf("\n\t %lu MB received\n\t ",
 				TftpBlockWrapOffset>>20);
-		}
-#ifdef CONFIG_TFTP_TSIZE
-		else if (TftpTsize) {
-			while (TftpNumchars <
-			       NetBootFileXferSize * 50 / TftpTsize) {
-				putc('#');
-				TftpNumchars++;
-			}
-		}
-#endif
-		else {
-			if (((TftpBlock - 1) % 10) == 0)
-				putc('#');
-			else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0)
-				puts("\n\t ");
+		} else {
+			show_block_marker();
 		}
 
 		if (TftpState == STATE_SEND_RRQ)
@@ -498,21 +521,8 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
 		}
 		else
 #endif
-		if (len < TftpBlkSize) {
-			/*
-			 *	We received the whole thing.  Try to
-			 *	run it.
-			 */
-#ifdef CONFIG_TFTP_TSIZE
-			/* Print hash marks for the last packet received */
-			while (TftpTsize && TftpNumchars < 49) {
-				putc('#');
-				TftpNumchars++;
-			}
-#endif
-			puts("\ndone\n");
-			NetState = NETLOOP_SUCCESS;
-		}
+		if (len < TftpBlkSize)
+			tftp_complete();
 		break;
 
 	case TFTP_ERROR:
Signature · 1 line
1.7.3.1
#15 lore raw

PATCH 5/8 tftpput: support selecting get/put for tftp

In reply to Simon Glass

TftpStart should support starting either a get or a put.

---
 include/net.h |    4 ++--
 net/bootp.c   |    2 +-
 net/tftp.c    |    5 +++--
 net/tftp.h    |    2 +-
 4 files changed, 7 insertions(+), 6 deletions(-)
include/net.h +2 -2
index 3dfe073..2e5a898 100644
@@ -349,8 +349,8 @@ extern int		NetRestartWrap;		/* Tried all network devices	*/
 
 enum {
 	BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-	TFTPSRV
-};
+	TFTPSRV, TFTPPUT
+} proto_t;
 
 /* from net/net.c */
 extern char	BootFile[128];			/* Boot File name		*/
net/bootp.c +1 -1
index a003c42..068b037 100644
@@ -165,7 +165,7 @@ static void auto_load(void)
 		}
 #endif
 	}
-	TftpStart();
+	TftpStart(TFTPGET);
 }
 
 #if !defined(CONFIG_CMD_DHCP)
net/tftp.c +3 -2
index 4ad85a5..3a58e32 100644
@@ -81,6 +81,7 @@ static int	TftpTsize;
 /* The number of hashes we printed */
 static short	TftpNumchars;
 #endif
+static int	TftpWriting;	/* 1 if writing, else 0 */
 
 #define STATE_SEND_RRQ	1
 #define STATE_DATA	2
@@ -572,8 +573,7 @@ TftpTimeout(void)
 }
 
 
-void
-TftpStart(void)
+void TftpStart(proto_t protocol)
 {
 	char *ep;             /* Environment pointer */
 
@@ -648,6 +648,7 @@ TftpStart(void)
 	}
 
 	putc('\n');
+	TftpWriting = (protocol == TFTPPUT);
 
 	printf("Load address: 0x%lx\n", load_addr);
 
net/tftp.h +1 -1
index 3abdf7b..2d5d594 100644
@@ -16,7 +16,7 @@
  */
 
 /* tftp.c */
-extern void	TftpStart (void);	/* Begin TFTP get */
+void TftpStart(proto_t protocol);	/* Begin TFTP get/put */
 
 #ifdef CONFIG_CMD_TFTPSRV
 extern void	TftpStartServer(void);	/* Wait for incoming TFTP put */
Signature · 1 line
1.7.3.1
#16 lore raw

PATCH 6/8 tftpput: add save_addr and save_size global variables

In reply to Simon Glass

We need something akin to load_addr to handle saving data.

---
 common/cmd_nvedit.c |    2 ++
 include/common.h    |    2 ++
 2 files changed, 4 insertions(+), 0 deletions(-)
common/cmd_nvedit.c +2 -0
index da7028c..30cf8df 100644
@@ -79,6 +79,8 @@ SPI_FLASH|MG_DISK|NVRAM|MMC} or CONFIG_ENV_IS_NOWHERE
 #define	MAX_ENV_SIZE	(1 << 20)	/* 1 MiB */
 
 ulong load_addr = CONFIG_SYS_LOAD_ADDR;	/* Default Load Address */
+ulong save_addr;			/* Default Save Address */
+ulong save_size;			/* Default Save Size (in bytes) */
 
 /*
  * Table with supported baudrates (defined in config_xyz.h)
include/common.h +2 -0
index 99c2a37..d7382d9 100644
@@ -278,6 +278,8 @@ void flash_perror (int);
 int	source (ulong addr, const char *fit_uname);
 
 extern ulong load_addr;		/* Default Load Address */
+extern ulong save_addr;		/* Default Save Address */
+extern ulong save_size;		/* Default Save Size */
 
 /* common/cmd_doc.c */
 void	doc_probe(unsigned long physadr);
Signature · 1 line
1.7.3.1
#17 lore raw

PATCH 7/8 tftpput: implement tftp logic

In reply to Simon Glass

This adds logic to tftp.c to implement the tftp 'put' command, and updates the README.

---
 README     |    2 +
 net/net.c  |    4 ++
 net/tftp.c |  114 +++++++++++++++++++++++++++++++++++++++++++++++++----------
 3 files changed, 100 insertions(+), 20 deletions(-)
README +2 -0
index 7e032a9..8261bfb 100644
@@ -784,6 +784,7 @@ The following options need to be configured:
 		CONFIG_CMD_SOURCE	  "source" command Support
 		CONFIG_CMD_SPI		* SPI serial bus support
 		CONFIG_CMD_TFTPSRV	* TFTP transfer in server mode
+		CONFIG_CMD_TFTPPUT	* TFTP put command (upload)
 		CONFIG_CMD_TIME		* run command and report execution time
 		CONFIG_CMD_USB		* USB support
 		CONFIG_CMD_CDP		* Cisco Discover Protocol support
@@ -3340,6 +3341,7 @@ bootp	- boot image via network using BootP/TFTP protocol
 tftpboot- boot image via network using TFTP protocol
 	       and env variables "ipaddr" and "serverip"
 	       (and eventually "gatewayip")
+tftpput - upload a file via network using TFTP protocol
 rarpboot- boot image via network using RARP/TFTP protocol
 diskboot- boot from IDE devicebootd   - boot default, i.e., run 'bootcmd'
 loads	- load S-Record file over serial line
net/net.c +4 -0
index ce07ed6..89596d3 100644
@@ -406,6 +406,9 @@ restart:
 		NetBootFileXferSize = 0;
 		switch (protocol) {
 		case TFTPGET:
+#ifdef CONFIG_CMD_TFTPPUT
+		case TFTPPUT:
+#endif
 			/* always use ARP to get server ethernet address */
 			TftpStart(protocol);
 			break;
@@ -1758,6 +1761,7 @@ static int net_check_prereq(enum proto_t protocol)
 	case NFS:
 #endif
 	case TFTPGET:
+	case TFTPPUT:
 		if (NetServerIP == 0) {
 			puts("*** ERROR: `serverip' not set\n");
 			return 1;
net/tftp.c +94 -20

214 lines not on this page · raw message

Signature · 1 line
1.7.3.1
#18 lore raw

PATCH 8/8 tftpput: add tftpput command

In reply to Simon Glass

This adds a command to start a tftp put transfer.

---
 common/cmd_net.c         |   23 +++++++++++++++++++++++
 include/config_cmd_all.h |    1 +
 2 files changed, 24 insertions(+), 0 deletions(-)
common/cmd_net.c +23 -0
index f610385..f89a24b 100644
@@ -52,6 +52,22 @@ U_BOOT_CMD(
 	"[loadAddress] [[hostIPaddr:]bootfilename]"
 );
 
+#ifdef CONFIG_CMD_TFTPPUT
+int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret;
+
+	ret = netboot_common(TFTPPUT, cmdtp, argc, argv);
+	return ret;
+}
+
+U_BOOT_CMD(
+	tftpput,	4,	1,	do_tftpput,
+	"TFTP put command, for uploading files to a server",
+	"Address Size [[hostIPaddr:]filename]"
+);
+#endif
+
 #ifdef CONFIG_CMD_TFTPSRV
 static int do_tftpsrv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
@@ -203,6 +219,13 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
 
 		break;
 
+#ifdef CONFIG_CMD_TFTPPUT
+	case 4:
+		save_addr = strict_strtoul(argv[1], NULL, 16);
+		save_size = strict_strtoul(argv[2], NULL, 16);
+		copy_filename(BootFile, argv[3], sizeof(BootFile));
+		break;
+#endif
 	default:
 		show_boot_progress (-80);
 		return cmd_usage(cmdtp);
include/config_cmd_all.h +1 -0
index 9716f9c..7fa8661 100644
@@ -82,6 +82,7 @@
 #define CONFIG_CMD_SOURCE	/* "source" command support	*/
 #define CONFIG_CMD_SPI		/* SPI utility			*/
 #define CONFIG_CMD_TERMINAL	/* built-in Serial Terminal	*/
+#define CONFIG_CMD_TFTPPUT	/* TFTP upload			*/
 #define CONFIG_CMD_UBI		/* UBI Support			*/
 #define CONFIG_CMD_UBIFS	/* UBIFS Support		*/
 #define CONFIG_CMD_UNIVERSE	/* Tundra Universe Support	*/
Signature · 1 line
1.7.3.1
#19 lore raw

cover Add tftpput command for uploading files over network

In reply to Simon Glass

Le 22/10/2011 06:51, Simon Glass a ?crit :

Quoted 10 lines

The tftpboot command permits reading of files over a network interface using the Trivial FTP protocol. This patch series adds the ability to transfer files the other way.

Why is this useful?

- Uploading boot time data to a server
- Uploading profiling information
- Uploading large mounts of data for comparison / checking on a host (e.g. use tftpput and ghex2 instead of the 'md' command)

Especially I find it interesting for backing up things like MTD and small disk files (not partitions, though). Most of my work currently is trying to bring mainline U-Boot support to existing boards with bad U-Boot implementations, and being able to backup things from U-Boot (as opposed to having to set up NFS root and Linux boot) would definitely be a plus.

Quoted 2 lines

Mostly the existing code can be re-used and I have tried to avoid too much refactoring or cleaning up.

:)

Quoted 4 lines

The feature is activated by the CONFIG_CMD_TFTPPUT option.

This has been very lightly tested on a Seaboard with a USB network adaptor. I don't think it handles block number overflow.

What size does this limit transfers to?

Quoted 9 lines

Simon Glass (8):
Move simple_itoa to vsprintf
Add setenv_uint() and setenv_addr()
tftpput: Rename TFTP to TFTPGET
tftpput: move common code into separate functions
tftpput: support selecting get/put for tftp
tftpput: add save_addr and save_size global variables
tftpput: implement tftp logic
tftpput: add tftpput command

Many U-Boot environments use 'tftp' as a shorthand to tftpboot. Did you verify that this is not broken by the introduction of 'tftpput'?

Also, I'd be happy to test this if a branch exists that already holds these commits.

Amicalement,

Signature · 1 line
Albert.
#20 lore raw

cover Add tftpput command for uploading files over network

Hi Albert,

Quoted 22 lines · Albert ARIBAUD

Le 22/10/2011 06:51, Simon Glass a ?crit :

Quoted 11 lines

The tftpboot command permits reading of files over a network interface using the Trivial FTP protocol. This patch series adds the ability to transfer files the other way.

Why is this useful?

- Uploading boot time data to a server
- Uploading profiling information
- Uploading large mounts of data for comparison / checking on a host ? ? (e.g. use tftpput and ghex2 instead of the 'md' command)

Especially I find it interesting for backing up things like MTD and small disk files (not partitions, though). Most of my work currently is trying to bring mainline U-Boot support to existing boards with bad U-Boot implementations, and being able to backup things from U-Boot (as opposed to having to set up NFS root and Linux boot) would definitely be a plus.

Quoted 2 lines

Mostly the existing code can be re-used and I have tried to avoid too much refactoring or cleaning up.

Quoted 8 lines

:)

Quoted 4 lines

The feature is activated by the CONFIG_CMD_TFTPPUT option.

This has been very lightly tested on a Seaboard with a USB network adaptor. I don't think it handles block number overflow.

What size does this limit transfers to?

I think about 1468 * 65535 - around 95MB - it's fairly easy to fix just by copying out the existing tftp get wrap code. I put it in the commit message so it wouldn't get lost.

Quoted 11 lines
Quoted 10 lines

Simon Glass (8):
? Move simple_itoa to vsprintf
? Add setenv_uint() and setenv_addr()
? tftpput: Rename TFTP to TFTPGET
? tftpput: move common code into separate functions ? tftpput: support selecting get/put for tftp ? tftpput: add save_addr and save_size global variables ? tftpput: implement tftp logic
? tftpput: add tftpput command

Quoted 5 lines

Many U-Boot environments use 'tftp' as a shorthand to tftpboot. Did you verify that this is not broken by the introduction of 'tftpput'?

Also, I'd be happy to test this if a branch exists that already holds these commits.

I will see if I can organise one at Denx.

Regards,
Simon

Quoted 5 lines

Amicalement,
--
Albert.

#21 lore raw

cover Add tftpput command for uploading files over network

Hi Albert,

Quoted 50 lines · Simon Glass

Hi Albert,

Quoted 22 lines · Albert ARIBAUD

Le 22/10/2011 06:51, Simon Glass a ?crit :

Quoted 11 lines

The tftpboot command permits reading of files over a network interface using the Trivial FTP protocol. This patch series adds the ability to transfer files the other way.

Why is this useful?

- Uploading boot time data to a server
- Uploading profiling information
- Uploading large mounts of data for comparison / checking on a host ? ? (e.g. use tftpput and ghex2 instead of the 'md' command)

Especially I find it interesting for backing up things like MTD and small disk files (not partitions, though). Most of my work currently is trying to bring mainline U-Boot support to existing boards with bad U-Boot implementations, and being able to backup things from U-Boot (as opposed to having to set up NFS root and Linux boot) would definitely be a plus.

Quoted 2 lines

Mostly the existing code can be re-used and I have tried to avoid too much refactoring or cleaning up.

Quoted 8 lines

:)

Quoted 4 lines

The feature is activated by the CONFIG_CMD_TFTPPUT option.

This has been very lightly tested on a Seaboard with a USB network adaptor. I don't think it handles block number overflow.

What size does this limit transfers to?

I think about 1468 * 65535 - around 95MB - it's fairly easy to fix just by copying out the existing tftp get wrap code. I put it in the commit message so it wouldn't get lost.

Quoted 11 lines
Quoted 10 lines

Simon Glass (8):
? Move simple_itoa to vsprintf
? Add setenv_uint() and setenv_addr()
? tftpput: Rename TFTP to TFTPGET
? tftpput: move common code into separate functions ? tftpput: support selecting get/put for tftp ? tftpput: add save_addr and save_size global variables ? tftpput: implement tftp logic
? tftpput: add tftpput command

Quoted 7 lines
Quoted 5 lines

Many U-Boot environments use 'tftp' as a shorthand to tftpboot. Did you verify that this is not broken by the introduction of 'tftpput'?

Also, I'd be happy to test this if a branch exists that already holds these commits.

I will see if I can organise one at Denx.

Thanks to Wolfgang I have something you can try:

git clone git://git.denx.de/u-boot-simonglass
git checkout us-tftp

Regards,
Simon

Quoted 10 lines

Regards,
Simon

Quoted 5 lines

Amicalement,
--
Albert.

#22 lore raw

cover Add tftpput command for uploading files over network

Hi Albert,

Quoted 41 lines · Simon Glass

Hi Albert,

Quoted 38 lines · Simon Glass

Hi Albert,

Quoted 22 lines · Albert ARIBAUD

Le 22/10/2011 06:51, Simon Glass a ?crit :

Quoted 11 lines

The tftpboot command permits reading of files over a network interface using the Trivial FTP protocol. This patch series adds the ability to transfer files the other way.

Why is this useful?

- Uploading boot time data to a server
- Uploading profiling information
- Uploading large mounts of data for comparison / checking on a host ? ? (e.g. use tftpput and ghex2 instead of the 'md' command)

Especially I find it interesting for backing up things like MTD and small disk files (not partitions, though). Most of my work currently is trying to bring mainline U-Boot support to existing boards with bad U-Boot implementations, and being able to backup things from U-Boot (as opposed to having to set up NFS root and Linux boot) would definitely be a plus.

Quoted 2 lines

Mostly the existing code can be re-used and I have tried to avoid too much refactoring or cleaning up.

Quoted 8 lines

:)

Quoted 4 lines

The feature is activated by the CONFIG_CMD_TFTPPUT option.

This has been very lightly tested on a Seaboard with a USB network adaptor. I don't think it handles block number overflow.

What size does this limit transfers to?

I think about 1468 * 65535 - around 95MB - it's fairly easy to fix just by copying out the existing tftp get wrap code. I put it in the commit message so it wouldn't get lost.

I have fixed this in v2 and tested that it can wrap around many times without trouble. There is a small issue that some servers wrap around to 0 and others to 1. For tftpd-hpa at least it is 0, although the write part seems broken anyway.

Unfortunately this involves a little more refactoring, since I didn't want to duplicate code, and some of the functions are awfully long.

Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines

Simon Glass (8):
? Move simple_itoa to vsprintf
? Add setenv_uint() and setenv_addr()
? tftpput: Rename TFTP to TFTPGET
? tftpput: move common code into separate functions ? tftpput: support selecting get/put for tftp ? tftpput: add save_addr and save_size global variables ? tftpput: implement tftp logic
? tftpput: add tftpput command

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Many U-Boot environments use 'tftp' as a shorthand to tftpboot. Did you verify that this is not broken by the introduction of 'tftpput'?

I forgot to answer this. No this will break 'tftp' as 'tftpserver' does. I vaguely remember a discussion that this was correct, since tftp is only an abbreviation and should not be used in scripts.

Quoted 10 lines
Quoted 5 lines
Quoted 3 lines

Also, I'd be happy to test this if a branch exists that already holds these commits.

I will see if I can organise one at Denx.

Thanks to Wolfgang I have something you can try:

git clone git://git.denx.de/u-boot-simonglass
git checkout us-tftp

Try git checkout us-tftp2 for the new version.

Regards,
SImon

Quoted 6 lines
Quoted 5 lines
Quoted 4 lines

Amicalement,
--
Albert.

#23 lore raw

cover Add tftpput command for uploading files over network

Hi Simon,

Le 25/10/2011 06:13, Simon Glass a ?crit :

Quoted 6 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

Many U-Boot environments use 'tftp' as a shorthand to tftpboot. Did you verify that this is not broken by the introduction of 'tftpput'?

I forgot to answer this. No this will break 'tftp' as 'tftpserver' does. I vaguely remember a discussion that this was correct, since tftp is only an abbreviation and should not be used in scripts.

Point taken. I'll have to fix some web pages floating around. :)

Quoted 11 lines
Quoted 9 lines
Quoted 4 lines
Quoted 2 lines

Also, I'd be happy to test this if a branch exists that already holds these commits.

I will see if I can organise one at Denx.

Thanks to Wolfgang I have something you can try:

git clone git://git.denx.de/u-boot-simonglass
git checkout us-tftp

Try git checkout us-tftp2 for the new version.

Thanks! Will test it this evening.

Quoted 2 lines

Regards,
SImon

Amicalement,

Signature · 1 line
Albert.
#24 lore raw

cover Add tftpput command for uploading files over network

In reply to Albert ARIBAUD
Quoted 2 lines · On Saturday 22 October 2011 04:21:18 Albert ARIBAUD wrote:

Many U-Boot environments use 'tftp' as a shorthand to tftpboot. Did you verify that this is not broken by the introduction of 'tftpput'?

those boards are broken. we can't sanely maintain support for people relying on autocompleted commands.

ignoring that, no one includes config_cmd_all.h, and no one enables this command. if people do, and they don't test things, then that's even more their problem.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20111030/52922e6f/attachment.pgp