flashrom_partial_write_test.sh 7.2 KB

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