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