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  &  0x1 :
152+             digest  =  hashlib .sha256 (entry_data ).digest ()
153+         elif  header .boot_flag  &  0x2 :
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,15 @@ 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+             return  header , get_newidblock_entries 
183+     return  None , None 
155184
156185
157186class  RKUSBMaskrom :
@@ -209,14 +238,14 @@ def load(self, code, bytesOrPath):
209238def  handle_load (busnum , devnum , initial , secondary = None , delay = None ):
210239    with  open (initial , 'rb' ) as  f :
211240        data  =  f .read ()
212-     header   =   parse_rkboot_header (data )
241+     header ,  get_image_entries   =   parse_image_header (data )
213242    if  header  is  None  and  secondary  is  not None :
214243        with  open (secondary , 'rb' ) as  f :
215244            data  =  f .read ()
216-         header   =   parse_rkboot_header (data )
245+         header ,  get_image_entries   =   parse_image_header (data )
217246    with  RKUSBMaskrom (bus = busnum , address = devnum ) as  maskrom :
218247        if  header  is  not None :
219-             for  code , entry_data , entry_delay  in  get_rkboot_entries (data , header ):
248+             for  code , entry_data , entry_delay  in  get_image_entries (data , header ,  delay ):
220249                maskrom .load (code , entry_data )
221250                if  entry_delay :
222251                    sleep (entry_delay )
0 commit comments