blob: 43a7099c4660684799a09b98d815c751b85f892a [file] [log] [blame]
Sam Protsenko61c72ea2020-01-24 17:53:45 +02001# SPDX-License-Identifier: GPL-2.0+
2# Copyright (c) 2020
3# Author: Sam Protsenko <joe.skb7@gmail.com>
4
5# Test U-Boot's "abootimg" commands.
6
7import os
8import pytest
9import u_boot_utils
10
11"""
12These tests rely on disk image (boot.img), which is automatically created by
13the test from the stored hex dump. This is done to avoid the dependency on the
14most recent mkbootimg tool from AOSP/master. Here is the list of commands which
15was used to generate the boot.img and obtain compressed hex dump from it:
16
17 $ echo '/dts-v1/; / { model = "x1"; compatible = "y1,z1"; };' > test1.dts
18 $ echo '/dts-v1/; / { model = "x2"; compatible = "y2,z2"; };' > test2.dts
19 $ dtc test1.dts > dt1.dtb
20 $ dtc test2.dts > dt2.dtb
21 $ cat dt1.dtb dt2.dtb > dtb.img
22 $ echo 'kernel payload' > kernel
23 $ echo 'ramdisk payload' > ramdisk.img
24 $ mkbootimg --kernel ./kernel --ramdisk ./ramdisk.img \
25 --cmdline "cmdline test" --dtb ./dtb.img \
26 --os_version R --os_patch_level 2019-06-05 \
27 --header_version 2 --output boot.img
28 $ gzip -9 boot.img
29 $ xxd -p boot.img.gz > boot.img.gz.hex
30
31Now one can obtain original boot.img from this hex dump like this:
32
33 $ xxd -r -p boot.img.gz.hex boot.img.gz
34 $ gunzip -9 boot.img.gz
35"""
36
37# boot.img.gz hex dump
38img_hex = """1f8b08084844af5d0203626f6f742e696d670073f47309f2f77451e46700
39820606010106301084501f04181819041838181898803c3346060c909c9b
4092939997aa50925a5cc2300a461c3078b2e1793c4b876fd92db97939fb6c
41b7762ffff07d345446c1281805e8a0868d81e117a45e111c0d8dc101b253
428bf25273140a122b73f21353b8460364148c8251300a46c1281801a02831
433725b3387bb401300a46c1281805a360148c207081f7df5b20550bc41640
449c03c41a0c90f17fe85400986d82452b6c3680198a192a0ce17c3610ae34
45d4a9820881a70f3873f35352731892f3730b124b32937252a96bb9119ae5
46463a5546f82c1f05a360148c8251300a462e000085bf67f200200000"""
47# Expected response for "abootimg dtb_dump" command
48dtb_dump_resp="""## DTB area contents (concat format):
49 - DTB #0:
50 (DTB)size = 125
51 (DTB)model = x1
52 (DTB)compatible = y1,z1
53 - DTB #1:
54 (DTB)size = 125
55 (DTB)model = x2
56 (DTB)compatible = y2,z2"""
57# Address in RAM where to load the boot image ('abootimg' looks in $loadaddr)
58loadaddr = 0x1000
59# Expected DTB #1 offset from the boot image start address
60dtb1_offset = 0x187d
61# DTB #1 start address in RAM
62dtb1_addr = loadaddr + dtb1_offset
63
64class AbootimgTestDiskImage(object):
65 """Disk image used by abootimg tests."""
66
67 def __init__(self, u_boot_console):
68 """Initialize a new AbootimgDiskImage object.
69
70 Args:
71 u_boot_console: A U-Boot console.
72
73 Returns:
74 Nothing.
75 """
76
77 gz_hex = u_boot_console.config.persistent_data_dir + '/boot.img.gz.hex'
78 gz = u_boot_console.config.persistent_data_dir + '/boot.img.gz'
79
80 filename = 'boot.img'
81 persistent = u_boot_console.config.persistent_data_dir + '/' + filename
82 self.path = u_boot_console.config.result_dir + '/' + filename
83
84 with u_boot_utils.persistent_file_helper(u_boot_console.log, persistent):
85 if os.path.exists(persistent):
86 u_boot_console.log.action('Disk image file ' + persistent +
87 ' already exists')
88 else:
89 u_boot_console.log.action('Generating ' + persistent)
90
91 f = open(gz_hex, "w")
92 f.write(img_hex)
93 f.close()
94
95 cmd = ('xxd', '-r', '-p', gz_hex, gz)
96 u_boot_utils.run_and_log(u_boot_console, cmd)
97
98 cmd = ('gunzip', '-9', gz)
99 u_boot_utils.run_and_log(u_boot_console, cmd)
100
101 cmd = ('cp', persistent, self.path)
102 u_boot_utils.run_and_log(u_boot_console, cmd)
103
104gtdi = None
105@pytest.fixture(scope='function')
106def abootimg_disk_image(u_boot_console):
107 """pytest fixture to provide a AbootimgTestDiskImage object to tests.
108 This is function-scoped because it uses u_boot_console, which is also
109 function-scoped. However, we don't need to actually do any function-scope
110 work, so this simply returns the same object over and over each time."""
111
112 global gtdi
113 if not gtdi:
114 gtdi = AbootimgTestDiskImage(u_boot_console)
115 return gtdi
116
117@pytest.mark.boardspec('sandbox')
118@pytest.mark.buildconfigspec('android_boot_image')
119@pytest.mark.buildconfigspec('cmd_abootimg')
120@pytest.mark.buildconfigspec('cmd_fdt')
121@pytest.mark.requiredtool('xxd')
122@pytest.mark.requiredtool('gunzip')
123def test_abootimg(abootimg_disk_image, u_boot_console):
124 """Test the 'abootimg' command."""
125
126 u_boot_console.log.action('Loading disk image to RAM...')
127 u_boot_console.run_command('setenv loadaddr 0x%x' % (loadaddr))
128 u_boot_console.run_command('host load hostfs - 0x%x %s' % (loadaddr,
129 abootimg_disk_image.path))
130
131 u_boot_console.log.action('Testing \'abootimg get ver\'...')
132 response = u_boot_console.run_command('abootimg get ver')
133 assert response == "2"
134 u_boot_console.run_command('abootimg get ver v')
135 response = u_boot_console.run_command('env print v')
136 assert response == 'v=2'
137
138 u_boot_console.log.action('Testing \'abootimg get recovery_dtbo\'...')
139 response = u_boot_console.run_command('abootimg get recovery_dtbo a')
140 assert response == 'Error: recovery_dtbo_size is 0'
141
142 u_boot_console.log.action('Testing \'abootimg dump dtb\'...')
143 response = u_boot_console.run_command('abootimg dump dtb').replace('\r', '')
144 assert response == dtb_dump_resp
145
146 u_boot_console.log.action('Testing \'abootimg get dtb_load_addr\'...')
147 u_boot_console.run_command('abootimg get dtb_load_addr a')
148 response = u_boot_console.run_command('env print a')
149 assert response == 'a=11f00000'
150
151 u_boot_console.log.action('Testing \'abootimg get dtb --index\'...')
152 u_boot_console.run_command('abootimg get dtb --index=1 dtb1_start')
153 response = u_boot_console.run_command('env print dtb1_start')
154 correct_str = "dtb1_start=%x" % (dtb1_addr)
155 assert response == correct_str
156 u_boot_console.run_command('fdt addr $dtb1_start')
157 u_boot_console.run_command('fdt get value v / model')
158 response = u_boot_console.run_command('env print v')
159 assert response == 'v=x2'