| 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 | # You should have received a copy of the GNU General Public License |
|---|
| 17 | # along with this program; if not, write to the Free Software |
|---|
| 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 19 | # |
|---|
| 20 | # This script attempts to test Flashrom partial write capability by writing |
|---|
| 21 | # patterns of 0xff and 0x00 bytes to the lowest 128kB of flash. 128kB is chosen |
|---|
| 22 | # since 64kB is usually the largest possible block size, so we will try to |
|---|
| 23 | # cover at least two blocks with this test. |
|---|
| 24 | |
|---|
| 25 | EXIT_SUCCESS=0 |
|---|
| 26 | EXIT_FAILURE=1 |
|---|
| 27 | |
|---|
| 28 | # The copy of flashrom to test. If unset, we'll assume the user wants to test |
|---|
| 29 | # a newly built flashrom binary in the parent directory (this script should |
|---|
| 30 | # reside in flashrom/util). |
|---|
| 31 | if [ -z "$FLASHROM" ] ; then |
|---|
| 32 | FLASHROM="../flashrom" |
|---|
| 33 | fi |
|---|
| 34 | echo "testing flashrom binary: ${FLASHROM}" |
|---|
| 35 | |
|---|
| 36 | OLDDIR=$(pwd) |
|---|
| 37 | |
|---|
| 38 | # test data location |
|---|
| 39 | TMPDIR=$(mktemp -d -t flashrom_test.XXXXXXXXXX) |
|---|
| 40 | if [ "$?" != "0" ] ; then |
|---|
| 41 | echo "Could not create temporary directory" |
|---|
| 42 | exit $EXIT_FAILURE |
|---|
| 43 | fi |
|---|
| 44 | |
|---|
| 45 | ZERO_4K="00_4k.bin" |
|---|
| 46 | FF_4K="ff_4k.bin" |
|---|
| 47 | FF_4K_TEXT="ff_4k.txt" |
|---|
| 48 | |
|---|
| 49 | TESTFILE="test.bin" |
|---|
| 50 | |
|---|
| 51 | which uuencode > /dev/null |
|---|
| 52 | if [ "$?" != "0" ] ; then |
|---|
| 53 | echo "uuencode is required to use this script" |
|---|
| 54 | exit $EXIT_FAILURE |
|---|
| 55 | fi |
|---|
| 56 | |
|---|
| 57 | which flashrom > /dev/null |
|---|
| 58 | if [ "$?" != "0" ] ; then |
|---|
| 59 | echo "Please install a stable version of flashrom in your path." |
|---|
| 60 | echo "This will be used to compare the test flashrom binary and " |
|---|
| 61 | echo "restore your firmware image at the end of the test." |
|---|
| 62 | exit $EXIT_FAILURE |
|---|
| 63 | fi |
|---|
| 64 | |
|---|
| 65 | # Keep a copy of flashrom with the test data |
|---|
| 66 | cp "$FLASHROM" "${TMPDIR}/" |
|---|
| 67 | cd "$TMPDIR" |
|---|
| 68 | echo "Running test in ${TMPDIR}" |
|---|
| 69 | |
|---|
| 70 | # Make 4k worth of 0xff bytes |
|---|
| 71 | echo "begin 640 $FF_4K" > "$FF_4K_TEXT" |
|---|
| 72 | i=0 |
|---|
| 73 | while [ $i -le 90 ] ; do |
|---|
| 74 | echo "M____________________________________________________________" >> "$FF_4K_TEXT" |
|---|
| 75 | i=$((${i} + 1)) |
|---|
| 76 | done |
|---|
| 77 | echo "!_P``" >> "$FF_4K_TEXT" |
|---|
| 78 | echo "\`" >> "$FF_4K_TEXT" |
|---|
| 79 | echo "end" >> "$FF_4K_TEXT" |
|---|
| 80 | uudecode -o "$FF_4K" "$FF_4K_TEXT" |
|---|
| 81 | rm -f "$FF_4K_TEXT" |
|---|
| 82 | |
|---|
| 83 | # Make 4k worth of 0x00 bytes |
|---|
| 84 | dd if=/dev/zero of="$ZERO_4K" bs=1 count=4096 2> /dev/null |
|---|
| 85 | echo "ffh pattern written in ${FF_4K}" |
|---|
| 86 | echo "00h pattern written in ${ZERO_4K}" |
|---|
| 87 | |
|---|
| 88 | echo "Reading BIOS image" |
|---|
| 89 | BIOS="bios.bin" |
|---|
| 90 | flashrom ${FLASHROM_PARAM} -r "$BIOS" > /dev/null |
|---|
| 91 | echo "Original image saved as ${BIOS}" |
|---|
| 92 | |
|---|
| 93 | # $1: exit code |
|---|
| 94 | do_exit() { |
|---|
| 95 | if [ ${1} -eq ${EXIT_FAILURE} ] ; then |
|---|
| 96 | echo "Result: FAILED" |
|---|
| 97 | else |
|---|
| 98 | echo "Result: PASSED" |
|---|
| 99 | fi |
|---|
| 100 | |
|---|
| 101 | echo "restoring original bios image using system's flashrom" |
|---|
| 102 | flashrom ${FLASHROM_PARAM} -w "$BIOS" |
|---|
| 103 | echo "test files remain in ${TMPDIR}" |
|---|
| 104 | cd "$OLDDIR" |
|---|
| 105 | exit "$1" |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | # |
|---|
| 109 | # Actual tests are performed below. |
|---|
| 110 | # |
|---|
| 111 | NUM_REGIONS=16 |
|---|
| 112 | |
|---|
| 113 | # Make a layout - 4K regions on 4K boundaries. This will test basic |
|---|
| 114 | # functionality of erasing and writing specific blocks. |
|---|
| 115 | echo " |
|---|
| 116 | 0x000000:0x000fff 00_0 |
|---|
| 117 | 0x001000:0x001fff ff_0 |
|---|
| 118 | |
|---|
| 119 | 0x002000:0x002fff 00_1 |
|---|
| 120 | 0x003000:0x003fff ff_1 |
|---|
| 121 | |
|---|
| 122 | 0x004000:0x004fff 00_2 |
|---|
| 123 | 0x005000:0x005fff ff_2 |
|---|
| 124 | |
|---|
| 125 | 0x006000:0x006fff 00_3 |
|---|
| 126 | 0x007000:0x007fff ff_3 |
|---|
| 127 | |
|---|
| 128 | 0x008000:0x008fff 00_4 |
|---|
| 129 | 0x009000:0x009fff ff_4 |
|---|
| 130 | |
|---|
| 131 | 0x00a000:0x00afff 00_5 |
|---|
| 132 | 0x00b000:0x00bfff ff_5 |
|---|
| 133 | |
|---|
| 134 | 0x00c000:0x00cfff 00_6 |
|---|
| 135 | 0x00d000:0x00dfff ff_6 |
|---|
| 136 | |
|---|
| 137 | 0x00e000:0x00efff 00_7 |
|---|
| 138 | 0x00f000:0x00ffff ff_7 |
|---|
| 139 | |
|---|
| 140 | 0x010000:0x010fff 00_8 |
|---|
| 141 | 0x011000:0x011fff ff_8 |
|---|
| 142 | |
|---|
| 143 | 0x012000:0x012fff 00_9 |
|---|
| 144 | 0x013000:0x013fff ff_9 |
|---|
| 145 | |
|---|
| 146 | 0x014000:0x014fff 00_10 |
|---|
| 147 | 0x015000:0x015fff ff_10 |
|---|
| 148 | |
|---|
| 149 | 0x016000:0x016fff 00_11 |
|---|
| 150 | 0x017000:0x017fff ff_11 |
|---|
| 151 | |
|---|
| 152 | 0x018000:0x018fff 00_12 |
|---|
| 153 | 0x019000:0x019fff ff_12 |
|---|
| 154 | |
|---|
| 155 | 0x01a000:0x01afff 00_13 |
|---|
| 156 | 0x01b000:0x01bfff ff_13 |
|---|
| 157 | |
|---|
| 158 | 0x01c000:0x01cfff 00_14 |
|---|
| 159 | 0x01d000:0x01dfff ff_14 |
|---|
| 160 | |
|---|
| 161 | 0x01e000:0x01efff 00_15 |
|---|
| 162 | 0x01f000:0x01ffff ff_15 |
|---|
| 163 | " > layout_4k_aligned.txt |
|---|
| 164 | |
|---|
| 165 | cp "$BIOS" "$TESTFILE" |
|---|
| 166 | i=0 |
|---|
| 167 | while [ $i -lt $NUM_REGIONS ] ; do |
|---|
| 168 | echo -n "aligned region ${i} test: " |
|---|
| 169 | offset=$((${i} * 8192)) |
|---|
| 170 | dd if=${ZERO_4K} of=${TESTFILE} bs=1 conv=notrunc seek=${offset} 2> /dev/null |
|---|
| 171 | dd if=${FF_4K} of=${TESTFILE} bs=1 conv=notrunc seek=$((${offset} + 4096)) 2> /dev/null |
|---|
| 172 | |
|---|
| 173 | ./flashrom ${FLASHROM_PARAM} -l layout_4k_aligned.txt -i 00_${i} -i ff_${i} -w "$TESTFILE" > /dev/null |
|---|
| 174 | if [ "$?" != "0" ] ; then |
|---|
| 175 | echo "failed to flash region" |
|---|
| 176 | do_exit "$EXIT_FAILURE" |
|---|
| 177 | fi |
|---|
| 178 | |
|---|
| 179 | # download the entire ROM image and use diff to compare to ensure |
|---|
| 180 | # flashrom logic does not violate user-specified regions |
|---|
| 181 | flashrom ${FLASHROM_PARAM} -r difftest.bin > /dev/null |
|---|
| 182 | diff -q difftest.bin "$TESTFILE" |
|---|
| 183 | if [ "$?" != "0" ] ; then |
|---|
| 184 | echo "failed diff test" |
|---|
| 185 | do_exit "$EXIT_FAILURE" |
|---|
| 186 | fi |
|---|
| 187 | rm -f difftest.bin |
|---|
| 188 | |
|---|
| 189 | i=$((${i} + 1)) |
|---|
| 190 | echo "passed" |
|---|
| 191 | done |
|---|
| 192 | |
|---|
| 193 | # Make a layout - 4K regions on 4.5K boundaries. This will help find problems |
|---|
| 194 | # with logic that only operates on part of a block. For example, if a user |
|---|
| 195 | # wishes to re-write a fraction of a block, then: |
|---|
| 196 | # 1. The whole block must be erased. |
|---|
| 197 | # 2. The old content must be restored at unspecified offsets. |
|---|
| 198 | # 3. The new content must be written at specified offsets. |
|---|
| 199 | # |
|---|
| 200 | # Note: The last chunk of 0xff bytes is only 2k as to avoid overrunning a 128kB |
|---|
| 201 | # test image. |
|---|
| 202 | # |
|---|
| 203 | echo " |
|---|
| 204 | 0x000800:0x0017ff 00_0 |
|---|
| 205 | 0x001800:0x0027ff ff_0 |
|---|
| 206 | |
|---|
| 207 | 0x002800:0x0037ff 00_1 |
|---|
| 208 | 0x003800:0x0047ff ff_1 |
|---|
| 209 | |
|---|
| 210 | 0x004800:0x0057ff 00_2 |
|---|
| 211 | 0x005800:0x0067ff ff_2 |
|---|
| 212 | |
|---|
| 213 | 0x006800:0x0077ff 00_3 |
|---|
| 214 | 0x007800:0x0087ff ff_3 |
|---|
| 215 | |
|---|
| 216 | 0x008800:0x0097ff 00_4 |
|---|
| 217 | 0x009800:0x00a7ff ff_4 |
|---|
| 218 | |
|---|
| 219 | 0x00a800:0x00b7ff 00_5 |
|---|
| 220 | 0x00b800:0x00c7ff ff_5 |
|---|
| 221 | |
|---|
| 222 | 0x00c800:0x00d7ff 00_6 |
|---|
| 223 | 0x00d800:0x00e7ff ff_6 |
|---|
| 224 | |
|---|
| 225 | 0x00e800:0x00f7ff 00_7 |
|---|
| 226 | 0x00f800:0x0107ff ff_7 |
|---|
| 227 | |
|---|
| 228 | 0x010800:0x0117ff 00_8 |
|---|
| 229 | 0x011800:0x0127ff ff_8 |
|---|
| 230 | |
|---|
| 231 | 0x012800:0x0137ff 00_9 |
|---|
| 232 | 0x013800:0x0147ff ff_9 |
|---|
| 233 | |
|---|
| 234 | 0x014800:0x0157ff 00_10 |
|---|
| 235 | 0x015800:0x0167ff ff_10 |
|---|
| 236 | |
|---|
| 237 | 0x016800:0x0177ff 00_11 |
|---|
| 238 | 0x017800:0x0187ff ff_11 |
|---|
| 239 | |
|---|
| 240 | 0x018800:0x0197ff 00_12 |
|---|
| 241 | 0x019800:0x01a7ff ff_12 |
|---|
| 242 | |
|---|
| 243 | 0x01a800:0x01b7ff 00_13 |
|---|
| 244 | 0x01b800:0x01c7ff ff_13 |
|---|
| 245 | |
|---|
| 246 | 0x01c800:0x01d7ff 00_14 |
|---|
| 247 | 0x01d800:0x01e7ff ff_14 |
|---|
| 248 | |
|---|
| 249 | 0x01e800:0x01f7ff 00_15 |
|---|
| 250 | 0x01f800:0x01ffff ff_15 |
|---|
| 251 | " > layout_unaligned.txt |
|---|
| 252 | |
|---|
| 253 | # reset the test file and ROM to the original state |
|---|
| 254 | flashrom ${FLASHROM_PARAM} -w "$BIOS" > /dev/null |
|---|
| 255 | cp "$BIOS" "$TESTFILE" |
|---|
| 256 | |
|---|
| 257 | i=0 |
|---|
| 258 | while [ $i -lt $NUM_REGIONS ] ; do |
|---|
| 259 | echo -n "unaligned region ${i} test: " |
|---|
| 260 | |
|---|
| 261 | offset=$(($((${i} * 8192)) + 2048)) |
|---|
| 262 | # Protect against too long write |
|---|
| 263 | writelen=4096 |
|---|
| 264 | if [ $((${offset} + 4096 + 4096)) -ge 131072 ]; then |
|---|
| 265 | writelen=$((131072 - $((${offset} + 4096)))) |
|---|
| 266 | if [ ${writelen} -lt 0 ]; then |
|---|
| 267 | writelen=0 |
|---|
| 268 | fi |
|---|
| 269 | fi |
|---|
| 270 | dd if=${ZERO_4K} of=${TESTFILE} bs=1 conv=notrunc seek=${offset} 2> /dev/null |
|---|
| 271 | dd if=${FF_4K} of=${TESTFILE} bs=1 conv=notrunc seek=$((${offset} + 4096)) count=writelen 2> /dev/null |
|---|
| 272 | |
|---|
| 273 | ./flashrom ${FLASHROM_PARAM} -l layout_unaligned.txt -i 00_${i} -i ff_${i} -w "$TESTFILE" > /dev/null |
|---|
| 274 | if [ "$?" != "0" ] ; then |
|---|
| 275 | echo "failed to flash region" |
|---|
| 276 | do_exit "$EXIT_FAILURE" |
|---|
| 277 | fi |
|---|
| 278 | |
|---|
| 279 | # download the entire ROM image and use diff to compare to ensure |
|---|
| 280 | # flashrom logic does not violate user-specified regions |
|---|
| 281 | flashrom ${FLASHROM_PARAM} -r difftest.bin > /dev/null |
|---|
| 282 | diff -q difftest.bin "$TESTFILE" |
|---|
| 283 | if [ "$?" != "0" ] ; then |
|---|
| 284 | echo "failed diff test" |
|---|
| 285 | do_exit "$EXIT_FAILURE" |
|---|
| 286 | fi |
|---|
| 287 | rm -f difftest.bin |
|---|
| 288 | |
|---|
| 289 | i=$((${i} + 1)) |
|---|
| 290 | echo "passed" |
|---|
| 291 | done |
|---|
| 292 | |
|---|
| 293 | do_exit "$EXIT_SUCCESS" |
|---|