test_capsule_firmware.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. # SPDX-License-Identifier: GPL-2.0+
  2. # Copyright (c) 2020, Linaro Limited
  3. # Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  4. #
  5. # U-Boot UEFI: Firmware Update Test
  6. """
  7. This test verifies capsule-on-disk firmware update
  8. """
  9. from subprocess import check_call, check_output, CalledProcessError
  10. import pytest
  11. from capsule_defs import *
  12. @pytest.mark.boardspec('sandbox')
  13. @pytest.mark.buildconfigspec('efi_capsule_firmware_fit')
  14. @pytest.mark.buildconfigspec('efi_capsule_firmware_raw')
  15. @pytest.mark.buildconfigspec('efi_capsule_on_disk')
  16. @pytest.mark.buildconfigspec('dfu')
  17. @pytest.mark.buildconfigspec('dfu_sf')
  18. @pytest.mark.buildconfigspec('cmd_efidebug')
  19. @pytest.mark.buildconfigspec('cmd_fat')
  20. @pytest.mark.buildconfigspec('cmd_memory')
  21. @pytest.mark.buildconfigspec('cmd_nvedit_efi')
  22. @pytest.mark.buildconfigspec('cmd_sf')
  23. @pytest.mark.slow
  24. class TestEfiCapsuleFirmwareFit(object):
  25. def test_efi_capsule_fw1(
  26. self, u_boot_config, u_boot_console, efi_capsule_data):
  27. """
  28. Test Case 1 - Update U-Boot and U-Boot environment on SPI Flash
  29. but with OsIndications unset
  30. No update should happen
  31. 0x100000-0x150000: U-Boot binary (but dummy)
  32. 0x150000-0x200000: U-Boot environment (but dummy)
  33. """
  34. disk_img = efi_capsule_data
  35. with u_boot_console.log.section('Test Case 1-a, before reboot'):
  36. output = u_boot_console.run_command_list([
  37. 'host bind 0 %s' % disk_img,
  38. 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
  39. 'efidebug boot order 1',
  40. 'env set -e OsIndications',
  41. 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
  42. 'env save'])
  43. # initialize contents
  44. output = u_boot_console.run_command_list([
  45. 'sf probe 0:0',
  46. 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
  47. 'sf write 4000000 100000 10',
  48. 'sf read 5000000 100000 10',
  49. 'md.b 5000000 10'])
  50. assert 'Old' in ''.join(output)
  51. output = u_boot_console.run_command_list([
  52. 'sf probe 0:0',
  53. 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR,
  54. 'sf write 4000000 150000 10',
  55. 'sf read 5000000 150000 10',
  56. 'md.b 5000000 10'])
  57. assert 'Old' in ''.join(output)
  58. # place a capsule file
  59. output = u_boot_console.run_command_list([
  60. 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR,
  61. 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR,
  62. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  63. assert 'Test01' in ''.join(output)
  64. # reboot
  65. u_boot_console.restart_uboot()
  66. capsule_early = u_boot_config.buildconfig.get(
  67. 'config_efi_capsule_on_disk_early')
  68. with u_boot_console.log.section('Test Case 1-b, after reboot'):
  69. if not capsule_early:
  70. # make sure that dfu_alt_info exists even persistent variables
  71. # are not available.
  72. output = u_boot_console.run_command_list([
  73. 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
  74. 'host bind 0 %s' % disk_img,
  75. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  76. assert 'Test01' in ''.join(output)
  77. # need to run uefi command to initiate capsule handling
  78. output = u_boot_console.run_command(
  79. 'env print -e Capsule0000')
  80. output = u_boot_console.run_command_list([
  81. 'host bind 0 %s' % disk_img,
  82. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  83. assert 'Test01' in ''.join(output)
  84. output = u_boot_console.run_command_list([
  85. 'sf probe 0:0',
  86. 'sf read 4000000 100000 10',
  87. 'md.b 4000000 10'])
  88. assert 'u-boot:Old' in ''.join(output)
  89. output = u_boot_console.run_command_list([
  90. 'sf read 4000000 150000 10',
  91. 'md.b 4000000 10'])
  92. assert 'u-boot-env:Old' in ''.join(output)
  93. def test_efi_capsule_fw2(
  94. self, u_boot_config, u_boot_console, efi_capsule_data):
  95. """
  96. Test Case 2 - Update U-Boot and U-Boot environment on SPI Flash
  97. 0x100000-0x150000: U-Boot binary (but dummy)
  98. 0x150000-0x200000: U-Boot environment (but dummy)
  99. """
  100. disk_img = efi_capsule_data
  101. with u_boot_console.log.section('Test Case 2-a, before reboot'):
  102. output = u_boot_console.run_command_list([
  103. 'host bind 0 %s' % disk_img,
  104. 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
  105. 'efidebug boot order 1',
  106. 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
  107. 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
  108. 'env save'])
  109. # initialize contents
  110. output = u_boot_console.run_command_list([
  111. 'sf probe 0:0',
  112. 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
  113. 'sf write 4000000 100000 10',
  114. 'sf read 5000000 100000 10',
  115. 'md.b 5000000 10'])
  116. assert 'Old' in ''.join(output)
  117. output = u_boot_console.run_command_list([
  118. 'sf probe 0:0',
  119. 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR,
  120. 'sf write 4000000 150000 10',
  121. 'sf read 5000000 150000 10',
  122. 'md.b 5000000 10'])
  123. assert 'Old' in ''.join(output)
  124. # place a capsule file
  125. output = u_boot_console.run_command_list([
  126. 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR,
  127. 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR,
  128. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  129. assert 'Test01' in ''.join(output)
  130. # reboot
  131. u_boot_console.restart_uboot()
  132. capsule_early = u_boot_config.buildconfig.get(
  133. 'config_efi_capsule_on_disk_early')
  134. capsule_auth = u_boot_config.buildconfig.get(
  135. 'config_efi_capsule_authenticate')
  136. with u_boot_console.log.section('Test Case 2-b, after reboot'):
  137. if not capsule_early:
  138. # make sure that dfu_alt_info exists even persistent variables
  139. # are not available.
  140. output = u_boot_console.run_command_list([
  141. 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
  142. 'host bind 0 %s' % disk_img,
  143. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  144. assert 'Test01' in ''.join(output)
  145. # need to run uefi command to initiate capsule handling
  146. output = u_boot_console.run_command(
  147. 'env print -e Capsule0000')
  148. output = u_boot_console.run_command_list([
  149. 'host bind 0 %s' % disk_img,
  150. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  151. assert 'Test01' not in ''.join(output)
  152. output = u_boot_console.run_command_list([
  153. 'sf probe 0:0',
  154. 'sf read 4000000 100000 10',
  155. 'md.b 4000000 10'])
  156. if capsule_auth:
  157. assert 'u-boot:Old' in ''.join(output)
  158. else:
  159. assert 'u-boot:New' in ''.join(output)
  160. output = u_boot_console.run_command_list([
  161. 'sf read 4000000 150000 10',
  162. 'md.b 4000000 10'])
  163. if capsule_auth:
  164. assert 'u-boot-env:Old' in ''.join(output)
  165. else:
  166. assert 'u-boot-env:New' in ''.join(output)
  167. def test_efi_capsule_fw3(
  168. self, u_boot_config, u_boot_console, efi_capsule_data):
  169. """
  170. Test Case 3 - Update U-Boot on SPI Flash, raw image format
  171. 0x100000-0x150000: U-Boot binary (but dummy)
  172. """
  173. disk_img = efi_capsule_data
  174. with u_boot_console.log.section('Test Case 3-a, before reboot'):
  175. output = u_boot_console.run_command_list([
  176. 'host bind 0 %s' % disk_img,
  177. 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
  178. 'efidebug boot order 1',
  179. 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
  180. 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
  181. 'env save'])
  182. # initialize content
  183. output = u_boot_console.run_command_list([
  184. 'sf probe 0:0',
  185. 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
  186. 'sf write 4000000 100000 10',
  187. 'sf read 5000000 100000 10',
  188. 'md.b 5000000 10'])
  189. assert 'Old' in ''.join(output)
  190. # place a capsule file
  191. output = u_boot_console.run_command_list([
  192. 'fatload host 0:1 4000000 %s/Test02' % CAPSULE_DATA_DIR,
  193. 'fatwrite host 0:1 4000000 %s/Test02 $filesize' % CAPSULE_INSTALL_DIR,
  194. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  195. assert 'Test02' in ''.join(output)
  196. # reboot
  197. u_boot_console.restart_uboot()
  198. capsule_early = u_boot_config.buildconfig.get(
  199. 'config_efi_capsule_on_disk_early')
  200. capsule_auth = u_boot_config.buildconfig.get(
  201. 'config_efi_capsule_authenticate')
  202. with u_boot_console.log.section('Test Case 3-b, after reboot'):
  203. if not capsule_early:
  204. # make sure that dfu_alt_info exists even persistent variables
  205. # are not available.
  206. output = u_boot_console.run_command_list([
  207. 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
  208. 'host bind 0 %s' % disk_img,
  209. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  210. assert 'Test02' in ''.join(output)
  211. # need to run uefi command to initiate capsule handling
  212. output = u_boot_console.run_command(
  213. 'env print -e Capsule0000')
  214. output = u_boot_console.run_command_list(['efidebug capsule esrt'])
  215. # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID is in the ESRT.
  216. assert 'AE13FF2D-9AD4-4E25-9AC8-6D80B3B22147' in ''.join(output)
  217. # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT.
  218. assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output)
  219. output = u_boot_console.run_command_list([
  220. 'host bind 0 %s' % disk_img,
  221. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  222. assert 'Test02' not in ''.join(output)
  223. output = u_boot_console.run_command_list([
  224. 'sf probe 0:0',
  225. 'sf read 4000000 100000 10',
  226. 'md.b 4000000 10'])
  227. if capsule_auth:
  228. assert 'u-boot:Old' in ''.join(output)
  229. else:
  230. assert 'u-boot:New' in ''.join(output)
  231. def test_efi_capsule_fw4(
  232. self, u_boot_config, u_boot_console, efi_capsule_data):
  233. """
  234. Test Case 4 - Test "--guid" option of mkeficapsule
  235. The test scenario is the same as Case 3.
  236. """
  237. disk_img = efi_capsule_data
  238. with u_boot_console.log.section('Test Case 4-a, before reboot'):
  239. output = u_boot_console.run_command_list([
  240. 'host bind 0 %s' % disk_img,
  241. 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
  242. 'efidebug boot order 1',
  243. 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
  244. 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
  245. 'env save'])
  246. # initialize content
  247. output = u_boot_console.run_command_list([
  248. 'sf probe 0:0',
  249. 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
  250. 'sf write 4000000 100000 10',
  251. 'sf read 5000000 100000 10',
  252. 'md.b 5000000 10'])
  253. assert 'Old' in ''.join(output)
  254. # place a capsule file
  255. output = u_boot_console.run_command_list([
  256. 'fatload host 0:1 4000000 %s/Test03' % CAPSULE_DATA_DIR,
  257. 'fatwrite host 0:1 4000000 %s/Test03 $filesize' % CAPSULE_INSTALL_DIR,
  258. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  259. assert 'Test03' in ''.join(output)
  260. # reboot
  261. u_boot_console.restart_uboot()
  262. capsule_early = u_boot_config.buildconfig.get(
  263. 'config_efi_capsule_on_disk_early')
  264. capsule_auth = u_boot_config.buildconfig.get(
  265. 'config_efi_capsule_authenticate')
  266. with u_boot_console.log.section('Test Case 4-b, after reboot'):
  267. if not capsule_early:
  268. # make sure that dfu_alt_info exists even persistent variables
  269. # are not available.
  270. output = u_boot_console.run_command_list([
  271. 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
  272. 'host bind 0 %s' % disk_img,
  273. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  274. assert 'Test03' in ''.join(output)
  275. # need to run uefi command to initiate capsule handling
  276. output = u_boot_console.run_command(
  277. 'env print -e Capsule0000')
  278. output = u_boot_console.run_command_list(['efidebug capsule esrt'])
  279. # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT.
  280. assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output)
  281. output = u_boot_console.run_command_list([
  282. 'host bind 0 %s' % disk_img,
  283. 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
  284. assert 'Test03' not in ''.join(output)
  285. output = u_boot_console.run_command_list([
  286. 'sf probe 0:0',
  287. 'sf read 4000000 100000 10',
  288. 'md.b 4000000 10'])
  289. if capsule_auth:
  290. assert 'u-boot:Old' in ''.join(output)
  291. else:
  292. assert 'u-boot:New' in ''.join(output)