Varyag
Varyag

Reputation: 696

U-boot: how to check if tftp command successfully loaded image into ram?

I load a rootfs image into RAM via u-boot tftp and flash it to the device flash storage. This is currently done manually, but now I want to do it automatically via a u-boot script:

tftp ${rootfs_image};
mmc write ${loadaddr} ${blk} ${cnt}

However, when it looks for an image from the tftp server with the u-boot tftp ${rootfs_image} command and it DOESN'T find the image, I don't want to run the mmc write part of the script.

How do I check if the tftp command successfully downloaded the image into RAM?

Upvotes: 0

Views: 2869

Answers (2)

Frant
Frant

Reputation: 5925

Using the TFTP protocol does not ensure that the integrity of the transferred data will be preserved - see section Security Consideration in this article.

Assuming your u-boot has the hash command available, or that you can re-compile it with CONFIG_CMD_HASH=y, you could use an SHA-256 hash for verifying that your image was properly transferred:

On a Linux TFTP server:

# create an image for the purpose of the example
echo "Binary Image" > image.bin

# display sha256 hash for image.bin
sha256sum -b image.bin
36949f85f1bff0d5d1dd5fcfdfd725e919b0ee64be24f7f3ccfb53908fd09550 *image.bin

# create a file containing the hash in binary
# credits:
sha256sum -b image.bin | xxd -r -p > image.bin.sha256sum.bin

# display content of binary file
hexdump -C image.bin.sha256sum.bin
00000000  36 94 9f 85 f1 bf f0 d5  d1 dd 5f cf df d7 25 e9  |6........._...%.|
00000010  19 b0 ee 64 be 24 f7 f3  cc fb 53 90 8f d0 95 50  |...d.$....S....P|
00000020

On your u-boot system (using the memory layout available on my Alwinner H5 system here):

# 0x40080000: address where image.bin will be transfered
# 0x40090000: address where image.bin.sha256sum.bin will be transfrered
# 0x40090000: address where the sha256 has will be computed by u-boot on the 13 bytes of image.bin

# clearing memory
mw.b 0x40080000 0 0x2000
mw.b 0x40090000 0 0x20
mw.b 0x400A0000 0 0x20

md.b 0x40080000 0x20
40080000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
40080010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

md.b 0x40090000 0x20
40090000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
40090010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

md.b 0x400A0000 0x20
400a0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
400a0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

tftp 0x40080000 image.bin
Using ethernet@1c30000 device
TFTP from server 192.168.1.22; our IP address is 192.168.1.2
Filename 'image.bin'.
Load address: 0x40080000
Loading: #
     5.9 KiB/s
done
Bytes transferred = 13 (d hex)

tftp 0x40090000 image.bin.sha256sum.bin
Using ethernet@1c30000 device
TFTP from server 192.168.1.22; our IP address is 192.168.1.2
Filename 'image.bin.sha256sum.bin'.
Load address: 0x40090000
Loading: #
     15.6 KiB/s
done
Bytes transferred = 32 (20 hex)

 md.b 0x40090000 0x20
40090000: 36 94 9f 85 f1 bf f0 d5 d1 dd 5f cf df d7 25 e9    6........._...%.
40090010: 19 b0 ee 64 be 24 f7 f3 cc fb 53 90 8f d0 95 50    ...d.$....S....P

hash sha256  0x40080000 0x0d *0x400A0000
sha256 for 40080000 ... 4008000c ==> 36949f85f1bff0d5d1dd5fcfdfd725e919b0ee64be24f7f3ccfb53908fd09550

cmp.b 0x40090000 0x400A0000 0x20
Total of 32 byte(s) were the same

echo $?
0

In the case image.bin and/or image.bin.sha256sum.bin would have been improperly transferred, the chances that the computed sha256 would match the transferred one are extremely unlikely - using SHA-512 would make this even more unlikely. The outcome would have been in the case of an incorrect transfer:

echo $?
1

In real life, this would be more practical to transfer an image with a fixed, maximum length, for example padded with zeroes, so that a u-boot script responsible for validating the transferred image would use a fixed length, say 8 KiB, that is 0x2000 bytes.

ls -lgG image.bin
-rw-rw-r-- 1 13 Dec 17 20:34 image.bin

dd if=/dev/zero  of=image.bin  bs=8K count=1  oflag=append
ls -lgG image.bin
-rw-rw-r-- 1 8192 Dec 17 21:03 image.bin
hexdump -C image.bin
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00002000

The correct u-boot command to use for computing the hash would be:
hash sha256  0x40080000 0x2000 *0x400A0000

And a new binary file containing the new hash would of course have to be created as well:

sha256sum -b image.bin | xxd -r -p > image.bin.sha256sum.bin

I used two files for the purpose of the example, but you could just append image.bin.sha256sum.bin to image.bin and transfer one single file.

You would have to replace 0x400A0000 by 0x40082000 in the hash and cmp commands.

I hope this helps.

Upvotes: 1

Xypron
Xypron

Reputation: 2483

The tftp command returns true if it succeeds. So you could write:

tftp ${rootfs_image} && mmc write ${loadaddr} ${blk} ${cnt}

Now mmc write will only be executed if the tftp command succeeds.

Upvotes: 1

Related Questions