Skip to content

Commit 13e2cf7

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 or Barebox rkimage tools. Signed-off-by: Jonas Karlman <[email protected]>
1 parent 8401742 commit 13e2cf7

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

doc/configuration.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2680,7 +2680,8 @@ Arguments:
26802680
of an image that typically initializes DRAM of the target
26812681
- image (str): optional, key in :ref:`images <labgrid-device-config-images>` containing the path
26822682
of a bootloader image to load to start of DRAM, or to SRAM when an initial image is unused, or
2683-
the path to a vendor loader image typically created using the vendor boot_merger tool
2683+
the path to a vendor loader image typically created using the vendor boot_merger tool, or the
2684+
path to an idblock image typically created using the U-Boot mkimage or Barebox rkimage tools
26842685
- delay (float, default=0.001): delay in seconds between loading initial and secondary image
26852686

26862687
UUUDriver

labgrid/util/agents/rkusbmaskrom.py

Lines changed: 45 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,28 @@ 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 & 0xf) == 1:
152+
digest = hashlib.sha256(entry_data).digest()
153+
elif (header.boot_flag & 0xf) == 2:
154+
digest = hashlib.sha512(entry_data).digest()
155+
else:
156+
digest = None
157+
if digest is not None and digest != entry.digest[:len(digest)]:
158+
raise ValueError(f"Digest mismatch for image {entry.counter}")
159+
code = 0x472 if entry.counter == header.num_images else 0x471
160+
yield code, entry_data, delay if code == 0x471 else 0
161+
offset += size
162+
163+
164+
def parse_image_header(data):
143165
tag = int.from_bytes(data[:4], 'little')
144166
RKBootHeader = namedtuple('RKBootHeader', [
145167
'tag', 'size', 'version', 'mergerVersion',
@@ -150,8 +172,24 @@ def parse_rkboot_header(data):
150172
crc32_rkboot(data[:-4]) == int.from_bytes(data[-4:], 'little'):
151173
header = RKBootHeader._make(unpack('<LHLL11xBLBBLB65x', data[:102]))
152174
if header.size == 102 and header.code471Num + header.code472Num > 0:
153-
return header
154-
return None
175+
return header, get_rkboot_entries
176+
RKNewIDBlockHeader = namedtuple('RKNewIDBlockHeader', [
177+
'tag', 'size', 'num_images', 'boot_flag',
178+
])
179+
if tag in (0x534e4b52, 0x53534b52):
180+
header = RKNewIDBlockHeader._make(unpack('<L4xHHL', data[:16]))
181+
if header.size == 384 and header.num_images > 0:
182+
if (header.boot_flag & 0xf) == 1:
183+
digest = hashlib.sha256(data[:1536]).digest()
184+
elif (header.boot_flag & 0xf) == 2:
185+
digest = hashlib.sha512(data[:1536]).digest()
186+
else:
187+
digest = None
188+
if (header.boot_flag & 0xf0) == 0 and digest is not None and \
189+
digest != data[1536:1536 + len(digest)]:
190+
raise ValueError("Digest mismatch for header")
191+
return header, get_newidblock_entries
192+
return None, None
155193

156194

157195
class RKUSBMaskrom:
@@ -209,14 +247,14 @@ def load(self, code, bytesOrPath):
209247
def handle_load(busnum, devnum, initial, secondary=None, delay=None):
210248
with open(initial, 'rb') as f:
211249
data = f.read()
212-
header = parse_rkboot_header(data)
250+
header, get_image_entries = parse_image_header(data)
213251
if header is None and secondary is not None:
214252
with open(secondary, 'rb') as f:
215253
data = f.read()
216-
header = parse_rkboot_header(data)
254+
header, get_image_entries = parse_image_header(data)
217255
with RKUSBMaskrom(bus=busnum, address=devnum) as maskrom:
218256
if header is not None:
219-
for code, entry_data, entry_delay in get_rkboot_entries(data, header):
257+
for code, entry_data, entry_delay in get_image_entries(data, header, delay):
220258
maskrom.load(code, entry_data)
221259
if entry_delay:
222260
sleep(entry_delay)

0 commit comments

Comments
 (0)