1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (c) 2020, Linaro Limited
3 # Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
5 # U-Boot UEFI: Firmware Update Test
8 This test verifies capsule-on-disk firmware update
11 from subprocess import check_call, check_output, CalledProcessError
13 from capsule_defs import *
16 @pytest.mark.boardspec('sandbox')
17 @pytest.mark.buildconfigspec('efi_capsule_firmware_fit')
18 @pytest.mark.buildconfigspec('efi_capsule_firmware_raw')
19 @pytest.mark.buildconfigspec('efi_capsule_on_disk')
20 @pytest.mark.buildconfigspec('dfu')
21 @pytest.mark.buildconfigspec('dfu_sf')
22 @pytest.mark.buildconfigspec('cmd_efidebug')
23 @pytest.mark.buildconfigspec('cmd_fat')
24 @pytest.mark.buildconfigspec('cmd_memory')
25 @pytest.mark.buildconfigspec('cmd_nvedit_efi')
26 @pytest.mark.buildconfigspec('cmd_sf')
28 class TestEfiCapsuleFirmwareFit(object):
29 def test_efi_capsule_fw1(
30 self, u_boot_config, u_boot_console, efi_capsule_data):
32 Test Case 1 - Update U-Boot and U-Boot environment on SPI Flash
33 but with OsIndications unset
34 No update should happen
35 0x100000-0x150000: U-Boot binary (but dummy)
36 0x150000-0x200000: U-Boot environment (but dummy)
38 disk_img = efi_capsule_data
39 with u_boot_console.log.section('Test Case 1-a, before reboot'):
40 output = u_boot_console.run_command_list([
41 'host bind 0 %s' % disk_img,
42 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
43 'efidebug boot order 1',
44 'env set -e OsIndications',
45 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
49 output = u_boot_console.run_command_list([
51 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
52 'sf write 4000000 100000 10',
53 'sf read 5000000 100000 10',
55 assert 'Old' in ''.join(output)
56 output = u_boot_console.run_command_list([
58 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR,
59 'sf write 4000000 150000 10',
60 'sf read 5000000 150000 10',
62 assert 'Old' in ''.join(output)
64 # place a capsule file
65 output = u_boot_console.run_command_list([
66 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR,
67 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR,
68 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
69 assert 'Test01' in ''.join(output)
72 u_boot_console.restart_uboot()
74 capsule_early = u_boot_config.buildconfig.get(
75 'config_efi_capsule_on_disk_early')
76 with u_boot_console.log.section('Test Case 1-b, after reboot'):
78 # make sure that dfu_alt_info exists even persistent variables
80 output = u_boot_console.run_command_list([
81 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
82 'host bind 0 %s' % disk_img,
83 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
84 assert 'Test01' in ''.join(output)
86 # need to run uefi command to initiate capsule handling
87 output = u_boot_console.run_command(
88 'env print -e Capsule0000')
90 output = u_boot_console.run_command_list([
91 'host bind 0 %s' % disk_img,
92 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
93 assert 'Test01' in ''.join(output)
95 output = u_boot_console.run_command_list([
97 'sf read 4000000 100000 10',
99 assert 'u-boot:Old' in ''.join(output)
101 output = u_boot_console.run_command_list([
102 'sf read 4000000 150000 10',
104 assert 'u-boot-env:Old' in ''.join(output)
106 def test_efi_capsule_fw2(
107 self, u_boot_config, u_boot_console, efi_capsule_data):
109 Test Case 2 - Update U-Boot and U-Boot environment on SPI Flash
110 0x100000-0x150000: U-Boot binary (but dummy)
111 0x150000-0x200000: U-Boot environment (but dummy)
113 disk_img = efi_capsule_data
114 with u_boot_console.log.section('Test Case 2-a, before reboot'):
115 output = u_boot_console.run_command_list([
116 'host bind 0 %s' % disk_img,
117 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
118 'efidebug boot order 1',
119 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
120 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
123 # initialize contents
124 output = u_boot_console.run_command_list([
126 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
127 'sf write 4000000 100000 10',
128 'sf read 5000000 100000 10',
130 assert 'Old' in ''.join(output)
131 output = u_boot_console.run_command_list([
133 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR,
134 'sf write 4000000 150000 10',
135 'sf read 5000000 150000 10',
137 assert 'Old' in ''.join(output)
139 # place a capsule file
140 output = u_boot_console.run_command_list([
141 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR,
142 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR,
143 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
144 assert 'Test01' in ''.join(output)
146 capsule_early = u_boot_config.buildconfig.get(
147 'config_efi_capsule_on_disk_early')
148 capsule_auth = u_boot_config.buildconfig.get(
149 'config_efi_capsule_authenticate')
152 u_boot_console.restart_uboot(expect_reset = capsule_early)
154 with u_boot_console.log.section('Test Case 2-b, after reboot'):
155 if not capsule_early:
156 # make sure that dfu_alt_info exists even persistent variables
158 output = u_boot_console.run_command_list([
159 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
160 'host bind 0 %s' % disk_img,
161 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
162 assert 'Test01' in ''.join(output)
164 # need to run uefi command to initiate capsule handling
165 output = u_boot_console.run_command(
166 'env print -e Capsule0000', wait_for_reboot = True)
168 output = u_boot_console.run_command_list([
169 'host bind 0 %s' % disk_img,
170 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
171 assert 'Test01' not in ''.join(output)
173 output = u_boot_console.run_command_list([
175 'sf read 4000000 100000 10',
178 assert 'u-boot:Old' in ''.join(output)
180 assert 'u-boot:New' in ''.join(output)
182 output = u_boot_console.run_command_list([
183 'sf read 4000000 150000 10',
186 assert 'u-boot-env:Old' in ''.join(output)
188 assert 'u-boot-env:New' in ''.join(output)
190 def test_efi_capsule_fw3(
191 self, u_boot_config, u_boot_console, efi_capsule_data):
193 Test Case 3 - Update U-Boot on SPI Flash, raw image format
194 0x100000-0x150000: U-Boot binary (but dummy)
196 disk_img = efi_capsule_data
197 with u_boot_console.log.section('Test Case 3-a, before reboot'):
198 output = u_boot_console.run_command_list([
199 'host bind 0 %s' % disk_img,
200 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
201 'efidebug boot order 1',
202 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
203 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
207 output = u_boot_console.run_command_list([
209 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
210 'sf write 4000000 100000 10',
211 'sf read 5000000 100000 10',
213 assert 'Old' in ''.join(output)
215 # place a capsule file
216 output = u_boot_console.run_command_list([
217 'fatload host 0:1 4000000 %s/Test02' % CAPSULE_DATA_DIR,
218 'fatwrite host 0:1 4000000 %s/Test02 $filesize' % CAPSULE_INSTALL_DIR,
219 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
220 assert 'Test02' in ''.join(output)
222 capsule_early = u_boot_config.buildconfig.get(
223 'config_efi_capsule_on_disk_early')
224 capsule_auth = u_boot_config.buildconfig.get(
225 'config_efi_capsule_authenticate')
228 u_boot_console.restart_uboot(expect_reset = capsule_early)
230 with u_boot_console.log.section('Test Case 3-b, after reboot'):
231 if not capsule_early:
232 # make sure that dfu_alt_info exists even persistent variables
234 output = u_boot_console.run_command_list([
235 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
236 'host bind 0 %s' % disk_img,
237 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
238 assert 'Test02' in ''.join(output)
240 # need to run uefi command to initiate capsule handling
241 output = u_boot_console.run_command(
242 'env print -e Capsule0000', wait_for_reboot = True)
244 # make sure the dfu_alt_info exists because it is required for making ESRT.
245 output = u_boot_console.run_command_list([
246 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
247 'efidebug capsule esrt'])
249 # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID is in the ESRT.
250 assert 'AE13FF2D-9AD4-4E25-9AC8-6D80B3B22147' in ''.join(output)
252 # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT.
253 assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output)
255 output = u_boot_console.run_command_list([
256 'host bind 0 %s' % disk_img,
257 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
258 assert 'Test02' not in ''.join(output)
260 output = u_boot_console.run_command_list([
262 'sf read 4000000 100000 10',
265 assert 'u-boot:Old' in ''.join(output)
267 assert 'u-boot:New' in ''.join(output)
269 def test_efi_capsule_fw4(
270 self, u_boot_config, u_boot_console, efi_capsule_data):
272 Test Case 4 - Test "--guid" option of mkeficapsule
273 The test scenario is the same as Case 3.
275 disk_img = efi_capsule_data
276 with u_boot_console.log.section('Test Case 4-a, before reboot'):
277 output = u_boot_console.run_command_list([
278 'host bind 0 %s' % disk_img,
279 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
280 'efidebug boot order 1',
281 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
282 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
286 output = u_boot_console.run_command_list([
288 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
289 'sf write 4000000 100000 10',
290 'sf read 5000000 100000 10',
292 assert 'Old' in ''.join(output)
294 # place a capsule file
295 output = u_boot_console.run_command_list([
296 'fatload host 0:1 4000000 %s/Test03' % CAPSULE_DATA_DIR,
297 'fatwrite host 0:1 4000000 %s/Test03 $filesize' % CAPSULE_INSTALL_DIR,
298 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
299 assert 'Test03' in ''.join(output)
301 capsule_early = u_boot_config.buildconfig.get(
302 'config_efi_capsule_on_disk_early')
303 capsule_auth = u_boot_config.buildconfig.get(
304 'config_efi_capsule_authenticate')
307 u_boot_console.restart_uboot(expect_reset = capsule_early)
309 with u_boot_console.log.section('Test Case 4-b, after reboot'):
310 if not capsule_early:
311 # make sure that dfu_alt_info exists even persistent variables
313 output = u_boot_console.run_command_list([
314 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
315 'host bind 0 %s' % disk_img,
316 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
317 assert 'Test03' in ''.join(output)
319 # need to run uefi command to initiate capsule handling
320 output = u_boot_console.run_command(
321 'env print -e Capsule0000', wait_for_reboot = True)
323 # make sure the dfu_alt_info exists because it is required for making ESRT.
324 output = u_boot_console.run_command_list([
325 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
326 'efidebug capsule esrt'])
328 # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT.
329 assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output)
331 output = u_boot_console.run_command_list([
332 'host bind 0 %s' % disk_img,
333 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
334 assert 'Test03' not in ''.join(output)
336 output = u_boot_console.run_command_list([
338 'sf read 4000000 100000 10',
341 assert 'u-boot:Old' in ''.join(output)
343 assert 'u-boot:New' in ''.join(output)