2018-04-19 09:42:26 +05:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								#!/usr/bin/env python 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# parttool returns info about the required partition. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# This utility is used by the make system to get information  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# about the start addresses: partition table, factory area, phy area. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# Copyright 2018 Espressif Systems (Shanghai) PTE LTD 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# Licensed under the Apache License, Version 2.0 (the "License"); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# you may not use this file except in compliance with the License. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# You may obtain a copy of the License at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#     http:#www.apache.org/licenses/LICENSE-2.0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# Unless required by applicable law or agreed to in writing, software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# distributed under the License is distributed on an "AS IS" BASIS, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# See the License for the specific language governing permissions and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# limitations under the License. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								from  __future__  import  print_function ,  division 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  argparse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  os 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  re 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  sys 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  hashlib 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  binascii 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  gen_esp32part  as  gen 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								__version__  =  ' 1.0 ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								quiet  =  False 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def  status ( msg ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    """  Print status message to stderr  """ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  quiet : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        critical ( msg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def  critical ( msg ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    """  Print critical message to stderr  """ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  not  quiet : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sys . stderr . write ( msg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sys . stderr . write ( ' \n ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								               
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								def  main ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    global  quiet 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    parser  =  argparse . ArgumentParser ( description = ' Returns info about the required partition. ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    parser . add_argument ( ' --quiet ' ,  ' -q ' ,  help = " Don ' t print status messages to stderr " ,  action = ' store_true ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-22 11:14:22 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-20 18:24:18 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    parser . add_argument ( ' --partition-table-offset ' ,  help = ' The offset of the partition table in flash. Only consulted if partition table is in CSV format. ' ,  type = str ,  default = ' 0x8000 ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-22 11:14:22 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    search_type  =  parser . add_mutually_exclusive_group ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    search_type . add_argument ( ' --partition-name ' ,  ' -p ' ,  help = ' The name of the required partition ' ,  type = str ,  default = None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    search_type . add_argument ( ' --type ' ,  ' -t ' ,  help = ' The type of the required partition ' ,  type = str ,  default = None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    search_type . add_argument ( ' --default-boot-partition ' ,  help = ' Select the default boot partition,  ' + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                             ' using the same fallback logic as the IDF bootloader ' ,  action = " store_true " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-19 09:42:26 +05:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    parser . add_argument ( ' --subtype ' ,  ' -s ' ,  help = ' The subtype of the required partition ' ,  type = str ,  default = None ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-22 11:14:22 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    parser . add_argument ( ' --offset ' ,  ' -o ' ,  help = ' Return offset of required partition ' ,  action = " store_true " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    parser . add_argument ( ' --size ' ,  help = ' Return size of required partition ' ,  action = " store_true " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    parser . add_argument ( ' input ' ,  help = ' Path to CSV or binary file to parse. Will use stdin if omitted. ' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        type = argparse . FileType ( ' rb ' ) ,  default = sys . stdin ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-19 09:42:26 +05:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    args  =  parser . parse_args ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-22 11:14:22 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  args . type  is  not  None  and  args . subtype  is  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        status ( " If --type is specified, --subtype is required " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  args . type  is  None  and  args . subtype  is  not  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        status ( " --subtype is only used with --type " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-19 09:42:26 +05:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    quiet  =  args . quiet 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-20 18:24:18 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    gen . offset_part_table  =  int ( args . partition_table_offset ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-19 09:42:26 +05:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    input  =  args . input . read ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    input_is_binary  =  input [ 0 : 2 ]  ==  gen . PartitionDefinition . MAGIC_BYTES 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  input_is_binary : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        status ( " Parsing binary partition input... " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        table  =  gen . PartitionTable . from_binary ( input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        input  =  input . decode ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        status ( " Parsing CSV input... " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        table  =  gen . PartitionTable . from_csv ( input ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-06-22 11:14:22 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    found_partition  =  None 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  args . default_boot_partition : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        search  =  [  " factory "  ]  +  [  " ota_ %d "  %  d  for  d  in  range ( 16 )  ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        for  subtype  in  search : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            found_partition  =  table . find_by_type ( " app " ,  subtype ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  found_partition  is  not  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif  args . partition_name  is  not  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        found_partition  =  table . find_by_name ( args . partition_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    elif  args . type  is  not  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        found_partition  =  table . find_by_type ( args . type ,  args . subtype ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        raise  RuntimeError ( " invalid partition selection choice " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  found_partition  is  None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  1   # nothing found 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  args . offset : 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-18 15:10:03 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        print ( ' 0x %x '  %  ( found_partition . offset ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-22 11:14:22 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  args . size : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        print ( ' 0x %x '  %  ( found_partition . size ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-19 09:42:26 +05:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								class  InputError ( RuntimeError ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    def  __init__ ( self ,  e ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        super ( InputError ,  self ) . __init__ ( e ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								class  ValidationError ( InputError ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    def  __init__ ( self ,  partition ,  message ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        super ( ValidationError ,  self ) . __init__ ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " Partition  %s  invalid:  %s "  %  ( partition . name ,  message ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								if  __name__  ==  ' __main__ ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try : 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-22 11:14:22 +10:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        r  =  main ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sys . exit ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-19 09:42:26 +05:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    except  InputError  as  e : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        print ( e ,  file = sys . stderr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sys . exit ( 2 )