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,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
157195class RKUSBMaskrom :
@@ -209,14 +247,14 @@ def load(self, code, bytesOrPath):
209247def 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