summaryrefslogtreecommitdiff
path: root/test/fs/fat-noncontig-test.sh
blob: f153c97bbf05615ac33de0c07be74cb5ef5f2d8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/bin/bash

# (C) Copyright 2015 Stephen Warren
#
# SPDX-License-Identifier:	GPL-2.0+

# This script tests U-Boot's FAT filesystem code's ability to read non-
# contiguous files.

# When porting the ff.c FAT parsing code into U-Boot, it was found that ff.c
# always reads files cluster-by-cluster, which results in poor performance.
# This was solved by adding a patch to ff.c to coalesce reads of adjacent
# clusters. Since this patch needed to correctly handle non-contiguous files,
# this test was written to validate that.
#
# To execute the test, simply run it from the U-Boot source root directory:
#
#    cd u-boot
#    ./test/fs/fat-noncontig-test.sh
#
# The test will create a FAT filesystem image, record the CRC of a randomly
# generated file in the image, build U-Boot sandbox, invoke U-Boot sandbox to
# read the file and validate that the CRCs match. Expected output is shown
# below. The important part of the log is the penultimate line that contains
# either "PASS" or "FAILURE".
#
#    mkfs.fat 3.0.26 (2014-03-07)
#
#
#    U-Boot 2015.10-rc4-00018-g4b22a3e5513f (Oct 03 2015 - 13:49:23 -0600)
#
#    DRAM:  128 MiB
#    Using default environment
#
#    In:    serial
#    Out:   lcd
#    Err:   lcd
#    Net:   No ethernet found.
#    => host bind 0 sandbox/fat-noncontig.img
#    => load host 0:0 1000 noncontig.img
#    33584964 bytes read in 18 ms (1.7 GiB/s)
#    => crc32 1000 $filesize 0
#    crc32 for 00001000 ... 02008743 ==> 6a080523
#    => if itest.l *0 != 2305086a; then echo FAILURE; else echo PASS; fi
#    PASS
#    => reset
#
# All temporary files used by this script are created in ./sandbox to avoid
# polluting the source tree. test/fs/fs-test.sh also uses this directory for
# the same purpose.
#
# TODO: Integrate this (and many other corner-cases e.g. different types of
# FAT) with fs-test.sh so that a single script tests everything filesystem-
# related.

odir=sandbox
img=${odir}/fat-noncontig.img
mnt=${odir}/mnt
fill=/dev/urandom
testfn=noncontig.img
mnttestfn=${mnt}/${testfn}
crcaddr=0
loadaddr=1000

for prereq in fallocate mkfs.fat dd crc32; do
    if [ ! -x "`which $prereq`" ]; then
        echo "Missing $prereq binary. Exiting!"
        exit 1
    fi
done

make O=${odir} -s sandbox_defconfig && make O=${odir} -s -j8

mkdir -p ${mnt}
if [ ! -f ${img} ]; then
    fallocate -l 40M ${img}
    mkfs.fat ${img}

    sudo mount -o loop,uid=$(id -u) ${img} ${mnt}

    for ((sects=8; sects < 512; sects += 8)); do
        fn=${mnt}/keep-${sects}.img
        dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1
        fn=${mnt}/remove-${sects}.img
        dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1
    done

    rm -f ${mnt}/remove-*.img

    # 511 deliberately to trigger a file size that's not a multiple of the
    # sector size (ignoring sizes that are multiples of both).
    dd if=${fill} of=${mnttestfn} bs=511 >/dev/null 2>&1

    sudo umount ${mnt}
fi

sudo mount -o ro,loop,uid=$(id -u) ${img} ${mnt}
crc=0x`crc32 ${mnttestfn}`
sudo umount ${mnt}

crc=`printf %02x%02x%02x%02x \
    $((${crc} & 0xff)) \
    $(((${crc} >> 8) & 0xff)) \
    $(((${crc} >> 16) & 0xff)) \
    $((${crc} >> 24))`

./sandbox/u-boot << EOF
host bind 0 ${img}
load host 0:0 ${loadaddr} ${testfn}
crc32 ${loadaddr} \$filesize ${crcaddr}
if itest.l *${crcaddr} != ${crc}; then echo FAILURE; else echo PASS; fi
reset
EOF