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