Skip to content

Commit 8c07231

Browse files
committed
gen_contents.py: Add utility to generate contents.xml
gen_contents.py accepts a contents template and partition.xml as inputs and generates 'contents.xml' by updating image information in a format compatible with Axiom for automatic image flashing. Signed-off-by: Viswanath Kraleti <[email protected]>
1 parent e1cd729 commit 8c07231

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

gen_contents.py

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
3+
# SPDX-License-Identifier: BSD-3-Clause
4+
5+
import getopt
6+
import sys
7+
8+
from xml.etree import ElementTree as ET
9+
10+
11+
def usage():
12+
print(("\n\tUsage: %s -t <template> -p <partitions_xml_path> -o <output> \n\tVersion 0.1\n" % (sys.argv[0])))
13+
sys.exit(1)
14+
15+
16+
def ParseXML(XMLFile):
17+
try:
18+
tree = ET.parse(XMLFile)
19+
root = tree.getroot()
20+
return root
21+
except FileNotFoundError:
22+
print(f"Error: File '{XMLFile}' not found")
23+
return None
24+
except ET.ParseError as e:
25+
print(f"Error: Failed parsing '{XMLFile}': {e}")
26+
return None
27+
28+
29+
def UpdateMetaData(TemplateRoot, PartitionRoot):
30+
ChipIdList = TemplateRoot.findall('product_info/chipid')
31+
DefaultStorageType = None
32+
for ChipId in ChipIdList:
33+
Flavor = ChipId.get('flavor')
34+
StorageType = ChipId.get('storage_type')
35+
print(f"Chipid Flavor: {Flavor} Storage Type: {StorageType}")
36+
if Flavor == "default":
37+
DefaultStorageType = ChipId.get('storage_type')
38+
39+
PhyPartition = PartitionRoot.findall('physical_partition')
40+
PartitionsSet = set()
41+
Partitions = PartitionRoot.findall('physical_partition/partition')
42+
for partition in Partitions:
43+
label = partition.get('label')
44+
filename = partition.get('filename')
45+
if label and filename:
46+
PartitionsSet.add((label, filename))
47+
print(f"PartitionsSet: {PartitionsSet}")
48+
49+
builds = TemplateRoot.findall('builds_flat/build')
50+
for build in builds:
51+
Name = build.find('name')
52+
print(f"Build Name: {Name.text}")
53+
if Name.text != "common":
54+
continue
55+
DownloadFile = build.find('download_file')
56+
if DownloadFile is not None:
57+
build.remove(DownloadFile)
58+
# Partition entires
59+
for Partition in PartitionsSet:
60+
new_download_file = ET.SubElement(build, "download_file")
61+
new_download_file.set("fastboot_complete", Partition[0])
62+
new_file_name = ET.SubElement(new_download_file, "file_name")
63+
new_file_name.text = Partition[1]
64+
new_file_path = ET.SubElement(new_download_file, "file_path")
65+
new_file_path.text = "."
66+
# GPT Main & GPT Backup entries
67+
for PhysicalPartitionNumber in range(0, len(PhyPartition)):
68+
new_download_file = ET.SubElement(build, "download_file")
69+
new_download_file.set("storage_type", DefaultStorageType)
70+
new_file_name = ET.SubElement(new_download_file, "file_name")
71+
new_file_name.text = 'gpt_main%d.xml' % (PhysicalPartitionNumber)
72+
new_file_path = ET.SubElement(new_download_file, "file_path")
73+
new_file_path.text = "."
74+
new_download_file = ET.SubElement(build, "download_file")
75+
new_download_file.set("storage_type", DefaultStorageType)
76+
new_file_name = ET.SubElement(new_download_file, "file_name")
77+
new_file_name.text = 'gpt_backup%d.xml' % (PhysicalPartitionNumber)
78+
new_file_path = ET.SubElement(new_download_file, "file_path")
79+
new_file_path.text = "."
80+
81+
PartitionFile = build.find('partition_file')
82+
if PartitionFile is not None:
83+
build.remove(PartitionFile)
84+
# Rawprogram entries
85+
for PhysicalPartitionNumber in range(0, len(PhyPartition)):
86+
new_partition_file = ET.SubElement(build, "partition_file")
87+
new_partition_file.set("storage_type", DefaultStorageType)
88+
new_file_name = ET.SubElement(new_partition_file, "file_name")
89+
new_file_name.text = 'rawprogram%d.xml' % (PhysicalPartitionNumber)
90+
new_file_path = ET.SubElement(new_partition_file, "file_path")
91+
new_file_path.set("flavor", "default")
92+
new_file_path.text = "."
93+
94+
PartitionPatchFile = build.find('partition_patch_file')
95+
if PartitionPatchFile is not None:
96+
build.remove(PartitionPatchFile)
97+
# Patch entries
98+
for PhysicalPartitionNumber in range(0, len(PhyPartition)):
99+
new_partition_patch_file = ET.SubElement(build, "partition_patch_file")
100+
new_partition_patch_file.set("storage_type", DefaultStorageType)
101+
new_file_name = ET.SubElement(new_partition_patch_file, "file_name")
102+
new_file_name.text = 'patch%d.xml' % (PhysicalPartitionNumber)
103+
new_file_path = ET.SubElement(new_partition_patch_file, "file_path")
104+
new_file_path.set("flavor", "default")
105+
new_file_path.text = "."
106+
107+
###############################################################################
108+
# main
109+
###############################################################################
110+
111+
112+
if len(sys.argv) < 3:
113+
usage()
114+
115+
try:
116+
if sys.argv[1] == "-h" or sys.argv[1] == "--help":
117+
usage()
118+
try:
119+
opts, rem = getopt.getopt(sys.argv[1:], "t:p:o:")
120+
for (opt, arg) in opts:
121+
if opt in ["-t"]:
122+
template = arg
123+
elif opt in ["-p"]:
124+
partition_xml = arg
125+
elif opt in ["-o"]:
126+
output_xml = arg
127+
else:
128+
usage()
129+
except Exception as argerr:
130+
print(str(argerr))
131+
usage()
132+
133+
print("Selected Template: " + template)
134+
xml_root = ParseXML(template)
135+
136+
print("Selected Partition XML: " + partition_xml)
137+
partition_root = ParseXML(partition_xml)
138+
139+
UpdateMetaData(xml_root, partition_root)
140+
141+
OutputTree = ET.ElementTree(xml_root)
142+
ET.indent(OutputTree, space="\t", level=0)
143+
OutputTree.write(output_xml, encoding="utf-8", xml_declaration=True)
144+
except Exception as e:
145+
print(("Error: ", e))
146+
sys.exit(1)
147+
148+
sys.exit(0)

0 commit comments

Comments
 (0)