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