blob: 040558d8078df403a2d27490c8f7b4847eb744cb [file] [log] [blame]
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301######################################################################
2# Copyright (c) 2017, The Linux Foundation. All rights reserved.
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05303#
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05304# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License version 2 and
6# only version 2 as published by the Free Software Foundation.
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05307#
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05308# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#####################################################################
13
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053014"""
15Script to create a U-Boot flashable multi-image blob.
16
17This script creates a multi-image blob, from a bunch of images, and
18adds a U-Boot shell script to the blob, that can flash the images from
19within U-Boot. The procedure to use this script is listed below.
20
21 1. Create an images folder. Ex: my-pack
22
23 2. Copy all the images to be flashed into the folder.
24
25 3. Copy the partition MBN file into the folder. The file should be
26 named 'partition.mbn'. This is used to determine the offsets for
27 each of the named partitions.
28
29 4. Create a flash configuration file, specifying the images be
30 flashed, and the partition in which the images is to be
31 flashed. The flash configuration file can be specified using the
32 -f option, default is flash.conf.
33
34 5. Invoke 'pack' with the folder name as argument, pass flash
35 parameters as arguments if required. A single image file will
36 be created, out side the images folder, with .img suffix. Ex:
37 my-pack.img
38
39 6. Transfer the file into a valid SDRAM address and invoke the
40 following U-Boot command to flash the images. Replace 0x41000000,
41 with address location where the image has been loaded. The script
42 expects the variable 'imgaddr' to be set.
43
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +053044 u-boot> imgaddr=0x88000000 source $imgaddr:script
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053045
46Host-side Pre-req
47
48 * Python >= 2.6
49 * ordereddict >= 1.1 (for Python 2.6)
50 * mkimage >= 2012.07
51 * dtc >= 1.2.0
52
53Target-side Pre-req
54
55The following U-Boot config macros should be enabled, for the
56generated flashing script to work.
57
58 * CONFIG_FIT -- FIT image format support
59 * CONFIG_SYS_HUSH_PARSER -- bash style scripting support
60 * CONFIG_SYS_NULLDEV -- redirecting command output support
61 * CONFIG_CMD_XIMG -- extracting sub-images support
62 * CONFIG_CMD_NAND -- NAND Flash commands support
63 * CONFIG_CMD_NAND_YAFFS -- NAND YAFFS2 write support
64 * CONFIG_CMD_SF -- SPI Flash commands support
65"""
66
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053067from os.path import getsize
68from getopt import getopt
69from getopt import GetoptError
70from collections import namedtuple
71from string import Template
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053072
73import os
74import sys
75import os.path
76import subprocess
77import struct
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053078import hashlib
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +053079import xml.etree.ElementTree as ET
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053080
81version = "1.1"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +053082ARCH_NAME = ""
83SRC_DIR = ""
84MODE = ""
Saravanan Jaganathan7d086402017-09-22 15:35:01 +053085image_type = "all"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053086#
87# Python 2.6 and earlier did not have OrderedDict use the backport
88# from ordereddict package. If that is not available report error.
89#
90try:
91 from collections import OrderedDict
92except ImportError:
93 try:
94 from ordereddict import OrderedDict
95 except ImportError:
96 print "error: this script requires the 'ordereddict' class."
97 print "Try 'pip install --user ordereddict'"
98 print "Or 'easy_install --user ordereddict'"
99 sys.exit(1)
100
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530101def error(msg, ex=None):
102 """Print an error message and exit.
103
104 msg -- string, the message to print
105 ex -- exception, the associate exception, if any
106 """
107
108 sys.stderr.write("pack: %s" % msg)
109 if ex != None: sys.stderr.write(": %s" % str(ex))
110 sys.stderr.write("\n")
111 sys.exit(1)
112
113FlashInfo = namedtuple("FlashInfo", "type pagesize blocksize chipsize")
114ImageInfo = namedtuple("ProgInfo", "name filename type")
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530115PartInfo = namedtuple("PartInfo", "name offset length which_flash")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530116
117def roundup(value, roundto):
118 """Return the next largest multiple of 'roundto'."""
119
120 return ((value + roundto - 1) // roundto) * roundto
121
122class GPT(object):
123 GPTheader = namedtuple("GPTheader", "signature revision header_size"
124 " crc32 current_lba backup_lba first_usable_lba"
125 " last_usable_lba disk_guid start_lba_part_entry"
126 " num_part_entry part_entry_size part_crc32")
127 GPT_SIGNATURE = 'EFI PART'
128 GPT_REVISION = '\x00\x00\x01\x00'
129 GPT_HEADER_SIZE = 0x5C
130 GPT_HEADER_FMT = "<8s4sLL4xQQQQ16sQLLL"
131
132 GPTtable = namedtuple("GPTtable", "part_type unique_guid first_lba"
133 " last_lba attribute_flag part_name")
134 GPT_TABLE_FMT = "<16s16sQQQ72s"
135
136 def __init__(self, filename, pagesize, blocksize, chipsize):
137 self.filename = filename
138 self.pagesize = pagesize
139 self.blocksize = blocksize
140 self.chipsize = chipsize
141 self.__partitions = OrderedDict()
142
143 def __validate_and_read_parts(self, part_fp):
144 """Validate the GPT and read the partition"""
145 part_fp.seek(self.blocksize, os.SEEK_SET)
146 gptheader_str = part_fp.read(struct.calcsize(GPT.GPT_HEADER_FMT))
147 gptheader = struct.unpack(GPT.GPT_HEADER_FMT, gptheader_str)
148 gptheader = GPT.GPTheader._make(gptheader)
149
150 if gptheader.signature != GPT.GPT_SIGNATURE:
151 error("Invalid signature")
152
153 if gptheader.revision != GPT.GPT_REVISION:
154 error("Unsupported GPT Revision")
155
156 if gptheader.header_size != GPT.GPT_HEADER_SIZE:
157 error("Invalid Header size")
158
159 # Adding GPT partition info. This has to be flashed first.
160 # GPT Header starts at LBA1 so (current_lba -1) will give the
161 # starting of primary GPT.
162 # blocksize will equal to gptheader.first_usuable_lba - current_lba + 1
163
164 name = "0:GPT"
165 block_start = gptheader.current_lba - 1
166 block_count = gptheader.first_usable_lba - gptheader.current_lba + 1
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530167 which_flash = 0
168 part_info = PartInfo(name, block_start, block_count, which_flash)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530169 self.__partitions[name] = part_info
170
171 part_fp.seek(2 * self.blocksize, os.SEEK_SET)
172
173 for i in range(gptheader.num_part_entry):
174 gpt_table_str = part_fp.read(struct.calcsize(GPT.GPT_TABLE_FMT))
175 gpt_table = struct.unpack(GPT.GPT_TABLE_FMT, gpt_table_str)
176 gpt_table = GPT.GPTtable._make(gpt_table)
177
178 block_start = gpt_table.first_lba
179 block_count = gpt_table.last_lba - gpt_table.first_lba + 1
180
181 part_name = gpt_table.part_name.strip(chr(0))
182 name = part_name.replace('\0','')
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530183 part_info = PartInfo(name, block_start, block_count, which_flash)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530184 self.__partitions[name] = part_info
185
186 # Adding the GPT Backup partition.
187 # GPT header backup_lba gives block number where the GPT backup header will be.
188 # GPT Backup header will start from offset of 32 blocks before
189 # the GPTheader.backup_lba. Backup GPT size is 33 blocks.
190 name = "0:GPTBACKUP"
191 block_start = gptheader.backup_lba - 32
192 block_count = 33
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530193 part_info = PartInfo(name, block_start, block_count, which_flash)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530194 self.__partitions[name] = part_info
195
196 def get_parts(self):
197 """Returns a list of partitions present in the GPT."""
198
199 try:
200 with open(self.filename, "r") as part_fp:
201 self.__validate_and_read_parts(part_fp)
202 except IOError, e:
203 error("error opening %s" % self.filename, e)
204
205 return self.__partitions
206
207class MIBIB(object):
208 Header = namedtuple("Header", "magic1 magic2 version age")
209 HEADER_FMT = "<LLLL"
210 HEADER_MAGIC1 = 0xFE569FAC
211 HEADER_MAGIC2 = 0xCD7F127A
212 HEADER_VERSION = 4
213
214 Table = namedtuple("Table", "magic1 magic2 version numparts")
215 TABLE_FMT = "<LLLL"
216 TABLE_MAGIC1 = 0x55EE73AA
217 TABLE_MAGIC2 = 0xE35EBDDB
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530218 TABLE_VERSION_IPQ806X = 3
219 TABLE_VERSION_OTHERS = 4
220
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530221
222 Entry = namedtuple("Entry", "name offset length"
223 " attr1 attr2 attr3 which_flash")
224 ENTRY_FMT = "<16sLLBBBB"
225
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530226 def __init__(self, filename, pagesize, blocksize, chipsize, nand_blocksize, nand_chipsize, root_part):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530227 self.filename = filename
228 self.pagesize = pagesize
229 self.blocksize = blocksize
230 self.chipsize = chipsize
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530231 self.nand_blocksize = nand_blocksize
232 self.nand_chipsize = nand_chipsize
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530233 self.__partitions = OrderedDict()
234
235 def __validate(self, part_fp):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530236 """Validate the MIBIB by checking for magic bytes."""
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530237
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530238 mheader_str = part_fp.read(struct.calcsize(MIBIB.HEADER_FMT))
239 mheader = struct.unpack(MIBIB.HEADER_FMT, mheader_str)
240 mheader = MIBIB.Header._make(mheader)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530241
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530242 if (mheader.magic1 != MIBIB.HEADER_MAGIC1
243 or mheader.magic2 != MIBIB.HEADER_MAGIC2):
244 """ mheader.magic1 = MIBIB.HEADER_MAGIC1
245 mheader.magic2 = MIBIB.HEADER_MAGIC2 """
246 error("invalid partition table, magic byte not present")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530247
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530248 if mheader.version != MIBIB.HEADER_VERSION:
249 error("unsupport mibib version")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530250
251 def __read_parts(self, part_fp):
252 """Read the partitions from the MIBIB."""
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530253 global ARCH_NAME
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530254 part_fp.seek(self.pagesize, os.SEEK_SET)
255 mtable_str = part_fp.read(struct.calcsize(MIBIB.TABLE_FMT))
256 mtable = struct.unpack(MIBIB.TABLE_FMT, mtable_str)
257 mtable = MIBIB.Table._make(mtable)
258
259 if (mtable.magic1 != MIBIB.TABLE_MAGIC1
260 or mtable.magic2 != MIBIB.TABLE_MAGIC2):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530261 """ mtable.magic1 = MIBIB.TABLE_MAGIC1
262 mtable.magic2 = MIBIB.TABLE_MAGIC2 """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530263 error("invalid sys part. table, magic byte not present")
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530264 if ARCH_NAME == "ipq806x":
265 if mtable.version != MIBIB.TABLE_VERSION_IPQ806X:
266 error("unsupported partition table version")
267 else:
268 if mtable.version != MIBIB.TABLE_VERSION_OTHERS:
269 error("unsupported partition table version")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530270
271 for i in range(mtable.numparts):
272 mentry_str = part_fp.read(struct.calcsize(MIBIB.ENTRY_FMT))
273 mentry = struct.unpack(MIBIB.ENTRY_FMT, mentry_str)
274 mentry = MIBIB.Entry._make(mentry)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530275 self.flash_flag = self.blocksize
276 self.chip_flag = self.chipsize
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530277
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530278 if mentry.which_flash != 0:
279 self.flash_flag = self.nand_blocksize
280 self.chip_flag = self.nand_chipsize
281
282 byte_offset = mentry.offset * self.flash_flag
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530283
284 if mentry.length == 0xFFFFFFFF:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530285 byte_length = self.chip_flag - byte_offset
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530286 else:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530287 byte_length = mentry.length * self.flash_flag
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530288
289 part_name = mentry.name.strip(chr(0))
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530290 part_info = PartInfo(part_name, byte_offset, byte_length, mentry.which_flash)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530291 self.__partitions[part_name] = part_info
292
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530293 def get_parts(self):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530294 """Returns a list of partitions present in the MIBIB. CE """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530295
296 try:
297 with open(self.filename, "r") as part_fp:
298 self.__validate(part_fp)
299 self.__read_parts(part_fp)
300 except IOError, e:
301 error("error opening %s" % self.filename, e)
302
303 return self.__partitions
304
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530305class FlashScript(object):
306 """Base class for creating flash scripts."""
307
308 def __init__(self, flinfo):
309 self.pagesize = flinfo.pagesize
310 self.blocksize = flinfo.blocksize
311 self.script = []
312 self.parts = []
313 self.curr_stdout = "serial"
314 self.activity = None
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530315 self.flash_type = flinfo.type
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530316
317 self.script.append('if test "x$verbose" = "x"; then\n')
318 self.script.append("failedmsg='[failed]'\n")
319 self.script.append('else\n')
320 self.script.append("failedmsg='%s Failed'\n" % ("#" * 40))
321 self.script.append('fi\n')
322
323 def append(self, cmd, fatal=True):
324 """Add a command to the script.
325
326 Add additional code, to terminate on error. This can be
327 supressed by passing 'fatal' as False.
328 """
329
330 if fatal:
Pavithra Palanisamy77ed38c2018-02-21 12:32:59 +0530331 """Check cmd strings to display reason for failure."""
332
333 if "imxtract" in cmd:
334 self.script.append("failreason='error: failed on image extraction'\n")
335 elif "erase" in cmd:
336 self.script.append("failreason='error: failed on partition erase'\n")
337 elif "write" in cmd:
338 self.script.append("failreason='error: failed on partition write'\n")
339 else:
340 pass
341
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530342 self.script.append(cmd
343 + ' || setenv stdout serial'
344 + ' && echo "$failedmsg"'
Pavithra Palanisamy77ed38c2018-02-21 12:32:59 +0530345 + ' && echo "$failreason"'
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530346 + ' && exit 1\n')
347 else:
348 self.script.append(cmd + "\n")
349
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530350 def dumps(self):
351 """Return the created script as a string."""
352 return "".join(self.script)
353
354 def redirect(self, dev):
355 """Generate code, to redirect command output to a device."""
356
357 if self.curr_stdout == dev:
358 return
359
360 self.append("setenv stdout %s" % dev, fatal=False)
361 self.curr_stdout = dev
362
363 def start_activity(self, activity):
364 """Generate code, to indicate start of an activity."""
365
366 self.script.append('if test "x$verbose" = "x"; then\n')
367 self.echo("'%-40.40s'" % activity, nl=False)
368 self.script.append('else\n')
369 self.echo("'%s %s Started'" % ("#" * 40, activity), verbose=True)
370 self.script.append('fi\n')
371 self.activity = activity
372
373 def finish_activity(self):
374 """Generate code, to indicate end of an activity."""
375
376 self.script.append('if test "x$verbose" = "x"; then\n')
377 self.echo("'[ done ]'")
378 self.redirect("serial")
379 self.script.append('else\n')
380 self.echo("'%s %s Done'" % ("#" * 40, self.activity), verbose=True)
381 self.script.append('fi\n')
382
383 def imxtract(self, part):
384 """Generate code, to extract image location, from a multi-image blob.
385
386 part -- string, name of the sub-image
387
388 Sets the $fileaddr environment variable, to point to the
389 location of the sub-image.
390 """
391
392 self.append("imxtract $imgaddr %s" % part)
393
394 def echo(self, msg, nl=True, verbose=False):
395 """Generate code, to print a message.
396
397 nl -- bool, indicates whether newline is to be printed
398 verbose -- bool, indicates whether printing in verbose mode
399 """
400
401 if not verbose:
402 self.redirect("serial")
403
404 if nl:
405 self.append("echo %s" % msg, fatal=False)
406 else:
407 self.append("echo %s%s" % (r"\\c", msg), fatal=False)
408
409 if not verbose:
410 self.redirect("nulldev")
411
412 def end(self):
413 """Generate code, to indicate successful completion of script."""
414
415 self.append("exit 0\n", fatal=False)
416
417 def start_if(self, var, value):
418 """Generate code, to check an environment variable.
419
420 var -- string, variable to check
421 value -- string, the value to compare with
422 """
423
424 self.append('if test "$%s" = "%s"; then\n' % (var, value),
425 fatal=False)
426
427 def end_if(self):
428 """Generate code, to end if statement."""
429
430 self.append('fi\n', fatal=False)
431
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530432class Flash_Script(FlashScript):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530433 """Class for creating NAND flash scripts."""
434
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530435 def __init__(self, *args):
436 FlashScript.__init__(self, args[0])
437 if args[0].type == "nand":
438 self.ipq_nand = args[1]
439 elif args[0].type == "nor" or args[0].type == "norplusnand":
440 self.nand_pagesize = args[1]
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530441
442 def erase(self, offset, size):
443 """Generate code, to erase the specified partition."""
444
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530445 if self.flash_type != "emmc":
446 size = roundup(size, self.blocksize)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530447
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530448 if self.flash_type == "nand":
449 self.append("nand device 0 && nand erase 0x%08x 0x%08x" % (offset, size))
450 elif self.flash_type == "nor":
451 self.append("sf erase 0x%08x +0x%08x" % (offset, size))
452 elif self.flash_type == "emmc":
453 self.append("mmc erase 0x%08x %x" % (offset, size))
454
455 def nand_write(self, offset, part_size, img_size, spi_nand):
456 """Handle the NOR + NAND case
457 All binaries upto HLOS will go to NOR and Root FS will go to NAND
458 Assumed all nand page sizes are less than are equal to 8KB
459 """
460
461 if spi_nand == "true":
462 self.append("nand device 1 && nand erase 0x%08x 0x%08x" % (offset, part_size))
463 else:
464 self.append("nand device 0 && nand erase 0x%08x 0x%08x" % (offset, part_size))
465
466 if img_size > 0:
467 self.append("nand write $fileaddr 0x%08x 0x%08x" % (offset, img_size))
468
469 def write(self, offset, size):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530470 """Generate code, to write to a partition."""
471
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530472 if self.flash_type == "nand":
473 if size > 0:
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530474 size = roundup(size, self.pagesize)
475 self.append("nand write $fileaddr 0x%08x 0x%08x" % (offset, size))
476
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530477 elif self.flash_type == "nor":
478 if size > 0:
479 self.append("sf write $fileaddr 0x%08x 0x%08x" % (offset, size))
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530480
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530481 elif self.flash_type == "emmc":
482 if size > 0:
483 size = roundup(size, self.blocksize)
484 blk_cnt = size / self.blocksize
485 self.append("mmc write $fileaddr 0x%08x %x" % (offset, blk_cnt))
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530486
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530487 def probe(self):
488 if self.flash_type == "nand":
489 pass
490 elif self.flash_type == "nor":
491 self.append("sf probe")
492 else:
493 pass
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +0530494
495 def switch_layout(self, layout):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530496 if self.flash_type == "nand":
497 self.append("ipq_nand %s" % layout)
498 else:
499 pass
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530500
501its_tmpl = Template("""
502/dts-v1/;
503
504/ {
505 description = "${desc}";
506 images {
507${images}
508 };
509};
510""")
511
512its_image_tmpl = Template("""
513 ${name} {
514 description = "${desc}";
515 data = /incbin/("./${fname}");
516 type = "${imtype}";
517 arch = "arm";
518 compression = "none";
519 hash@1 { algo = "crc32"; };
520 };
521""")
522
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530523def sha1(message):
524 """Returns SHA1 digest in hex format of the message."""
525
526 m = hashlib.sha1()
527 m.update(message)
528 return m.hexdigest()
529
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530530class Pack(object):
531 """Class to create a flashable, multi-image blob.
532
533 Combine multiple images present in a directory, and generate a
534 U-Boot script to flash the images.
535 """
536 # The maximum rootfs size is 64MB
537 norplusnand_rootfs_img_size = (64 * 1024 * 1024)
538
539 def __init__(self):
540 self.flinfo = None
541 self.images_dname = None
542 self.ipq_nand = None
543 self.partitions = {}
544
545 self.fconf_fname = None
546 self.scr_fname = None
547 self.its_fname = None
548 self.img_fname = None
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530549 self.emmc_page_size = 512
550 self.emmc_block_size = 512
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530551
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530552 def __get_machid(self, section):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530553 """Get the machid for a section.
554
555 info -- ConfigParser object, containing image flashing info
556 section -- section to retreive the machid from
557 """
558 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530559 machid = int(section.find("./machid").text, 0)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530560 machid = "%x" % machid
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530561 except ValueError, e:
562 error("invalid value for machid, should be integer")
563
564 return machid
565
566 def __get_img_size(self, filename):
567 """Get the size of the image to be flashed
568
569 filaneme -- string, filename of the image to be flashed
570 """
571
572 if filename.lower() == "none":
573 return 0
574 try:
575 return getsize(os.path.join(self.images_dname, filename))
576 except OSError, e:
577 error("error getting image size '%s'" % filename, e)
578
579 def __get_part_info(self, partition):
580 """Return partition info for the specified partition.
581
582 partition -- string, partition name
583 """
584 try:
585 return self.partitions[partition]
586 except KeyError, e:
587 return None
588
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530589 def __gen_flash_script_cdt(self, entries, partition, flinfo, script):
590 global ARCH_NAME
591 for section in entries:
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530592
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530593 machid = int(section.find(".//machid").text, 0)
594 machid = "%x" % machid
595 board = section.find(".//board").text
596 spi_nand = section.find(".//spi_nand").text
597 if ARCH_NAME != "ipq806x":
598 try:
599 memory = section.find(".//memory").text
600 except AttributeError, e:
601 memory = "128M16"
602 filename = "cdt-" + board + "_" + memory + ".bin"
603 else:
604 filename = "cdt-" + board + ".bin"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530605
606 img_size = self.__get_img_size(filename)
607 part_info = self.__get_part_info(partition)
608
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530609 section_label = partition.split(":")
610 if len(section_label) != 1:
611 section_conf = section_label[1]
612 else:
613 section_conf = section_label[0]
614
615 section_conf = section_conf.lower()
616
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530617 if self.flinfo.type == 'nand':
618 size = roundup(img_size, flinfo.pagesize)
619 tr = ' | tr \"\\000\" \"\\377\"'
620
621 if self.flinfo.type == 'emmc':
622 size = roundup(img_size, flinfo.blocksize)
623 tr = ''
624
625 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
626 pad_size = size - img_size
627 filename_abs = os.path.join(self.images_dname, filename)
628 filename_abs_pad = filename_abs + ".padded"
629 cmd = 'cat %s > %s' % (filename_abs, filename_abs_pad)
630 ret = subprocess.call(cmd, shell=True)
631 if ret != 0:
632 error("failed to copy image")
633 cmd = 'dd if=/dev/zero count=1 bs=%s %s >> %s' % (pad_size, tr, filename_abs_pad)
634 cmd = '(' + cmd + ') 1>/dev/null 2>/dev/null'
635 ret = subprocess.call(cmd, shell=True)
636 if ret != 0:
637 error("failed to create padded image from script")
638
639 if self.flinfo.type != "emmc":
640 if part_info == None:
641 if self.flinfo.type == 'norplusnand':
642 if count > 2:
643 error("More than 2 NAND images for NOR+NAND is not allowed")
644 elif img_size > part_info.length:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530645 error("img size is larger than part. len in '%s'" % section_conf)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530646 else:
647 if part_info != None:
648 if (img_size > 0):
649 if img_size > (part_info.length * self.flinfo.blocksize):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530650 error("img size is larger than part. len in '%s'" % section_conf)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530651
652 if part_info == None and self.flinfo.type != 'norplusnand':
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530653 print "Flash type is norplusemmc"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530654 continue
655
656 if machid:
657 script.start_if("machid", machid)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530658 if ARCH_NAME != "ipq806x":
659 script.start_activity("Flashing ddr-%s_%s:" % ( board, memory ))
660 if img_size > 0:
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +0530661 filename_pad = filename + ".padded"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530662 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
663 script.imxtract("ddr-" + board + "_" + memory + "-" + sha1(filename_pad))
664 else:
665 script.imxtract("ddr-" + board + "_" + memory + "-" + sha1(filename))
666 """ script.imxtract("cdt-" + board + "_" + memory + ".bin-" + sha1(filename_pad))
667 else:
668 script.imxtract("cdt-" + board + "_" + memory + ".bin-" + sha1(filename)) """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530669
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530670 else:
671 script.start_activity("Flashing ddr-%s:" % (board))
672 script.switch_layout("sbl")
673 if img_size > 0:
674 filename_pad = filename + ".padded"
675 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
676 script.imxtract("ddr-" + board + "-" + sha1(filename_pad))
677 else:
678 script.imxtract("ddr-" + board + "-" + sha1(filename))
679 """ script.imxtract("cdt-" + board + ".bin-" + sha1(filename_pad))
680 else:
681 script.imxtract("cdt-" + board + ".bin-" + sha1(filename)) """
682
683 part_size = Pack.norplusnand_rootfs_img_size
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530684 if part_info == None:
685 if self.flinfo.type == 'norplusnand':
686 offset = count * Pack.norplusnand_rootfs_img_size
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530687 script.nand_write(offset, part_size, img_size, spi_nand)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530688 count = count + 1
689 else:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530690 if part_info.which_flash == 0:
691 offset = part_info.offset
692 script.erase(offset, part_info.length)
693 script.write(offset, img_size)
694 else:
695 offset = part_info.offset
696 script.nand_write(offset, part_info.length, img_size, spi_nand)
697
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530698 script.finish_activity()
699
700 if machid:
701 script.end_if()
702
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530703 def __gen_flash_script_image(self, filename, soc_version, file_exists, machid, partition, flinfo, script):
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530704
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530705 img_size = 0
706 if file_exists == 1:
707 img_size = self.__get_img_size(filename)
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530708 part_info = self.__get_part_info(partition)
709
710 section_label = partition.split(":")
711 if len(section_label) != 1:
712 section_conf = section_label[1]
713 else:
714 section_conf = section_label[0]
715
716 section_conf = section_conf.lower()
717 spi_nand = False
718
719 if self.flinfo.type == 'nand':
720 size = roundup(img_size, flinfo.pagesize)
721 tr = ' | tr \"\\000\" \"\\377\"'
722
723 if self.flinfo.type == 'emmc':
724 size = roundup(img_size, flinfo.blocksize)
725 tr = ''
726
727 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
728 pad_size = size - img_size
729 filename_abs = os.path.join(self.images_dname, filename)
730 filename_abs_pad = filename_abs + ".padded"
731 cmd = 'cat %s > %s' % (filename_abs, filename_abs_pad)
732 ret = subprocess.call(cmd, shell=True)
733 if ret != 0:
734 error("failed to copy image")
735 cmd = 'dd if=/dev/zero count=1 bs=%s %s >> %s' % (pad_size, tr, filename_abs_pad)
736 cmd = '(' + cmd + ') 1>/dev/null 2>/dev/null'
737 ret = subprocess.call(cmd, shell=True)
738 if ret != 0:
739 error("failed to create padded image from script")
740
741 if self.flinfo.type != "emmc":
742 if part_info == None:
743 if self.flinfo.type == 'norplusnand':
744 if count > 2:
745 error("More than 2 NAND images for NOR+NAND is not allowed")
746 elif img_size > part_info.length:
747 error("img size is larger than part. len in '%s'" % section_conf)
748 else:
749 if part_info != None:
750 if (img_size > 0):
751 if img_size > (part_info.length * self.flinfo.blocksize):
752 error("img size is larger than part. len in '%s'" % section_conf)
753
754 if part_info == None and self.flinfo.type != 'norplusnand':
755 print "Flash type is norplusemmc"
756 return
757
758 if machid:
759 script.start_if("machid", machid)
760
761 if section_conf == "qsee":
762 section_conf = "tz"
763 elif section_conf == "appsbl":
764 section_conf = "u-boot"
765 elif section_conf == "rootfs" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
766 section_conf = "ubi"
767 elif section_conf == "wififw" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
768 section_conf = "wififw_ubi"
769
770 if soc_version:
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +0530771 section_conf = section_conf + "_v" + str(soc_version)
Pavithra Palanisamy06f249a2018-09-11 12:49:50 +0530772 if str(soc_version) == "1":
773 script.append('if test "$soc_version_major" = "1" || test "$soc_version_major" = ""; then\n', fatal=False)
774 else:
775 script.start_if("soc_version_major", soc_version)
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530776
777 script.start_activity("Flashing %s:" % section_conf)
778
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530779 if file_exists == 0:
780 script.append('setenv stdout serial && echo "error: binary image not found" && exit 1', fatal=False)
781 if soc_version:
782 script.end_if()
783 return
784
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530785 if ARCH_NAME == "ipq806x":
786 script.switch_layout(layout)
787 if img_size > 0:
788 filename_pad = filename + ".padded"
789 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
790 script.imxtract(section_conf + "-" + sha1(filename_pad))
791 else:
792 script.imxtract(section_conf + "-" + sha1(filename))
793
794 part_size = Pack.norplusnand_rootfs_img_size
795 if part_info == None:
796 if self.flinfo.type == 'norplusnand':
797 offset = count * Pack.norplusnand_rootfs_img_size
798 img_size = Pack.norplusnand_rootfs_img_size
799 script.nand_write(offset, part_size, img_size, spi_nand)
800 count = count + 1
801 else:
802 if part_info.which_flash == 0:
803 offset = part_info.offset
804 script.erase(offset, part_info.length)
805 script.write(offset, img_size)
806 else:
807 offset = part_info.offset
808 script.nand_write(offset, part_info.length, img_size, spi_nand)
809
810 script.finish_activity()
811
812 if soc_version:
813 script.end_if()
814
815 if machid:
816 script.end_if()
817
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530818 def __gen_flash_script(self, script, flinfo, root):
819 """Generate the script to flash the images.
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530820
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530821 info -- ConfigParser object, containing image flashing info
822 script -- Script object, to append commands to
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530823 """
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530824 global MODE
825 global SRC_DIR
826 global ARCH_NAME
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530827
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530828 diff_files = ""
829 count = 0
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530830 soc_version = 0
831 diff_soc_ver_files = 0
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530832 file_exists = 1
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530833
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530834 if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
835 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
836 else:
837 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
838
839 root_part = ET.parse(srcDir_part)
840 if self.flash_type != "emmc" and flinfo.type != "emmc":
841 parts = root_part.findall(".//partitions/partition")
842 elif self.flash_type != "emmc" and flinfo.type == "emmc":
843 parts = root_part.findall(".//physical_partition[@ref='norplusemmc']/partition")
844 else:
845 parts = root_part.findall(".//physical_partition[@ref='emmc']/partition")
846 if flinfo.type == "emmc":
847 parts_length = len(parts) + 2
848 else:
849 parts_length = len(parts)
850 entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
851
852 first = False
853 section = None
854 part_index = 0
855
856 if flinfo.type == "emmc":
857 first = True
858
859 for index in range(parts_length):
860
861 if first:
862 if self.flash_type == "norplusemmc":
863 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
864 else:
865 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
866 part_fname = part_info.find(".//partition_mbn")
867 filename = part_fname.text
868 partition = "0:GPT"
869 first = False
870
871 elif index == (parts_length - 1) and flinfo.type == "emmc":
872 if self.flash_type == "norplusemmc":
873 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
874 else:
875 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
876 part_fname = part_info.find(".//partition_mbn_backup")
877 filename = part_fname.text
878 partition = "0:GPTBACKUP"
879
880 else:
881 section = parts[part_index]
882 part_index += 1
883 if flinfo.type != "emmc":
884 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530885 if image_type == "all" or section[8].attrib['image_type'] == image_type:
886 filename = section[8].text
887 try:
888 if section[8].attrib['mode'] != MODE:
889 filename = section[9].text
890 else:
891 pass
892 except AttributeError, e:
893 pass
894 except KeyError, e:
895 pass
896 else:
897 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530898 except IndexError, e:
899 if index == (parts_length - 1):
900 return
901 else:
902 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530903 except KeyError, e:
904 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530905 partition = section[0].text
906 else:
907 try:
908 diff_files = section.attrib['diff_files']
909 except KeyError, e:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530910 try:
911 diff_soc_ver_files = section.attrib['diff_soc_ver_files']
912 except KeyError, e:
913 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530914 if image_type == "all" or section.attrib['image_type'] == image_type:
915 filename = section.attrib['filename']
916 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530917 if filename == "":
918 continue
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530919 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530920 print "Skipping partition '%s'" % section.attrib['label']
921 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530922
923 if diff_files == "true":
924 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530925 if image_type == "all" or section.attrib['image_type'] == image_type:
926 filename = section.attrib['filename_' + MODE]
927 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530928 if filename == "":
929 continue
930 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530931 print "Skipping partition '%s'" % section.attrib['label']
932 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530933 diff_files = "" # Clear for next iteration
934
935 # Get machID
936 if partition != "0:CDT" and partition != "0:DDRCONFIG":
937 machid = None
938 else:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530939 try:
940 if image_type == "all" or section.attrib['image_type'] == image_type:
941 self.__gen_flash_script_cdt(entries, partition, flinfo, script)
942 continue
943 except KeyError, e:
944 continue
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530945
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530946 if ARCH_NAME == "ipq806x":
947 # Get Layout
948 try:
949 layout = section[9].text
950 except:
951 layout = None
952
953 if layout not in ("sbl", "linux", None):
954 error("invalid layout in '%s'" % section)
955
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530956 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530957
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530958 img = section.find('img_name')
959 if img != None and 'soc_version' in img.attrib:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530960
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530961 imgs = section.findall('img_name')
962 try:
963 for img in imgs:
964 filename = img.text
965 soc_version = img.get('soc_version')
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530966 if 'optional' in img.attrib:
967 if not os.path.exists(os.path.join(self.images_dname, filename)):
968 file_exists = 0
969 self.__gen_flash_script_image(filename, soc_version, file_exists, machid, partition, flinfo, script)
970 file_exists = 1 # generating flash script is mandatory by default
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530971
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530972 soc_version = 0 # Clear soc_version for next iteration
973 continue
974 except KeyError, e:
975 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530976
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530977 else:
978 if diff_soc_ver_files:
979 try:
980 for version in range(1, int(diff_soc_ver_files)+1):
981 if image_type == "all" or section.attrib['image_type'] == image_type:
982 filename = section.attrib['filename_v' + str(version)]
983 partition = section.attrib['label']
984 if filename == "":
985 continue
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530986 if section.attrib['optional']:
987 if not os.path.exists(os.path.join(self.images_dname, filename)):
988 file_exists = 0
989 self.__gen_flash_script_image(filename, version, file_exists, machid, partition, flinfo, script)
990 file_exists = 1
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530991 diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
992 continue
993 except KeyError, e:
994 print "Skipping partition '%s'" % section.attrib['label']
995 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530996
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530997 self.__gen_flash_script_image(filename, soc_version, file_exists, machid, partition, flinfo, script)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530998
999 def __gen_script_cdt(self, images, flinfo, root, section_conf, partition):
1000 global ARCH_NAME
1001
1002 entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
1003
1004 for section in entries:
1005
1006 board = section.find(".//board").text
1007 if ARCH_NAME != "ipq806x":
1008 try:
1009 memory = section.find(".//memory").text
1010 except AttributeError, e:
1011 memory = "128M16"
1012
1013 filename = "cdt-" + board + "_" + memory + ".bin"
1014 file_info = "ddr-" + board + "_" + memory
1015 else:
1016 filename = "cdt-" + board + ".bin"
1017 file_info = "ddr-" + board
1018
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301019 part_info = self.__get_part_info(partition)
1020
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +05301021 if part_info == None and self.flinfo.type != 'norplusnand':
1022 continue
1023
1024 if self.flinfo.type == 'nand':
1025 img_size = self.__get_img_size(filename)
1026 size = roundup(img_size, flinfo.pagesize)
1027 if ( size != img_size ):
1028 filename = filename + ".padded"
1029 if self.flinfo.type == 'emmc':
1030 img_size = self.__get_img_size(filename)
1031 size = roundup(img_size, flinfo.blocksize)
1032 if ( size != img_size ):
1033 filename = filename + ".padded"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301034 image_info = ImageInfo(file_info + "-" + sha1(filename),
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301035 filename, "firmware")
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +05301036 if filename.lower() != "none":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301037 if image_info not in images:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301038 images.append(image_info)
1039
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301040 def __gen_script_append_images(self, filename, soc_version, images, flinfo, root, section_conf, partition):
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301041
1042 part_info = self.__get_part_info(partition)
1043 if part_info == None and self.flinfo.type != 'norplusnand':
1044 return
1045
1046 if self.flinfo.type == 'nand':
1047 img_size = self.__get_img_size(filename)
1048 size = roundup(img_size, flinfo.pagesize)
1049 if ( size != img_size ):
1050 filename = filename + ".padded"
1051 if self.flinfo.type == 'emmc':
1052 img_size = self.__get_img_size(filename)
1053 size = roundup(img_size, flinfo.blocksize)
1054 if ( size != img_size ):
1055 filename = filename + ".padded"
1056 if section_conf == "qsee":
1057 section_conf = "tz"
1058 elif section_conf == "appsbl":
1059 section_conf = "u-boot"
1060 elif section_conf == "rootfs" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
1061 section_conf = "ubi"
1062 elif section_conf == "wififw" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
1063 section_conf = "wififw_ubi"
1064
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301065 if soc_version:
1066 section_conf = section_conf + "_v" + str(soc_version)
1067
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301068 image_info = ImageInfo(section_conf + "-" + sha1(filename),
1069 filename, "firmware")
1070 if filename.lower() != "none":
1071 if image_info not in images:
1072 images.append(image_info)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301073
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301074 def __gen_script(self, script_fp, script, images, flinfo, root):
1075 """Generate the script to flash the multi-image blob.
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301076
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301077 script_fp -- file object, to write script to
1078 info_fp -- file object, to read flashing information from
1079 script -- Script object, to append the commands to
1080 images -- list of ImageInfo, appended to, based on images in config
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301081 """
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301082 global MODE
1083 global SRC_DIR
1084
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301085 soc_version = 0
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301086 diff_soc_ver_files = 0
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301087 diff_files = ""
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +05301088 file_exists = 1
1089
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301090 self.__gen_flash_script(script, flinfo, root)
1091 if (self.flash_type == "norplusemmc" and flinfo.type == "emmc") or (self.flash_type != "norplusemmc"):
1092 if flinfo.type == "emmc":
1093 script.start_activity("Flashing rootfs_data:")
1094 part_info = self.partitions["rootfs_data"]
1095 script.erase(part_info.offset, part_info.length)
1096 script.finish_activity()
1097 script.end()
1098
1099 if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
1100 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
1101 else:
1102 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
1103 root_part = ET.parse(srcDir_part)
1104 if self.flash_type != "emmc" and flinfo.type != "emmc":
1105 parts = root_part.findall(".//partitions/partition")
1106 elif self.flash_type != "emmc" and flinfo.type == "emmc":
1107 parts = root_part.findall(".//physical_partition[@ref='norplusemmc']/partition")
1108 else:
1109 parts = root_part.findall(".//physical_partition[@ref='emmc']/partition")
1110 if flinfo.type == "emmc":
1111 parts_length = len(parts) + 2
1112 else:
1113 parts_length = len(parts)
1114
1115 first = False
1116 section = None
1117 part_index = 0
1118
1119 if flinfo.type == "emmc":
1120 first = True
1121
1122 for index in range(parts_length):
1123
1124 if first:
1125 if self.flash_type == "norplusemmc":
1126 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1127 else:
1128 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1129 part_fname = part_info.find(".//partition_mbn")
1130 filename = part_fname.text
1131 partition = "0:GPT"
1132 first = False
1133
1134 elif index == (parts_length - 1) and flinfo.type == "emmc":
1135 if self.flash_type == "norplusemmc":
1136 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1137 else:
1138 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1139 part_fname = part_info.find(".//partition_mbn_backup")
1140 filename = part_fname.text
1141 partition = "0:GPTBACKUP"
1142
1143 else:
1144 section = parts[part_index]
1145 part_index += 1
1146 if flinfo.type != "emmc":
1147 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301148 if image_type == "all" or section[8].attrib['image_type'] == image_type:
1149 filename = section[8].text
1150 try:
1151 if section[8].attrib['mode'] != MODE:
1152 filename = section[9].text
1153 except AttributeError, e:
1154 pass
1155 except KeyError, e:
1156 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301157 except IndexError, e:
1158 if index == (parts_length - 1):
1159 return
1160 else:
1161 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301162 except KeyError, e:
1163 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301164 partition = section[0].text
1165 else:
1166
1167 try:
1168 diff_files = section.attrib['diff_files']
1169 except KeyError, e:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301170 try:
1171 diff_soc_ver_files = section.attrib['diff_soc_ver_files']
1172 partition = section.attrib['label']
1173 except KeyError, e:
1174 try:
1175 if image_type == "all" or section.attrib['image_type'] == image_type:
1176 filename = section.attrib['filename']
1177 partition = section.attrib['label']
1178 if filename == "":
1179 continue
1180 except KeyError, e:
1181 print "Skipping partition '%s'" % section.attrib['label']
1182 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301183
1184 if diff_files == "true":
1185 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301186 if image_type == "all" or section.attrib['image_type'] == image_type:
1187 filename = section.attrib['filename_' + MODE]
1188 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301189 if filename == "":
1190 continue
1191
1192 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301193 print "Skipping partition '%s'" % section.attrib['label']
1194 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301195 diff_files = "" # Clear for next iteration
1196
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301197
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301198 part_info = self.__get_part_info(partition)
1199
1200 section_label = partition.split(":")
1201 if len(section_label) != 1:
1202 section_conf = section_label[1]
1203 else:
1204 section_conf = section_label[0]
1205
1206 section_conf = section_conf.lower()
1207
1208 if section_conf == "cdt" or section_conf == "ddrconfig":
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301209 try:
1210 if image_type == "all" or section[8].attrib['image_type'] == image_type:
1211 self.__gen_script_cdt(images, flinfo, root, section_conf, partition)
1212 continue
1213 except KeyError, e:
1214 continue
1215
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301216 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301217
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301218 img = section.find('img_name')
1219 if img != None and 'soc_version' in img.attrib:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301220
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301221 imgs = section.findall('img_name')
1222 try:
1223 for img in imgs:
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301224 soc_version = img.get('soc_version')
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301225 filename = img.text
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +05301226 if 'optional' in img.attrib:
1227 if not os.path.exists(os.path.join(self.images_dname, filename)):
1228 file_exists = 0
1229
1230 if file_exists == 1:
1231 self.__gen_script_append_images(filename, soc_version, images, flinfo, root, section_conf, partition)
1232 file_exists = 1
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301233 soc_version = 0 # Clear soc_version for next iteration
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301234 continue
1235 except KeyError, e:
1236 continue
1237
1238 else:
1239 if diff_soc_ver_files:
1240 try:
1241 for version in range(1, int(diff_soc_ver_files)+1):
1242 if image_type == "all" or section.attrib['image_type'] == image_type:
1243 filename = section.attrib['filename_v' + str(version)]
1244 partition = section.attrib['label']
1245 if filename == "":
1246 continue
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +05301247 if section.attrib['optional']:
1248 if not os.path.exists(os.path.join(self.images_dname, filename)):
1249 file_exists = 0
1250
1251 if file_exists == 1:
1252 self.__gen_script_append_images(filename, version, images, flinfo, root, section_conf, partition)
1253 file_exists = 1
1254
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301255 diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
1256 continue
1257 except KeyError, e:
1258 print "Skipping partition '%s'" % section.attrib['label']
1259 pass
1260
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301261 self.__gen_script_append_images(filename, soc_version, images, flinfo, root, section_conf, partition)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301262
1263 def __mkimage(self, images):
1264 """Create the multi-image blob.
1265
1266 images -- list of ImageInfo, containing images to be part of the blob
1267 """
1268 try:
1269 its_fp = open(self.its_fname, "wb")
1270 except IOError, e:
1271 error("error opening its file '%s'" % self.its_fname, e)
1272
1273 desc = "Flashing %s %x %x"
1274 desc = desc % (self.flinfo.type, self.flinfo.pagesize,
1275 self.flinfo.blocksize)
1276
1277 image_data = []
1278 for (section, fname, imtype) in images:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301279 fname = fname.replace("\\", "\\\\")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301280 subs = dict(name=section, desc=fname, fname=fname, imtype=imtype)
1281 image_data.append(its_image_tmpl.substitute(subs))
1282
1283 image_data = "".join(image_data)
1284 its_data = its_tmpl.substitute(desc=desc, images=image_data)
1285
1286 its_fp.write(its_data)
1287 its_fp.close()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301288
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301289 try:
1290 cmd = ["mkimage", "-f", self.its_fname, self.img_fname]
1291 ret = subprocess.call(cmd)
1292 if ret != 0:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301293 print ret
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301294 error("failed to create u-boot image from script")
1295 except OSError, e:
1296 error("error executing mkimage", e)
1297
1298 def __create_fnames(self):
1299 """Populate the filenames."""
1300
1301 self.scr_fname = os.path.join(self.images_dname, "flash.scr")
1302 self.its_fname = os.path.join(self.images_dname, "flash.its")
1303
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301304 def __gen_board_script(self, flinfo, part_fname, images, root):
1305 global SRC_DIR
1306 global ARCH_NAME
1307
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301308 """Generate the flashing script for one board.
1309
1310 board_section -- string, board section in board config file
1311 machid -- string, board machine ID in hex format
1312 flinfo -- FlashInfo object, contains board specific flash params
1313 part_fname -- string, partition file specific to the board
1314 fconf_fname -- string, flash config file specific to the board
1315 images -- list of ImageInfo, append images used by the board here
1316 """
1317 script_fp = open(self.scr_fname, "a")
1318
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301319 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301320 flash_param = root.find(".//data[@type='NAND_PARAMETER']")
1321 pagesize = int(flash_param.find(".//page_size").text)
1322 pages_per_block = int(flash_param.find(".//pages_per_block").text)
1323 blocksize = pages_per_block * pagesize
1324 blocks_per_chip = int(flash_param.find(".//total_block").text)
1325 chipsize = blocks_per_chip * blocksize
1326
1327 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
1328 root_part = ET.parse(srcDir_part)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301329 mibib = MIBIB(part_fname, flinfo.pagesize, flinfo.blocksize,
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301330 flinfo.chipsize, blocksize, chipsize, root_part)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301331 self.partitions = mibib.get_parts()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301332 if flinfo.type == "nand":
1333 script = Flash_Script(flinfo, self.ipq_nand)
1334 elif flinfo.type == "nor":
1335 script = Flash_Script(flinfo, pagesize)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301336 else:
1337 gpt = GPT(part_fname, flinfo.pagesize, flinfo.blocksize, flinfo.chipsize)
1338 self.partitions = gpt.get_parts()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301339 script = Flash_Script(flinfo)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301340
1341 self.flinfo = flinfo
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301342
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301343 script.probe()
1344 self.__gen_script(script_fp, script, images, flinfo, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301345
1346 try:
1347 script_fp.write(script.dumps())
1348 except IOError, e:
1349 error("error writing to script '%s'" % script_fp.name, e)
1350
1351 script_fp.close()
1352
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301353 def __process_board_flash_emmc(self, ftype, images, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301354 """Extract board info from config and generate the flash script.
1355
1356 ftype -- string, flash type 'emmc'
1357 board_section -- string, board section in config file
1358 machid -- string, board machine ID in hex format
1359 images -- list of ImageInfo, append images used by the board here
1360 """
1361
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301362 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301363 part_info = root.find(".//data[@type='" + self.flash_type.upper() + "_PARAMETER']")
1364 part_fname = part_info.find(".//partition_mbn")
1365 part_fname = part_fname.text
1366 part_fname = os.path.join(self.images_dname, part_fname)
1367 if ftype == "norplusemmc":
1368 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1369 pagesize = int(part_info.find(".//page_size_flash").text)
1370 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1371 else:
1372 pagesize = self.emmc_page_size
1373 blocksize = self.emmc_block_size
1374 chipsize = int(part_info.find(".//total_block").text)
1375 if ftype.lower() == "norplusemmc":
1376 ftype = "emmc"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301377
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301378 except ValueError, e:
1379 error("invalid flash info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301380
1381 flinfo = FlashInfo(ftype, pagesize, blocksize, chipsize)
1382
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301383 self.__gen_board_script(flinfo, part_fname, images, root)
1384
1385 def __process_board_flash(self, ftype, images, root):
1386 global SRC_DIR
1387 global ARCH_NAME
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301388
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301389 try:
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301390 if ftype == "tiny-nor":
1391 part_info = root.find(".//data[@type='" + "NOR_PARAMETER']")
1392 else:
1393 part_info = root.find(".//data[@type='" + ftype.upper() + "_PARAMETER']")
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301394 part_file = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + ftype + "-partition.xml"
1395 part_xml = ET.parse(part_file)
1396 partition = part_xml.find(".//partitions/partition[2]")
1397 part_fname = partition[8].text
1398 part_fname = os.path.join(self.images_dname, part_fname)
1399 pagesize = int(part_info.find(".//page_size").text)
1400 pages_per_block = int(part_info.find(".//pages_per_block").text)
1401 blocks_per_chip = int(part_info.find(".//total_block").text)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301402
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301403 if ftype == "norplusnand" or ftype == "norplusemmc" or ftype == "tiny-nor":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301404 ftype = "nor"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301405
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301406 except ValueError, e:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301407 error("invalid flash info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301408
1409 blocksize = pages_per_block * pagesize
1410 chipsize = blocks_per_chip * blocksize
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301411
1412 flinfo = FlashInfo(ftype, pagesize, blocksize, chipsize)
1413
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301414 self.__gen_board_script(flinfo, part_fname, images, root)
1415
1416 def __process_board(self, images, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301417
1418 try:
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301419 if self.flash_type in [ "nand", "nor", "tiny-nor", "norplusnand" ]:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301420 self.__process_board_flash(self.flash_type, images, root)
1421 elif self.flash_type == "emmc":
1422 self.__process_board_flash_emmc(self.flash_type, images, root)
1423 elif self.flash_type == "norplusemmc":
1424 self.__process_board_flash("norplusemmc", images, root)
1425 self.__process_board_flash_emmc("norplusemmc", images, root)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301426 except ValueError, e:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301427 error("error getting board info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301428
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301429 def main_bconf(self, flash_type, images_dname, out_fname, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301430 """Start the packing process, using board config.
1431
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301432 flash_type -- string, indicates flash type, 'nand' or 'nor' or 'tiny-nor' or 'emmc' or 'norplusnand'
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301433 images_dname -- string, name of images directory
1434 out_fname -- string, output file path
1435 """
1436 self.flash_type = flash_type
1437 self.images_dname = images_dname
1438 self.img_fname = out_fname
1439
1440 self.__create_fnames()
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301441 try:
1442 os.unlink(self.scr_fname)
1443 except OSError, e:
1444 pass
1445
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301446 images = []
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301447 self.__process_board(images, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301448 images.insert(0, ImageInfo("script", "flash.scr", "script"))
1449 self.__mkimage(images)
1450
1451class UsageError(Exception):
1452 """Indicates error in command arguments."""
1453 pass
1454
1455class ArgParser(object):
1456 """Class to parse command-line arguments."""
1457
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301458 DEFAULT_TYPE = "nor,tiny-nor,nand,norplusnand,emmc,norplusemmc"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301459
1460 def __init__(self):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301461 self.flash_type = None
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301462 self.images_dname = None
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301463 self.out_dname = None
1464 self.scr_fname = None
1465 self.its_fname = None
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301466
1467 def parse(self, argv):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301468 global MODE
1469 global SRC_DIR
1470 global ARCH_NAME
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301471 global image_type
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301472
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301473 """Start the parsing process, and populate members with parsed value.
1474
1475 argv -- list of string, the command line arguments
1476 """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301477
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301478 cdir = os.path.abspath(os.path.dirname(""))
1479 if len(sys.argv) > 1:
1480 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301481 opts, args = getopt(sys.argv[1:], "", ["arch=", "fltype=", "srcPath=", "inImage=", "outImage=", "image_type="])
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301482 except GetoptError, e:
1483 raise UsageError(e.msg)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301484
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301485 for option, value in opts:
1486 if option == "--arch":
1487 ARCH_NAME = value
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301488
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301489 elif option == "--fltype":
1490 self.flash_type = value
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301491
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301492 elif option == "--srcPath":
1493 SRC_DIR = os.path.abspath(value)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301494
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301495 elif option == "--inImage":
1496 self.images_dname = os.path.join(cdir, value)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301497
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301498 elif option == "--outImage":
1499 self.out_dname = os.path.join(cdir, value)
1500
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301501 elif option == "--image_type":
1502 image_type = value
1503
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301504#Verify Arguments passed by user
1505
1506# Verify arch type
1507 if ARCH_NAME not in ["ipq40xx", "ipq806x", "ipq807x", "ipq807x_64"]:
1508 raise UsageError("Invalid arch type '%s'" % arch)
1509
1510 if ARCH_NAME == "ipq807x":
1511 MODE = "32"
1512 elif ARCH_NAME == "ipq807x_64":
1513 MODE = "64"
1514 ARCH_NAME = "ipq807x"
1515
1516# Set flash type to default type (nand) if not given by user
1517 if self.flash_type == None:
1518 self.flash_type = ArgParser.DEFAULT_TYPE
1519 for flash_type in self.flash_type.split(","):
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301520 if flash_type not in [ "nand", "nor", "tiny-nor", "emmc", "norplusnand", "norplusemmc" ]:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301521 raise UsageError("invalid flash type '%s'" % flash_type)
1522
1523# Verify src Path
1524 if SRC_DIR == "":
1525 raise UsageError("Source Path is not provided")
1526
1527#Verify input image path
1528 if self.images_dname == None:
1529 raise UsageError("input images' Path is not provided")
1530
1531#Verify Output image path
1532 if self.out_dname == None:
1533 raise UsageError("Output Path is not provided")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301534
1535 def usage(self, msg):
1536 """Print error message and command usage information.
1537
1538 msg -- string, the error message
1539 """
1540 print "pack: %s" % msg
1541 print
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301542 print "Usage:"
1543 print "python pack_hk.py [options] [Value] ..."
1544 print
1545 print "options:"
1546 print " --arch \tARCH_TYPE [ipq40xx/ipq806x/ipq807x/ipq807x_64]"
1547 print
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301548 print " --fltype \tFlash Type [nor/tiny-nor/nand/emmc/norplusnand/norplusemmc]"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301549 print " \t\tMultiple flashtypes can be passed by a comma separated string"
1550 print " \t\tDefault is all. i.e If \"--fltype\" is not passed image for all the flash-type will be created.\n"
1551 print " --srcPath \tPath to the directory containg the meta scripts and configs"
1552 print
1553 print " --inImage \tPath to the direcory containg binaries and images needed for singleimage"
1554 print
1555 print " --outImage \tPath to the directory where single image will be generated"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301556 print
1557 print "Pack Version: %s" % version
1558
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301559def main():
1560 """Main script entry point.
1561
1562 Created to avoid polluting the global namespace.
1563 """
1564 try:
1565 parser = ArgParser()
1566 parser.parse(sys.argv)
1567 except UsageError, e:
1568 parser.usage(e.args[0])
1569 sys.exit(1)
1570
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301571 pack = Pack()
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301572
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301573 if not os.path.exists(parser.out_dname):
1574 os.makedirs(parser.out_dname)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301575
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301576 config = SRC_DIR + "/" + ARCH_NAME + "/config.xml"
1577 root = ET.parse(config)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301578
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301579# Format the output image name from Arch, flash type and mode
1580 for flash_type in parser.flash_type.split(","):
1581 if MODE == "64":
1582 parser.out_fname = flash_type + "-" + ARCH_NAME + "_" + MODE + "-single.img"
1583 else:
1584 parser.out_fname = flash_type + "-" + ARCH_NAME + "-single.img"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301585
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301586 parser.out_fname = os.path.join(parser.out_dname, parser.out_fname)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301587
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301588 pack.main_bconf(flash_type, parser.images_dname,
1589 parser.out_fname, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301590
1591if __name__ == "__main__":
1592 main()