Skip to content

Commit 2d0a61a

Browse files
committed
RKUSBMaskromDriver: add support for using vendor idblock v2 images
Add support for using vendor idblock v2 image files, typically created using the U-Boot mkimage tool. Signed-off-by: Jonas Karlman <[email protected]>
1 parent 028ff1e commit 2d0a61a

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

labgrid/util/agents/rkusbmaskrom.py

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
that typically initializes DRAM, followed by optionally loading a secondary
44
image to start of DRAM, when a Rockchip device is in MASKROM mode.
55
"""
6+
import hashlib
67
from collections import namedtuple
78
from struct import unpack
89
from time import sleep
@@ -124,7 +125,7 @@ def rc4_prga(S):
124125
yield K
125126

126127

127-
def get_rkboot_entries(data, header):
128+
def get_rkboot_entries(data, header, _):
128129
RKBootEntry = namedtuple('RKBootEntry', [
129130
'size', 'type', 'dataOffset', 'dataSize', 'dataDelay',
130131
])
@@ -139,7 +140,26 @@ def get_rkboot_entries(data, header):
139140
offset += size
140141

141142

142-
def parse_rkboot_header(data):
143+
def get_newidblock_entries(data, header, delay):
144+
RKImageEntry = namedtuple('RKImageEntry', [
145+
'offset', 'size', 'address', 'flag', 'counter', 'digest'
146+
])
147+
offset, size = 120, 88
148+
for _ in range(header.num_images):
149+
entry = RKImageEntry._make(unpack('<HHLLL8x64s', data[offset:offset + size]))
150+
entry_data = data[entry.offset * 512:(entry.offset + entry.size) * 512]
151+
if header.boot_flag & 0x1:
152+
digest = hashlib.sha256(entry_data).digest()
153+
elif header.boot_flag & 0x2:
154+
digest = hashlib.sha512(entry_data).digest()
155+
if header.boot_flag & 0x3 and digest != entry.digest[:len(digest)]:
156+
raise ValueError(f"Digest mismatch for image {entry.counter}")
157+
code = 0x472 if entry.counter == header.num_images else 0x471
158+
yield code, entry_data, delay if code == 0x471 else 0
159+
offset += size
160+
161+
162+
def parse_image_header(data):
143163
tag = int.from_bytes(data[:4], 'little')
144164
RKBootHeader = namedtuple('RKBootHeader', [
145165
'tag', 'size', 'version', 'mergerVersion',
@@ -150,8 +170,15 @@ def parse_rkboot_header(data):
150170
crc32_rkboot(data[:-4]) == int.from_bytes(data[-4:], 'little'):
151171
header = RKBootHeader._make(unpack('<LHLL11xBLBBLB65x', data[:102]))
152172
if header.size == 102 and header.code471Num + header.code472Num > 0:
153-
return header
154-
return None
173+
return header, get_rkboot_entries
174+
RKNewIDBlockHeader = namedtuple('RKNewIDBlockHeader', [
175+
'tag', 'size', 'num_images', 'boot_flag',
176+
])
177+
if tag in (0x534e4b52, 0x53534b52):
178+
header = RKNewIDBlockHeader._make(unpack('<L4xHHL', data[:16]))
179+
if header.size == 384 and header.num_images > 0:
180+
return header, get_newidblock_entries
181+
return None, None
155182

156183

157184
class RKUSBMaskrom:
@@ -209,14 +236,14 @@ def load(self, code, bytesOrPath):
209236
def handle_load(busnum, devnum, initial, secondary=None, delay=None):
210237
with open(initial, 'rb') as f:
211238
data = f.read()
212-
header = parse_rkboot_header(data)
239+
header, get_image_entries = parse_image_header(data)
213240
if header is None and secondary is not None:
214241
with open(secondary, 'rb') as f:
215242
data = f.read()
216-
header = parse_rkboot_header(data)
243+
header, get_image_entries = parse_image_header(data)
217244
with RKUSBMaskrom(bus=busnum, address=devnum) as maskrom:
218245
if header is not None:
219-
for code, entry_data, entry_delay in get_rkboot_entries(data, header):
246+
for code, entry_data, entry_delay in get_image_entries(data, header, delay):
220247
maskrom.load(code, entry_data)
221248
if entry_delay:
222249
sleep(entry_delay)

0 commit comments

Comments
 (0)