1#!/bin/sh 2# 3# Copyright (C) 2010 Google Inc. 4# Written by David Hendricks for Google Inc. 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# This script attempts to test Flashrom partial write capability by writing 17# patterns of 0xff and 0x00 bytes to the lowest 128kB of flash. 128kB is chosen 18# since 64kB is usually the largest possible block size, so we will try to 19# cover at least two blocks with this test. 20 21EXIT_SUCCESS=0 22EXIT_FAILURE=1 23 24# The copy of flashrom to test. If unset, we'll assume the user wants to test 25# a newly built flashrom binary in the parent directory (this script should 26# reside in flashrom/util). 27if [ -z "$FLASHROM" ] ; then 28 FLASHROM="../flashrom" 29fi 30echo "testing flashrom binary: ${FLASHROM}" 31 32OLDDIR=$(pwd) 33 34# test data location 35TMPDIR=$(mktemp -d -t flashrom_test.XXXXXXXXXX) 36if [ "$?" != "0" ] ; then 37 echo "Could not create temporary directory" 38 exit $EXIT_FAILURE 39fi 40 41ZERO_4K="00_4k.bin" 42FF_4K="ff_4k.bin" 43FF_4K_TEXT="ff_4k.txt" 44 45TESTFILE="test.bin" 46 47which uuencode > /dev/null 48if [ "$?" != "0" ] ; then 49 echo "uuencode is required to use this script" 50 exit $EXIT_FAILURE 51fi 52 53which flashrom > /dev/null 54if [ "$?" != "0" ] ; then 55 echo "Please install a stable version of flashrom in your path." 56 echo "This will be used to compare the test flashrom binary and " 57 echo "restore your firmware image at the end of the test." 58 exit $EXIT_FAILURE 59fi 60 61# Keep a copy of flashrom with the test data 62cp "$FLASHROM" "${TMPDIR}/" 63cd "$TMPDIR" 64echo "Running test in ${TMPDIR}" 65 66# Make 4k worth of 0xff bytes 67echo "begin 640 $FF_4K" > "$FF_4K_TEXT" 68i=0 69while [ $i -le 90 ] ; do 70 echo "M____________________________________________________________" >> "$FF_4K_TEXT" 71 i=$((${i} + 1)) 72done 73echo "!_P``" >> "$FF_4K_TEXT" 74echo "\`" >> "$FF_4K_TEXT" 75echo "end" >> "$FF_4K_TEXT" 76uudecode -o "$FF_4K" "$FF_4K_TEXT" 77rm -f "$FF_4K_TEXT" 78 79# Make 4k worth of 0x00 bytes 80dd if=/dev/zero of="$ZERO_4K" bs=1 count=4096 2> /dev/null 81echo "ffh pattern written in ${FF_4K}" 82echo "00h pattern written in ${ZERO_4K}" 83 84echo "Reading BIOS image" 85BIOS="bios.bin" 86flashrom ${FLASHROM_PARAM} -r "$BIOS" > /dev/null 87echo "Original image saved as ${BIOS}" 88 89# $1: exit code 90do_exit() { 91 if [ ${1} -eq ${EXIT_FAILURE} ] ; then 92 echo "Result: FAILED" 93 else 94 echo "Result: PASSED" 95 fi 96 97 echo "restoring original bios image using system's flashrom" 98 flashrom ${FLASHROM_PARAM} -w "$BIOS" 99 echo "test files remain in ${TMPDIR}" 100 cd "$OLDDIR" 101 exit "$1" 102} 103 104# 105# Actual tests are performed below. 106# 107NUM_REGIONS=16 108 109# Make a layout - 4K regions on 4K boundaries. This will test basic 110# functionality of erasing and writing specific blocks. 111echo " 1120x000000:0x000fff 00_0 1130x001000:0x001fff ff_0 114 1150x002000:0x002fff 00_1 1160x003000:0x003fff ff_1 117 1180x004000:0x004fff 00_2 1190x005000:0x005fff ff_2 120 1210x006000:0x006fff 00_3 1220x007000:0x007fff ff_3 123 1240x008000:0x008fff 00_4 1250x009000:0x009fff ff_4 126 1270x00a000:0x00afff 00_5 1280x00b000:0x00bfff ff_5 129 1300x00c000:0x00cfff 00_6 1310x00d000:0x00dfff ff_6 132 1330x00e000:0x00efff 00_7 1340x00f000:0x00ffff ff_7 135 1360x010000:0x010fff 00_8 1370x011000:0x011fff ff_8 138 1390x012000:0x012fff 00_9 1400x013000:0x013fff ff_9 141 1420x014000:0x014fff 00_10 1430x015000:0x015fff ff_10 144 1450x016000:0x016fff 00_11 1460x017000:0x017fff ff_11 147 1480x018000:0x018fff 00_12 1490x019000:0x019fff ff_12 150 1510x01a000:0x01afff 00_13 1520x01b000:0x01bfff ff_13 153 1540x01c000:0x01cfff 00_14 1550x01d000:0x01dfff ff_14 156 1570x01e000:0x01efff 00_15 1580x01f000:0x01ffff ff_15 159" > layout_4k_aligned.txt 160 161cp "$BIOS" "$TESTFILE" 162i=0 163while [ $i -lt $NUM_REGIONS ] ; do 164 echo -n "aligned region ${i} test: " 165 offset=$((${i} * 8192)) 166 dd if=${ZERO_4K} of=${TESTFILE} bs=1 conv=notrunc seek=${offset} 2> /dev/null 167 dd if=${FF_4K} of=${TESTFILE} bs=1 conv=notrunc seek=$((${offset} + 4096)) 2> /dev/null 168 169 ./flashrom ${FLASHROM_PARAM} -l layout_4k_aligned.txt -i 00_${i} -i ff_${i} -w "$TESTFILE" > /dev/null 170 if [ "$?" != "0" ] ; then 171 echo "failed to flash region" 172 do_exit "$EXIT_FAILURE" 173 fi 174 175 # download the entire ROM image and use diff to compare to ensure 176 # flashrom logic does not violate user-specified regions 177 flashrom ${FLASHROM_PARAM} -r difftest.bin > /dev/null 178 diff -q difftest.bin "$TESTFILE" 179 if [ "$?" != "0" ] ; then 180 echo "failed diff test" 181 do_exit "$EXIT_FAILURE" 182 fi 183 rm -f difftest.bin 184 185 i=$((${i} + 1)) 186 echo "passed" 187done 188 189# Make a layout - 4K regions on 4.5K boundaries. This will help find problems 190# with logic that only operates on part of a block. For example, if a user 191# wishes to re-write a fraction of a block, then: 192# 1. The whole block must be erased. 193# 2. The old content must be restored at unspecified offsets. 194# 3. The new content must be written at specified offsets. 195# 196# Note: The last chunk of 0xff bytes is only 2k as to avoid overrunning a 128kB 197# test image. 198# 199echo " 2000x000800:0x0017ff 00_0 2010x001800:0x0027ff ff_0 202 2030x002800:0x0037ff 00_1 2040x003800:0x0047ff ff_1 205 2060x004800:0x0057ff 00_2 2070x005800:0x0067ff ff_2 208 2090x006800:0x0077ff 00_3 2100x007800:0x0087ff ff_3 211 2120x008800:0x0097ff 00_4 2130x009800:0x00a7ff ff_4 214 2150x00a800:0x00b7ff 00_5 2160x00b800:0x00c7ff ff_5 217 2180x00c800:0x00d7ff 00_6 2190x00d800:0x00e7ff ff_6 220 2210x00e800:0x00f7ff 00_7 2220x00f800:0x0107ff ff_7 223 2240x010800:0x0117ff 00_8 2250x011800:0x0127ff ff_8 226 2270x012800:0x0137ff 00_9 2280x013800:0x0147ff ff_9 229 2300x014800:0x0157ff 00_10 2310x015800:0x0167ff ff_10 232 2330x016800:0x0177ff 00_11 2340x017800:0x0187ff ff_11 235 2360x018800:0x0197ff 00_12 2370x019800:0x01a7ff ff_12 238 2390x01a800:0x01b7ff 00_13 2400x01b800:0x01c7ff ff_13 241 2420x01c800:0x01d7ff 00_14 2430x01d800:0x01e7ff ff_14 244 2450x01e800:0x01f7ff 00_15 2460x01f800:0x01ffff ff_15 247" > layout_unaligned.txt 248 249# reset the test file and ROM to the original state 250flashrom ${FLASHROM_PARAM} -w "$BIOS" > /dev/null 251cp "$BIOS" "$TESTFILE" 252 253i=0 254while [ $i -lt $NUM_REGIONS ] ; do 255 echo -n "unaligned region ${i} test: " 256 257 offset=$(($((${i} * 8192)) + 2048)) 258 # Protect against too long write 259 writelen=4096 260 if [ $((${offset} + 4096 + 4096)) -ge 131072 ]; then 261 writelen=$((131072 - $((${offset} + 4096)))) 262 if [ ${writelen} -lt 0 ]; then 263 writelen=0 264 fi 265 fi 266 dd if=${ZERO_4K} of=${TESTFILE} bs=1 conv=notrunc seek=${offset} 2> /dev/null 267 dd if=${FF_4K} of=${TESTFILE} bs=1 conv=notrunc seek=$((${offset} + 4096)) count=writelen 2> /dev/null 268 269 ./flashrom ${FLASHROM_PARAM} -l layout_unaligned.txt -i 00_${i} -i ff_${i} -w "$TESTFILE" > /dev/null 270 if [ "$?" != "0" ] ; then 271 echo "failed to flash region" 272 do_exit "$EXIT_FAILURE" 273 fi 274 275 # download the entire ROM image and use diff to compare to ensure 276 # flashrom logic does not violate user-specified regions 277 flashrom ${FLASHROM_PARAM} -r difftest.bin > /dev/null 278 diff -q difftest.bin "$TESTFILE" 279 if [ "$?" != "0" ] ; then 280 echo "failed diff test" 281 do_exit "$EXIT_FAILURE" 282 fi 283 rm -f difftest.bin 284 285 i=$((${i} + 1)) 286 echo "passed" 287done 288 289do_exit "$EXIT_SUCCESS" 290