Stephen Warren | ef28913 | 2015-10-03 13:56:47 -0600 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | |
| 3 | # (C) Copyright 2015 Stephen Warren |
| 4 | # |
| 5 | # SPDX-License-Identifier: GPL-2.0+ |
| 6 | |
| 7 | # This script tests U-Boot's FAT filesystem code's ability to read non- |
| 8 | # contiguous files. |
| 9 | |
| 10 | # When porting the ff.c FAT parsing code into U-Boot, it was found that ff.c |
| 11 | # always reads files cluster-by-cluster, which results in poor performance. |
| 12 | # This was solved by adding a patch to ff.c to coalesce reads of adjacent |
| 13 | # clusters. Since this patch needed to correctly handle non-contiguous files, |
| 14 | # this test was written to validate that. |
| 15 | # |
| 16 | # To execute the test, simply run it from the U-Boot source root directory: |
| 17 | # |
| 18 | # cd u-boot |
| 19 | # ./test/fs/fat-noncontig-test.sh |
| 20 | # |
| 21 | # The test will create a FAT filesystem image, record the CRC of a randomly |
| 22 | # generated file in the image, build U-Boot sandbox, invoke U-Boot sandbox to |
| 23 | # read the file and validate that the CRCs match. Expected output is shown |
| 24 | # below. The important part of the log is the penultimate line that contains |
| 25 | # either "PASS" or "FAILURE". |
| 26 | # |
| 27 | # mkfs.fat 3.0.26 (2014-03-07) |
| 28 | # |
| 29 | # |
| 30 | # U-Boot 2015.10-rc4-00018-g4b22a3e5513f (Oct 03 2015 - 13:49:23 -0600) |
| 31 | # |
| 32 | # DRAM: 128 MiB |
| 33 | # Using default environment |
| 34 | # |
| 35 | # In: serial |
| 36 | # Out: lcd |
| 37 | # Err: lcd |
| 38 | # Net: No ethernet found. |
| 39 | # => host bind 0 sandbox/fat-noncontig.img |
| 40 | # => load host 0:0 1000 noncontig.img |
| 41 | # 33584964 bytes read in 18 ms (1.7 GiB/s) |
| 42 | # => crc32 1000 $filesize 0 |
| 43 | # crc32 for 00001000 ... 02008743 ==> 6a080523 |
| 44 | # => if itest.l *0 != 2305086a; then echo FAILURE; else echo PASS; fi |
| 45 | # PASS |
| 46 | # => reset |
| 47 | # |
| 48 | # All temporary files used by this script are created in ./sandbox to avoid |
| 49 | # polluting the source tree. test/fs/fs-test.sh also uses this directory for |
| 50 | # the same purpose. |
| 51 | # |
| 52 | # TODO: Integrate this (and many other corner-cases e.g. different types of |
| 53 | # FAT) with fs-test.sh so that a single script tests everything filesystem- |
| 54 | # related. |
| 55 | |
| 56 | odir=sandbox |
| 57 | img=${odir}/fat-noncontig.img |
| 58 | mnt=${odir}/mnt |
| 59 | fill=/dev/urandom |
| 60 | testfn=noncontig.img |
| 61 | mnttestfn=${mnt}/${testfn} |
| 62 | crcaddr=0 |
| 63 | loadaddr=1000 |
| 64 | |
| 65 | for prereq in fallocate mkfs.fat dd crc32; do |
| 66 | if [ ! -x "`which $prereq`" ]; then |
| 67 | echo "Missing $prereq binary. Exiting!" |
| 68 | exit 1 |
| 69 | fi |
| 70 | done |
| 71 | |
| 72 | make O=${odir} -s sandbox_defconfig && make O=${odir} -s -j8 |
| 73 | |
| 74 | mkdir -p ${mnt} |
| 75 | if [ ! -f ${img} ]; then |
| 76 | fallocate -l 40M ${img} |
Stephen Warren | 781910d | 2015-11-17 10:29:07 -0700 | [diff] [blame^] | 77 | if [ $? -ne 0 ]; then |
| 78 | echo fallocate failed - using dd instead |
| 79 | dd if=/dev/zero of=${img} bs=1024 count=$((40 * 1024)) |
| 80 | if [ $? -ne 0 ]; then |
| 81 | echo Could not create empty disk image |
| 82 | exit $? |
| 83 | fi |
| 84 | fi |
Stephen Warren | ef28913 | 2015-10-03 13:56:47 -0600 | [diff] [blame] | 85 | mkfs.fat ${img} |
Stephen Warren | 781910d | 2015-11-17 10:29:07 -0700 | [diff] [blame^] | 86 | if [ $? -ne 0 ]; then |
| 87 | echo Could not create FAT filesystem |
| 88 | exit $? |
| 89 | fi |
Stephen Warren | ef28913 | 2015-10-03 13:56:47 -0600 | [diff] [blame] | 90 | |
| 91 | sudo mount -o loop,uid=$(id -u) ${img} ${mnt} |
Stephen Warren | 781910d | 2015-11-17 10:29:07 -0700 | [diff] [blame^] | 92 | if [ $? -ne 0 ]; then |
| 93 | echo Could not mount test filesystem |
| 94 | exit $? |
| 95 | fi |
Stephen Warren | ef28913 | 2015-10-03 13:56:47 -0600 | [diff] [blame] | 96 | |
| 97 | for ((sects=8; sects < 512; sects += 8)); do |
| 98 | fn=${mnt}/keep-${sects}.img |
| 99 | dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1 |
| 100 | fn=${mnt}/remove-${sects}.img |
| 101 | dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1 |
| 102 | done |
| 103 | |
| 104 | rm -f ${mnt}/remove-*.img |
| 105 | |
| 106 | # 511 deliberately to trigger a file size that's not a multiple of the |
| 107 | # sector size (ignoring sizes that are multiples of both). |
| 108 | dd if=${fill} of=${mnttestfn} bs=511 >/dev/null 2>&1 |
| 109 | |
| 110 | sudo umount ${mnt} |
Stephen Warren | 781910d | 2015-11-17 10:29:07 -0700 | [diff] [blame^] | 111 | if [ $? -ne 0 ]; then |
| 112 | echo Could not unmount test filesystem |
| 113 | exit $? |
| 114 | fi |
Stephen Warren | ef28913 | 2015-10-03 13:56:47 -0600 | [diff] [blame] | 115 | fi |
| 116 | |
| 117 | sudo mount -o ro,loop,uid=$(id -u) ${img} ${mnt} |
Stephen Warren | 781910d | 2015-11-17 10:29:07 -0700 | [diff] [blame^] | 118 | if [ $? -ne 0 ]; then |
| 119 | echo Could not mount test filesystem |
| 120 | exit $? |
| 121 | fi |
Stephen Warren | ef28913 | 2015-10-03 13:56:47 -0600 | [diff] [blame] | 122 | crc=0x`crc32 ${mnttestfn}` |
| 123 | sudo umount ${mnt} |
Stephen Warren | 781910d | 2015-11-17 10:29:07 -0700 | [diff] [blame^] | 124 | if [ $? -ne 0 ]; then |
| 125 | echo Could not unmount test filesystem |
| 126 | exit $? |
| 127 | fi |
Stephen Warren | ef28913 | 2015-10-03 13:56:47 -0600 | [diff] [blame] | 128 | |
| 129 | crc=`printf %02x%02x%02x%02x \ |
| 130 | $((${crc} & 0xff)) \ |
| 131 | $(((${crc} >> 8) & 0xff)) \ |
| 132 | $(((${crc} >> 16) & 0xff)) \ |
| 133 | $((${crc} >> 24))` |
| 134 | |
| 135 | ./sandbox/u-boot << EOF |
| 136 | host bind 0 ${img} |
| 137 | load host 0:0 ${loadaddr} ${testfn} |
| 138 | crc32 ${loadaddr} \$filesize ${crcaddr} |
| 139 | if itest.l *${crcaddr} != ${crc}; then echo FAILURE; else echo PASS; fi |
| 140 | reset |
| 141 | EOF |
Stephen Warren | 781910d | 2015-11-17 10:29:07 -0700 | [diff] [blame^] | 142 | if [ $? -ne 0 ]; then |
| 143 | echo U-Boot exit status indicates an error |
| 144 | exit $? |
| 145 | fi |