Skip to content

Commit 316a139

Browse files
rustammendeldavidvincze
authored andcommitted
imgtool: dumpinfo improvements
Fix trailer info dumping reads pad characters as values for status Refactor printing styled texts and frames Use isinstance() for type checking Fold notice text depending on line length Refactoring some parts for readability Fix additional linting issues Signed-off-by: Rustam Ismayilov <[email protected]> Change-Id: I741562bb70b18407bdd32e9c7391048faf6394c6
1 parent f3a5702 commit 316a139

File tree

1 file changed

+102
-74
lines changed

1 file changed

+102
-74
lines changed

scripts/imgtool/dumpinfo.py

Lines changed: 102 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
"""
1818
Parse and print header, TLV area and trailer information of a signed image.
1919
"""
20-
from imgtool import image
21-
import click
22-
import struct
23-
import yaml
2420
import os.path
21+
import struct
2522
import sys
2623

24+
import click
25+
import yaml
26+
27+
from imgtool import image
28+
2729
HEADER_ITEMS = ("magic", "load_addr", "hdr_size", "protected_tlv_size",
2830
"img_size", "flags", "version")
2931
TLV_TYPES = dict((value, key) for key, value in image.TLV_VALUES.items())
@@ -39,6 +41,59 @@
3941
0x1f, 0x8a, ])
4042
BOOT_MAGIC_SIZE = len(BOOT_MAGIC)
4143
_LINE_LENGTH = 60
44+
STATUS = {
45+
'0x1': 'SET',
46+
'0x2': 'BAD',
47+
'0x3': 'UNSET',
48+
'0x4': 'ANY',
49+
}
50+
51+
52+
def parse_enc(key_field_len):
53+
if key_field_len is not None:
54+
return "(len: {}, if BOOT_SWAP_SAVE_ENCTLV is unset)".format(hex(key_field_len))
55+
else:
56+
return "Image not encrypted"
57+
58+
59+
def parse_size(size_hex):
60+
if size_hex == '0xffffffff':
61+
return "unknown"
62+
return size_hex + " octal: " + str(int(size_hex, 0))
63+
64+
65+
def parse_status(status_hex):
66+
return f"{STATUS[status_hex]} ({status_hex})" if status_hex in STATUS else f"INVALID ({status_hex})"
67+
68+
69+
def parse_boot_magic(trailer_magic):
70+
magic = ""
71+
for i in range(BOOT_MAGIC_SIZE):
72+
magic += "{0:#04x} ".format(trailer_magic[i])
73+
if i == (BOOT_MAGIC_SIZE / 2 - 1):
74+
magic += ("\n" + " ")
75+
return magic
76+
77+
78+
def print_in_frame(header_text, content):
79+
sepc = " "
80+
header = "#### " + header_text + sepc
81+
post_header = "#" * (_LINE_LENGTH - len(header))
82+
print(header + post_header)
83+
84+
print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
85+
offset = (_LINE_LENGTH - len(content)) // 2
86+
pre = "|" + (sepc * (offset - 1))
87+
post = sepc * (_LINE_LENGTH - len(pre) - len(content) - 1) + "|"
88+
print(pre, content, post, sep="")
89+
print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
90+
print("#" * _LINE_LENGTH)
91+
92+
93+
def print_in_row(row_text):
94+
row_text = "#### " + row_text + " "
95+
fill = "#" * (_LINE_LENGTH - len(row_text))
96+
print(row_text + fill)
4297

4398

4499
def print_tlv_records(tlv_list):
@@ -66,10 +121,11 @@ def print_tlv_records(tlv_list):
66121
def dump_imginfo(imgfile, outfile=None, silent=False):
67122
"""Parse a signed image binary and print/save the available information."""
68123
trailer_magic = None
69-
swap_size = 0
70-
swap_info = 0
71-
copy_done = 0
72-
image_ok = 0
124+
# set to INVALID by default
125+
swap_size = 0x99
126+
swap_info = 0x99
127+
copy_done = 0x99
128+
image_ok = 0x99
73129
trailer = {}
74130
key_field_len = None
75131

@@ -92,16 +148,16 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
92148

93149
# Parsing the TLV area
94150
tlv_area = {"tlv_hdr_prot": {},
95-
"tlvs_prot": [],
96-
"tlv_hdr": {},
97-
"tlvs": []}
151+
"tlvs_prot": [],
152+
"tlv_hdr": {},
153+
"tlvs": []}
98154
tlv_off = header["hdr_size"] + header["img_size"]
99155
protected_tlv_size = header["protected_tlv_size"]
100156

101157
if protected_tlv_size != 0:
102158
_tlv_prot_head = struct.unpack(
103-
'HH',
104-
b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
159+
'HH',
160+
b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
105161
tlv_area["tlv_hdr_prot"]["magic"] = _tlv_prot_head[0]
106162
tlv_area["tlv_hdr_prot"]["tlv_tot"] = _tlv_prot_head[1]
107163
tlv_end = tlv_off + tlv_area["tlv_hdr_prot"]["tlv_tot"]
@@ -110,8 +166,8 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
110166
# Iterating through the protected TLV area
111167
while tlv_off < tlv_end:
112168
tlv_type, tlv_len = struct.unpack(
113-
'HH',
114-
b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
169+
'HH',
170+
b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
115171
tlv_off += image.TLV_INFO_SIZE
116172
tlv_data = b[tlv_off:(tlv_off + tlv_len)]
117173
tlv_area["tlvs_prot"].append(
@@ -128,8 +184,8 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
128184
# Iterating through the TLV area
129185
while tlv_off < tlv_end:
130186
tlv_type, tlv_len = struct.unpack(
131-
'HH',
132-
b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
187+
'HH',
188+
b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
133189
tlv_off += image.TLV_INFO_SIZE
134190
tlv_data = b[tlv_off:(tlv_off + tlv_len)]
135191
tlv_area["tlvs"].append(
@@ -177,7 +233,7 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
177233

178234
# Encryption key 0/1
179235
if ((header["flags"] & image.IMAGE_F["ENCRYPTED_AES128"]) or
180-
(header["flags"] & image.IMAGE_F["ENCRYPTED_AES256"])):
236+
(header["flags"] & image.IMAGE_F["ENCRYPTED_AES256"])):
181237
# The image is encrypted
182238
# Estimated value of key_field_len is correct if
183239
# BOOT_SWAP_SAVE_ENCTLV is unset
@@ -192,17 +248,16 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
192248
# sort_keys - from pyyaml 5.1
193249
yaml.dump(imgdata, outf, sort_keys=False)
194250

195-
###############################################################################
251+
###############################################################################
196252

197253
if silent:
198254
sys.exit(0)
199255

200256
print("Printing content of signed image:", os.path.basename(imgfile), "\n")
201257

202258
# Image header
203-
str1 = "#### Image header (offset: 0x0) "
204-
str2 = "#" * (_LINE_LENGTH - len(str1))
205-
print(str1 + str2)
259+
section_name = "Image header (offset: 0x0)"
260+
print_in_row(section_name)
206261
for key, value in header.items():
207262
if key == "flags":
208263
if not value:
@@ -214,45 +269,34 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
214269
if flag_string:
215270
flag_string += ("\n" + (" " * 20))
216271
flag_string += "{} ({})".format(
217-
flag, hex(image.IMAGE_F[flag]))
272+
flag, hex(image.IMAGE_F[flag]))
218273
value = flag_string
219274

220-
if type(value) != str:
275+
if not isinstance(value, str):
221276
value = hex(value)
222277
print(key, ":", " " * (19 - len(key)), value, sep="")
223278
print("#" * _LINE_LENGTH)
224279

225280
# Image payload
226281
_sectionoff = header["hdr_size"]
227-
sepc = " "
228-
str1 = "#### Payload (offset: {}) ".format(hex(_sectionoff))
229-
str2 = "#" * (_LINE_LENGTH - len(str1))
230-
print(str1 + str2)
231-
print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
232-
str1 = "FW image (size: {} Bytes)".format(hex(header["img_size"]))
233-
numc = (_LINE_LENGTH - len(str1)) // 2
234-
str2 = "|" + (sepc * (numc - 1))
235-
str3 = sepc * (_LINE_LENGTH - len(str2) - len(str1) - 1) + "|"
236-
print(str2, str1, str3, sep="")
237-
print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
238-
print("#" * _LINE_LENGTH)
282+
frame_header_text = "Payload (offset: {})".format(hex(_sectionoff))
283+
frame_content = "FW image (size: {} Bytes)".format(hex(header["img_size"]))
284+
print_in_frame(frame_header_text, frame_content)
239285

240286
# TLV area
241287
_sectionoff += header["img_size"]
242288
if protected_tlv_size != 0:
243289
# Protected TLV area
244-
str1 = "#### Protected TLV area (offset: {}) ".format(hex(_sectionoff))
245-
str2 = "#" * (_LINE_LENGTH - len(str1))
246-
print(str1 + str2)
290+
section_name = "Protected TLV area (offset: {})".format(hex(_sectionoff))
291+
print_in_row(section_name)
247292
print("magic: ", hex(tlv_area["tlv_hdr_prot"]["magic"]))
248293
print("area size:", hex(tlv_area["tlv_hdr_prot"]["tlv_tot"]))
249294
print_tlv_records(tlv_area["tlvs_prot"])
250295
print("#" * _LINE_LENGTH)
251296

252297
_sectionoff += protected_tlv_size
253-
str1 = "#### TLV area (offset: {}) ".format(hex(_sectionoff))
254-
str2 = "#" * (_LINE_LENGTH - len(str1))
255-
print(str1 + str2)
298+
section_name = "TLV area (offset: {})".format(hex(_sectionoff))
299+
print_in_row(section_name)
256300
print("magic: ", hex(tlv_area["tlv_hdr"]["magic"]))
257301
print("area size:", hex(tlv_area["tlv_hdr"]["tlv_tot"]))
258302
print_tlv_records(tlv_area["tlvs"])
@@ -261,40 +305,24 @@ def dump_imginfo(imgfile, outfile=None, silent=False):
261305
if _img_pad_size:
262306
_sectionoff += tlv_area["tlv_hdr"]["tlv_tot"]
263307
_erased_val = b[_sectionoff]
264-
str1 = "#### Image padding (offset: {}) ".format(hex(_sectionoff))
265-
str2 = "#" * (_LINE_LENGTH - len(str1))
266-
print(str1 + str2)
267-
print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
268-
str1 = "padding ({})".format(hex(_erased_val))
269-
numc = (_LINE_LENGTH - len(str1)) // 2
270-
str2 = "|" + (sepc * (numc - 1))
271-
str3 = sepc * (_LINE_LENGTH - len(str2) - len(str1) - 1) + "|"
272-
print(str2, str1, str3, sep="")
273-
print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
274-
print("#" * _LINE_LENGTH)
308+
frame_header_text = "Image padding (offset: {})".format(hex(_sectionoff))
309+
frame_content = "padding ({})".format(hex(_erased_val))
310+
print_in_frame(frame_header_text, frame_content)
275311

276312
# Image trailer
277-
str1 = "#### Image trailer (offset: unknown) "
278-
str2 = "#" * (_LINE_LENGTH - len(str1))
279-
print(str1 + str2)
280-
print("(Note: some field may not be used, \n"
281-
" depending on the update strategy)\n")
282-
313+
section_name = "Image trailer (offset: unknown)"
314+
print_in_row(section_name)
315+
notice = "(Note: some fields may not be used, depending on the update strategy)\n"
316+
notice = '\n'.join(notice[i:i + _LINE_LENGTH] for i in range(0, len(notice), _LINE_LENGTH))
317+
print(notice)
283318
print("swap status: (len: unknown)")
284-
if key_field_len is not None:
285-
print("enc. keys: (len: {}, if BOOT_SWAP_SAVE_ENCTLV is unset)"
286-
.format(hex(key_field_len)))
287-
print("swap size: ", hex(swap_size))
288-
print("swap_info: ", hex(swap_info))
289-
print("copy_done: ", hex(copy_done))
290-
print("image_ok: ", hex(image_ok))
291-
print("boot magic: ", end="")
292-
for i in range(BOOT_MAGIC_SIZE):
293-
print("{0:#04x}".format(trailer_magic[i]), end=" ")
294-
if i == (BOOT_MAGIC_SIZE / 2 - 1):
295-
print("\n", end=" ")
319+
print("enc. keys: ", parse_enc(key_field_len))
320+
print("swap size: ", parse_size(hex(swap_size)))
321+
print("swap_info: ", parse_status(hex(swap_info)))
322+
print("copy_done: ", parse_status(hex(copy_done)))
323+
print("image_ok: ", parse_status(hex(image_ok)))
324+
print("boot magic: ", parse_boot_magic(trailer_magic))
296325
print()
297326

298-
str1 = "#### End of Image "
299-
str2 = "#" * (_LINE_LENGTH - len(str1))
300-
print(str1 + str2)
327+
footer = "End of Image "
328+
print_in_row(footer)

0 commit comments

Comments
 (0)