33that typically initializes DRAM, followed by optionally loading a secondary
44image to start of DRAM, when a Rockchip device is in MASKROM mode.
55"""
6+ import hashlib
67from collections import namedtuple
78from struct import unpack
89from 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
157184class RKUSBMaskrom :
@@ -209,14 +236,14 @@ def load(self, code, bytesOrPath):
209236def 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