The TFTP Protocol

Leave a comment

The TFTP protocol is pretty simple (hence, the “trivial” of TFTP). It’s spelled out in RFC1350 (which is relatively short), but if you just want the quick explanation for a client initiated file read request, it’s as follows:

The server listens on UDP port 69 for incoming requests. When the client wants to read a file, it sends a RRQ (0x0001) followed by a null terminated file name (in ASCII) followed by a null terminated list of “mode” options.The mode options would include either “octect” or “netascii”. I have also seen “blksizeXXXX” to specify the suggested size of the block to send back to the client, and “timeoutX” to indicate the timeout period of the client.

The server hands off to another local UDP port and responds with a DATA packet. This packet is composed of a 16 bit DATA command (value 0x0003) followed by a 16 bit block number followed by the data. The first block should start with a block number of 1.

The client sends an ACK back to the server to indicate receipt of the DATA packet. The ACK packet is composed of a 16 bit ACK command (value 0x0004) followed by the 16 bit block number that it just received.

If the server’s data packet is lost or dropped due to corruption, the server will timeout due to the lack of an ACK from the client and retransmit its last data packet. Receipt of a data packet by the client of size less than the block size will indicate to the client that the transfer is complete.

BeagleBoard-xM U-Boot TFTP

3 Comments

Once you start having to reflash your kernel onto the SD card a few times, it gets a bit tiring going through the cycle of manually popping the uSD card out, inserting it into a USB or SD adapter and plugging it into your host (probably Linux) system and then copying over the kernel image, syncing, and umounting. There is a better way – TFTP. With TFTP, you should update your Linux build process to copy the kernel image to your TFTP dir as the last step of the build and then simply reboot your target and it will fetch the new kernel from your server.

My stock 05.02 precompiled u-boot image didn’t seem to support TFTP. After “usb start”, I couldn’t get out to the net. Googling revealed that others were having the same problem and suggested that the USB Ethernet driver was not built into that stock u-boot image and suggested another u-boot source tree at git://github.com/koenkooi/u-boot.git u-boot.not.mainline. So I pulled that and rebuilt (haven’t diff’ed it with stock u-boot source yet) and put that onto the boot partition and TFTP now seems to work.

Remember that to do your cross building, you need to set the environment variables CROSS_COMPILE and PATH to point to your cross tool chain.

In my case:

export CROSS_COMPILE="arm-arago-linux-gnueabi-"
export PATH="/home/dneiss/beagleboard/linux-devkit/bin:$PATH"

And then to build a fresh u-boot image,

make distclean
make omap3_beagle_config
make

The top level u-boot.bin file is the one you want. Once you copy that to your boot partition and reboot the target and stop the boot up sequence,

setenv serverip 192.168.1.78 (or your server IP)
setenv ipaddr 192.168.1.10 (or your static Beagle IP)
usb start

You should see some output such as:

(Re)start USB...
USB:   Register 1313 NbrPorts 3
USB EHCI 1.0
scanning bus for devices... 3 USB Device(s) found
.
.

Once you get back to the prompt, you can try to “ping” to make sure you can ping that server. Assuming you can, then go for tftp with a “tftp yourFile” and see if you can download the file from the server. Make sure that your server is up and running and that you have populated the tftp dir with the file. To test if your FTFP server is up, try running tftp from your Linux host itself (“tftp localhost, get yourFile”). If you are not sure whether the request is making it to your server, you can run “sudo netcat -u -l 69”. When the target tries to do the TFTP request, netcat should dump out the TFTP read request. You should see something like “uImageoctettimeout5blksize1468”. This can be broken down into “uImage” (file name to xfer), “octet” (send data as binary and not ASCII), “timeout5” (5 second retry period), and “blksize1468” (return data blocks of this # of octets).