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 56odir=sandbox 57img=${odir}/fat-noncontig.img 58mnt=${odir}/mnt 59fill=/dev/urandom 60testfn=noncontig.img 61mnttestfn=${mnt}/${testfn} 62crcaddr=0 63loadaddr=1000 64 65for 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 70done 71 72make O=${odir} -s sandbox_defconfig && make O=${odir} -s -j8 73 74mkdir -p ${mnt} 75if [ ! -f ${img} ]; then 76 fallocate -l 40M ${img} 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 85 mkfs.fat ${img} 86 if [ $? -ne 0 ]; then 87 echo Could not create FAT filesystem 88 exit $? 89 fi 90 91 sudo mount -o loop,uid=$(id -u) ${img} ${mnt} 92 if [ $? -ne 0 ]; then 93 echo Could not mount test filesystem 94 exit $? 95 fi 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} 111 if [ $? -ne 0 ]; then 112 echo Could not unmount test filesystem 113 exit $? 114 fi 115fi 116 117sudo mount -o ro,loop,uid=$(id -u) ${img} ${mnt} 118if [ $? -ne 0 ]; then 119 echo Could not mount test filesystem 120 exit $? 121fi 122crc=0x`crc32 ${mnttestfn}` 123sudo umount ${mnt} 124if [ $? -ne 0 ]; then 125 echo Could not unmount test filesystem 126 exit $? 127fi 128 129crc=`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 136host bind 0 ${img} 137load host 0:0 ${loadaddr} ${testfn} 138crc32 ${loadaddr} \$filesize ${crcaddr} 139if itest.l *${crcaddr} != ${crc}; then echo FAILURE; else echo PASS; fi 140reset 141EOF 142if [ $? -ne 0 ]; then 143 echo U-Boot exit status indicates an error 144 exit $? 145fi 146