#!/usr/bin/python
#===========================================================================
# This script parses "partition.xml" and creates numerous output files
# specifically, partition.bin, rawprogram.xml
# REFERENCES
# when who what, where, why
# -------- --- -------------------------------------------------------
# 2015-06-19 as Do not erase CDT.
# 2013-04-01 ah Fixed rawprogram0_BLANK.xml to have correct size on last partition if GROW='true'
# 2012-08-20 ah Allow "uniqueguid" in partition.xml
# 2012-08-16 ah Fixed bug if PERFORMANCE_BOUNDARY_IN_KB wasn't specified
# 2012-08-14 ah PERFORMANCE_BOUNDARY_IN_KB can now be an individual partition tag
# 2012-07-06 ah More user friendly with ShowPartitionExample()
# 2012-04-30 ah GPT Attributes bits corrected
# 2012-02-24 ah Much cleaner code - fixes for configurable sector sizes
# 2012-02-15 ah Minor fix when 'SECTOR_SIZE_IN_BYTES' is not defined
# 2012-01-13 ah Fixed bug where rawprogram.xml was reporting numsectors off by 1
# 2011-11-22 ah Added SECTOR_SIZE_IN_BYTES option (defaults to 512)
# 2011-11-17 ah Added force128 partitions, option -k
# 2011-11-14 ah Enabled zeroout tag for GPT
# 2011-10-19 ah Not allowing empty <physical_partition> tags in partition.xml - makes multiple PHY partitions work
# 2011-09-23 ah GPT num partitions in table not fixed to 128, respecting partition table attributes now
# 2011-08-12 ah Added ALIGN_PARTITIONS_TO_PERFORMANCE_BOUNDARY, WRITE_PROTECT_GPT_PARTITION_TABLE
# 2011-08-11 ah Added Unique GUID option or Sequential -g (default is unique)
# 2011-08-09 ah Fix alignment issue for WPG<64MB - Fixed GPT off by 1 sector issue
# 2011-08-04 ah Now allowing -t option to specify output directory for files
# 2011-07-26 ah Much better error message if GUID invalid, fixed 'grow' partition size (patch)
# 2011-07-21 ah Major revision, using getopt(), auto-discovering GPT or MBR
# 2011-07-13 ah Corrected sparse support
# 2011-06-01 ah Added sparse support for GPT - corrected size of last partition
# 2011-05-26 ah Adds "zeroout" tag (wiping GPT) and "sparse" file support
# 2011-05-21 ab Undoing hack for boot to wipe out sector 1
# 2011-05-17 ah removing GPT sectors is simpler now, compatible with 8960 tz.mbn issue
# 2011-05-06 ah MBR partition tables now nuke any trace of GPT (request from boot team)
# 2011-04-26 ah temporarily removed 'start_byte_hex':szStartByte for QPST compatibility
# 2011-03-23 ah ensured last partition is size 0 for rawprogram.xml
# 2011-03-22 ah rawprogram for GPT for 'grow' partition, since mjsdload.cmm couldn't handle big number
# 2011-03-22 ah Corrected final disk size patch (off by 1 sector), corrected GPT labels (uni-code)
# 2011-03-18 ah Fixed default bug for DISK_SIGNATURE, align_wpb -> align
# 2011-03-16 ah New DISK_SIGNATURE tag added for MBR partitions, Split partition0.bin into
# MBR0.bin and EBR0.bin, Corrected bug in backup GPT DISK patching
# 2011-03-10 ah Removes loadpt.cmm, splits partition0.bin to MBR0.bin, EBR0.bin
# 2011-03-09 ah Much more error checking, cleaner, adds "align_wpb" tag
# 2011-02-14 ah Added patching of DISK for GPT
# 2011-02-02 ah Allow MBR Type to be specified as "4C" or "0x4C"
# 2011-25-01 ah Outputs "patch.xml" as well, allows more optimal partition alignment
# 2010-12-01 ah Matching QPST, all EXT partitions 64MB aligned (configurable actually)
# More error checking, Removed CHS option, GPT output is 2 files (primary and backup)
# 2010-10-26 ah better error checking, corrected typo on physical_partition for > 0
# 2010-10-25 ah adds GPT, CFILE output, various other features
# 2010-10-08 ah released to remove compile errors of missing PERL script modules
# Copyright (c) 2007-2010
# Qualcomm Technologies Incorporated.
# All Rights Reserved.
# Qualcomm Confidential and Proprietary
# ===========================================================================*/
import sys,os,getopt
import random,math
import re
import struct
from types import *
from time import sleep
if sys.version_info < (2,5):
sys.stdout.write("\n\nERROR: This script needs Python version 2.5 or greater, detected as ")
print sys.version_info
sys.exit() # error
from xml.etree import ElementTree as ET
#from elementtree.ElementTree import ElementTree
from xml.etree.ElementTree import Element, SubElement, Comment, tostring
from xml.dom import minidom
OutputFolder = ""
LastPartitionBeginsAt = 0
HashInstructions = {}
tempVar = 5
NumPhyPartitions = 0
PartitionCollection = [] # An array of Partition objects. Partition is a hash of information about partition
PhyPartition = {} # An array of PartitionCollection objects
MinSectorsNeeded = 0
# Ex. PhyPartition[0] holds the PartitionCollection that holds all the info for partitions in PHY partition 0
AvailablePartitions = {}
XMLFile = "module_common.py"
ExtendedPartitionBegins= 0
instructions = []
HashStruct = {}
StructPartitions = []
StructAdditionalFields = []
AllPartitions = {}
PARTITION_SYSTEM_GUID = 0x3BC93EC9A0004BBA11D2F81FC12A7328
PARTITION_MSFT_RESERVED_GUID= 0xAE1502F02DF97D814DB80B5CE3C9E316
PARTITION_BASIC_DATA_GUID = 0xC79926B7B668C0874433B9E5EBD0A0A2
SECTOR_SIZE_IN_BYTES = 512 # This can be over ridden in the partition.xml file
PrimaryGPT = [0]*17408 # This gets redefined later based on SECTOR_SIZE_IN_BYTES This is LBA 0 to 33 (34 sectors total) (start of disk)
BackupGPT = [0]*16896 # This gets redefined later based on SECTOR_SIZE_IN_BYTES This is LBA-33 to -1 (33 sectors total) (end of disk)
EmptyGPT = [0]*17408 # This gets redefined later based on SECTOR_SIZE_IN_BYTES This is LBA 0 to 33 (34 sectors total) (start of disk)
PrimaryGPTNumLBAs=len(PrimaryGPT)/SECTOR_SIZE_IN_BYTES
BackupGPTNumLBAs =len(BackupGPT)/SECTOR_SIZE_IN_BYTES
## Note that these HashInstructions are updated by the XML file
HashInstructions['WRITE_PROTECT_BOUNDARY_IN_KB'] = 64*1024
HashInstructions['GROW_LAST_PARTITION_TO_FILL_DISK'] = True
HashInstructions['DISK_SIGNATURE'] = 0x0
MBR = [0]*SECTOR_SIZE_IN_BYTES
EBR = [0]*SECTOR_SIZE_IN_BYTES
hash_w = [{'start_sector':0,'num_sectors':(HashInstructions['WRITE_PROTECT_BOUNDARY_IN_KB']*1024/SECTOR_SIZE_IN_BYTES),
'end_sector':(HashInstructions['WRITE_PROTECT_BOUNDARY_IN_KB']*1024/SECTOR_SIZE_IN_BYTES)-1,'physical_partition_number':0,'boundary_num':0,'num_boundaries_covered':1}]
NumWPregions = 0
def ShowPartitionExample():
print "Your \"partition.xml\" file needs to look like something like this below"
print "\t(i.e. notice the *multiple* physical_partition tags)\n"
print "<!-- This is physical partition 0 -->"
print "<physical_partition>"
print " <partition label=\"SBL1\" size_in_kb=\"100\" type=\"DEA0BA2C-CBDD-4805-B4F9-F428251C3E98\" filename=\"sbl1.mbn\"/>"
print "</physical_partition>"
print " "
print "<!-- This is physical partition 1 -->"
print "<physical_partition>"
print " <partition label=\"SBL2\" size_in_kb=\"200\" type=\"8C6B52AD-8A9E-4398-AD09-AE916E53AE2D\" filename=\"sbl2.mbn\"/>"
print "</physical_partition>"
def ConvertKBtoSectors(x):
## 1KB / SECTOR_SIZE_IN_BYTES normally means return 2 (i.e. with SECTOR_SIZE_IN_BYTES=512)
## 2KB / SECTOR_SIZE_IN_BYTES normally means return 4 (i.e. with SECTOR_SIZE_IN_BYTES=512)
return int((x*1024)/SECTOR_SIZE_IN_BYTES)
def UpdatePatch(StartSector,ByteOffset,PHYPartition,size_in_bytes,szvalue,szfilename,szwhat):
global PatchesXML
SubElem