blob: 0e2caebf8b9526b93db55b3a193340427a7d9664 [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 Palanisamye34f3092018-08-29 19:30:41 +0530703 def __gen_flash_script_image(self, filename, soc_version, machid, partition, flinfo, script):
704
705 img_size = self.__get_img_size(filename)
706 part_info = self.__get_part_info(partition)
707
708 section_label = partition.split(":")
709 if len(section_label) != 1:
710 section_conf = section_label[1]
711 else:
712 section_conf = section_label[0]
713
714 section_conf = section_conf.lower()
715 spi_nand = False
716
717 if self.flinfo.type == 'nand':
718 size = roundup(img_size, flinfo.pagesize)
719 tr = ' | tr \"\\000\" \"\\377\"'
720
721 if self.flinfo.type == 'emmc':
722 size = roundup(img_size, flinfo.blocksize)
723 tr = ''
724
725 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
726 pad_size = size - img_size
727 filename_abs = os.path.join(self.images_dname, filename)
728 filename_abs_pad = filename_abs + ".padded"
729 cmd = 'cat %s > %s' % (filename_abs, filename_abs_pad)
730 ret = subprocess.call(cmd, shell=True)
731 if ret != 0:
732 error("failed to copy image")
733 cmd = 'dd if=/dev/zero count=1 bs=%s %s >> %s' % (pad_size, tr, filename_abs_pad)
734 cmd = '(' + cmd + ') 1>/dev/null 2>/dev/null'
735 ret = subprocess.call(cmd, shell=True)
736 if ret != 0:
737 error("failed to create padded image from script")
738
739 if self.flinfo.type != "emmc":
740 if part_info == None:
741 if self.flinfo.type == 'norplusnand':
742 if count > 2:
743 error("More than 2 NAND images for NOR+NAND is not allowed")
744 elif img_size > part_info.length:
745 error("img size is larger than part. len in '%s'" % section_conf)
746 else:
747 if part_info != None:
748 if (img_size > 0):
749 if img_size > (part_info.length * self.flinfo.blocksize):
750 error("img size is larger than part. len in '%s'" % section_conf)
751
752 if part_info == None and self.flinfo.type != 'norplusnand':
753 print "Flash type is norplusemmc"
754 return
755
756 if machid:
757 script.start_if("machid", machid)
758
759 if section_conf == "qsee":
760 section_conf = "tz"
761 elif section_conf == "appsbl":
762 section_conf = "u-boot"
763 elif section_conf == "rootfs" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
764 section_conf = "ubi"
765 elif section_conf == "wififw" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
766 section_conf = "wififw_ubi"
767
768 if soc_version:
769 script.start_if("soc_version_major", soc_version)
770
771 script.start_activity("Flashing %s:" % section_conf)
772
773 if ARCH_NAME == "ipq806x":
774 script.switch_layout(layout)
775 if img_size > 0:
776 filename_pad = filename + ".padded"
777 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
778 script.imxtract(section_conf + "-" + sha1(filename_pad))
779 else:
780 script.imxtract(section_conf + "-" + sha1(filename))
781
782 part_size = Pack.norplusnand_rootfs_img_size
783 if part_info == None:
784 if self.flinfo.type == 'norplusnand':
785 offset = count * Pack.norplusnand_rootfs_img_size
786 img_size = Pack.norplusnand_rootfs_img_size
787 script.nand_write(offset, part_size, img_size, spi_nand)
788 count = count + 1
789 else:
790 if part_info.which_flash == 0:
791 offset = part_info.offset
792 script.erase(offset, part_info.length)
793 script.write(offset, img_size)
794 else:
795 offset = part_info.offset
796 script.nand_write(offset, part_info.length, img_size, spi_nand)
797
798 script.finish_activity()
799
800 if soc_version:
801 script.end_if()
802
803 if machid:
804 script.end_if()
805
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530806 def __gen_flash_script(self, script, flinfo, root):
807 """Generate the script to flash the images.
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530808
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530809 info -- ConfigParser object, containing image flashing info
810 script -- Script object, to append commands to
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530811 """
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530812 global MODE
813 global SRC_DIR
814 global ARCH_NAME
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530815
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530816 diff_files = ""
817 count = 0
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530818 soc_version = 0
819 diff_soc_ver_files = 0
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530820
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530821 if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
822 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
823 else:
824 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
825
826 root_part = ET.parse(srcDir_part)
827 if self.flash_type != "emmc" and flinfo.type != "emmc":
828 parts = root_part.findall(".//partitions/partition")
829 elif self.flash_type != "emmc" and flinfo.type == "emmc":
830 parts = root_part.findall(".//physical_partition[@ref='norplusemmc']/partition")
831 else:
832 parts = root_part.findall(".//physical_partition[@ref='emmc']/partition")
833 if flinfo.type == "emmc":
834 parts_length = len(parts) + 2
835 else:
836 parts_length = len(parts)
837 entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
838
839 first = False
840 section = None
841 part_index = 0
842
843 if flinfo.type == "emmc":
844 first = True
845
846 for index in range(parts_length):
847
848 if first:
849 if self.flash_type == "norplusemmc":
850 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
851 else:
852 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
853 part_fname = part_info.find(".//partition_mbn")
854 filename = part_fname.text
855 partition = "0:GPT"
856 first = False
857
858 elif index == (parts_length - 1) and flinfo.type == "emmc":
859 if self.flash_type == "norplusemmc":
860 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
861 else:
862 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
863 part_fname = part_info.find(".//partition_mbn_backup")
864 filename = part_fname.text
865 partition = "0:GPTBACKUP"
866
867 else:
868 section = parts[part_index]
869 part_index += 1
870 if flinfo.type != "emmc":
871 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530872 if image_type == "all" or section[8].attrib['image_type'] == image_type:
873 filename = section[8].text
874 try:
875 if section[8].attrib['mode'] != MODE:
876 filename = section[9].text
877 else:
878 pass
879 except AttributeError, e:
880 pass
881 except KeyError, e:
882 pass
883 else:
884 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530885 except IndexError, e:
886 if index == (parts_length - 1):
887 return
888 else:
889 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530890 except KeyError, e:
891 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530892 partition = section[0].text
893 else:
894 try:
895 diff_files = section.attrib['diff_files']
896 except KeyError, e:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530897 try:
898 diff_soc_ver_files = section.attrib['diff_soc_ver_files']
899 except KeyError, e:
900 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530901 if image_type == "all" or section.attrib['image_type'] == image_type:
902 filename = section.attrib['filename']
903 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530904 if filename == "":
905 continue
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530906 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530907 print "Skipping partition '%s'" % section.attrib['label']
908 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530909
910 if diff_files == "true":
911 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530912 if image_type == "all" or section.attrib['image_type'] == image_type:
913 filename = section.attrib['filename_' + MODE]
914 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530915 if filename == "":
916 continue
917 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530918 print "Skipping partition '%s'" % section.attrib['label']
919 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530920 diff_files = "" # Clear for next iteration
921
922 # Get machID
923 if partition != "0:CDT" and partition != "0:DDRCONFIG":
924 machid = None
925 else:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530926 try:
927 if image_type == "all" or section.attrib['image_type'] == image_type:
928 self.__gen_flash_script_cdt(entries, partition, flinfo, script)
929 continue
930 except KeyError, e:
931 continue
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530932
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530933 if ARCH_NAME == "ipq806x":
934 # Get Layout
935 try:
936 layout = section[9].text
937 except:
938 layout = None
939
940 if layout not in ("sbl", "linux", None):
941 error("invalid layout in '%s'" % section)
942
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530943 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530944
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530945 img = section.find('img_name')
946 if img != None and 'soc_version' in img.attrib:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530947
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530948 imgs = section.findall('img_name')
949 try:
950 for img in imgs:
951 filename = img.text
952 soc_version = img.get('soc_version')
953 self.__gen_flash_script_image(filename, soc_version, machid, partition, flinfo, script)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530954
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530955 soc_version = 0 # Clear soc_version for next iteration
956 continue
957 except KeyError, e:
958 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530959
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530960 else:
961 if diff_soc_ver_files:
962 try:
963 for version in range(1, int(diff_soc_ver_files)+1):
964 if image_type == "all" or section.attrib['image_type'] == image_type:
965 filename = section.attrib['filename_v' + str(version)]
966 partition = section.attrib['label']
967 if filename == "":
968 continue
969 self.__gen_flash_script_image(filename, version, machid, partition, flinfo, script)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530970
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530971 diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
972 continue
973 except KeyError, e:
974 print "Skipping partition '%s'" % section.attrib['label']
975 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530976
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530977 self.__gen_flash_script_image(filename, soc_version, machid, partition, flinfo, script)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530978
979 def __gen_script_cdt(self, images, flinfo, root, section_conf, partition):
980 global ARCH_NAME
981
982 entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
983
984 for section in entries:
985
986 board = section.find(".//board").text
987 if ARCH_NAME != "ipq806x":
988 try:
989 memory = section.find(".//memory").text
990 except AttributeError, e:
991 memory = "128M16"
992
993 filename = "cdt-" + board + "_" + memory + ".bin"
994 file_info = "ddr-" + board + "_" + memory
995 else:
996 filename = "cdt-" + board + ".bin"
997 file_info = "ddr-" + board
998
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +0530999 part_info = self.__get_part_info(partition)
1000
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +05301001 if part_info == None and self.flinfo.type != 'norplusnand':
1002 continue
1003
1004 if self.flinfo.type == 'nand':
1005 img_size = self.__get_img_size(filename)
1006 size = roundup(img_size, flinfo.pagesize)
1007 if ( size != img_size ):
1008 filename = filename + ".padded"
1009 if self.flinfo.type == 'emmc':
1010 img_size = self.__get_img_size(filename)
1011 size = roundup(img_size, flinfo.blocksize)
1012 if ( size != img_size ):
1013 filename = filename + ".padded"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301014 image_info = ImageInfo(file_info + "-" + sha1(filename),
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301015 filename, "firmware")
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +05301016 if filename.lower() != "none":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301017 if image_info not in images:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301018 images.append(image_info)
1019
1020 def __gen_script_append_images(self, filename, images, flinfo, root, section_conf, partition):
1021
1022 part_info = self.__get_part_info(partition)
1023 if part_info == None and self.flinfo.type != 'norplusnand':
1024 return
1025
1026 if self.flinfo.type == 'nand':
1027 img_size = self.__get_img_size(filename)
1028 size = roundup(img_size, flinfo.pagesize)
1029 if ( size != img_size ):
1030 filename = filename + ".padded"
1031 if self.flinfo.type == 'emmc':
1032 img_size = self.__get_img_size(filename)
1033 size = roundup(img_size, flinfo.blocksize)
1034 if ( size != img_size ):
1035 filename = filename + ".padded"
1036 if section_conf == "qsee":
1037 section_conf = "tz"
1038 elif section_conf == "appsbl":
1039 section_conf = "u-boot"
1040 elif section_conf == "rootfs" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
1041 section_conf = "ubi"
1042 elif section_conf == "wififw" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
1043 section_conf = "wififw_ubi"
1044
1045 image_info = ImageInfo(section_conf + "-" + sha1(filename),
1046 filename, "firmware")
1047 if filename.lower() != "none":
1048 if image_info not in images:
1049 images.append(image_info)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301050
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301051 def __gen_script(self, script_fp, script, images, flinfo, root):
1052 """Generate the script to flash the multi-image blob.
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301053
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301054 script_fp -- file object, to write script to
1055 info_fp -- file object, to read flashing information from
1056 script -- Script object, to append the commands to
1057 images -- list of ImageInfo, appended to, based on images in config
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301058 """
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301059 global MODE
1060 global SRC_DIR
1061
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301062 diff_soc_ver_files = 0
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301063 diff_files = ""
1064 self.__gen_flash_script(script, flinfo, root)
1065 if (self.flash_type == "norplusemmc" and flinfo.type == "emmc") or (self.flash_type != "norplusemmc"):
1066 if flinfo.type == "emmc":
1067 script.start_activity("Flashing rootfs_data:")
1068 part_info = self.partitions["rootfs_data"]
1069 script.erase(part_info.offset, part_info.length)
1070 script.finish_activity()
1071 script.end()
1072
1073 if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
1074 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
1075 else:
1076 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
1077 root_part = ET.parse(srcDir_part)
1078 if self.flash_type != "emmc" and flinfo.type != "emmc":
1079 parts = root_part.findall(".//partitions/partition")
1080 elif self.flash_type != "emmc" and flinfo.type == "emmc":
1081 parts = root_part.findall(".//physical_partition[@ref='norplusemmc']/partition")
1082 else:
1083 parts = root_part.findall(".//physical_partition[@ref='emmc']/partition")
1084 if flinfo.type == "emmc":
1085 parts_length = len(parts) + 2
1086 else:
1087 parts_length = len(parts)
1088
1089 first = False
1090 section = None
1091 part_index = 0
1092
1093 if flinfo.type == "emmc":
1094 first = True
1095
1096 for index in range(parts_length):
1097
1098 if first:
1099 if self.flash_type == "norplusemmc":
1100 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1101 else:
1102 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1103 part_fname = part_info.find(".//partition_mbn")
1104 filename = part_fname.text
1105 partition = "0:GPT"
1106 first = False
1107
1108 elif index == (parts_length - 1) and flinfo.type == "emmc":
1109 if self.flash_type == "norplusemmc":
1110 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1111 else:
1112 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1113 part_fname = part_info.find(".//partition_mbn_backup")
1114 filename = part_fname.text
1115 partition = "0:GPTBACKUP"
1116
1117 else:
1118 section = parts[part_index]
1119 part_index += 1
1120 if flinfo.type != "emmc":
1121 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301122 if image_type == "all" or section[8].attrib['image_type'] == image_type:
1123 filename = section[8].text
1124 try:
1125 if section[8].attrib['mode'] != MODE:
1126 filename = section[9].text
1127 except AttributeError, e:
1128 pass
1129 except KeyError, e:
1130 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301131 except IndexError, e:
1132 if index == (parts_length - 1):
1133 return
1134 else:
1135 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301136 except KeyError, e:
1137 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301138 partition = section[0].text
1139 else:
1140
1141 try:
1142 diff_files = section.attrib['diff_files']
1143 except KeyError, e:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301144 try:
1145 diff_soc_ver_files = section.attrib['diff_soc_ver_files']
1146 partition = section.attrib['label']
1147 except KeyError, e:
1148 try:
1149 if image_type == "all" or section.attrib['image_type'] == image_type:
1150 filename = section.attrib['filename']
1151 partition = section.attrib['label']
1152 if filename == "":
1153 continue
1154 except KeyError, e:
1155 print "Skipping partition '%s'" % section.attrib['label']
1156 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301157
1158 if diff_files == "true":
1159 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301160 if image_type == "all" or section.attrib['image_type'] == image_type:
1161 filename = section.attrib['filename_' + MODE]
1162 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301163 if filename == "":
1164 continue
1165
1166 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301167 print "Skipping partition '%s'" % section.attrib['label']
1168 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301169 diff_files = "" # Clear for next iteration
1170
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301171
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301172 part_info = self.__get_part_info(partition)
1173
1174 section_label = partition.split(":")
1175 if len(section_label) != 1:
1176 section_conf = section_label[1]
1177 else:
1178 section_conf = section_label[0]
1179
1180 section_conf = section_conf.lower()
1181
1182 if section_conf == "cdt" or section_conf == "ddrconfig":
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301183 try:
1184 if image_type == "all" or section[8].attrib['image_type'] == image_type:
1185 self.__gen_script_cdt(images, flinfo, root, section_conf, partition)
1186 continue
1187 except KeyError, e:
1188 continue
1189
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301190 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301191
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301192 img = section.find('img_name')
1193 if img != None and 'soc_version' in img.attrib:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301194
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301195 imgs = section.findall('img_name')
1196 try:
1197 for img in imgs:
1198 filename = img.text
1199 self.__gen_script_append_images(filename, images, flinfo, root, section_conf, partition)
1200 continue
1201 except KeyError, e:
1202 continue
1203
1204 else:
1205 if diff_soc_ver_files:
1206 try:
1207 for version in range(1, int(diff_soc_ver_files)+1):
1208 if image_type == "all" or section.attrib['image_type'] == image_type:
1209 filename = section.attrib['filename_v' + str(version)]
1210 partition = section.attrib['label']
1211 if filename == "":
1212 continue
1213 self.__gen_script_append_images(filename, images, flinfo, root, section_conf, partition)
1214 diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
1215 continue
1216 except KeyError, e:
1217 print "Skipping partition '%s'" % section.attrib['label']
1218 pass
1219
1220 self.__gen_script_append_images(filename, images, flinfo, root, section_conf, partition)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301221
1222 def __mkimage(self, images):
1223 """Create the multi-image blob.
1224
1225 images -- list of ImageInfo, containing images to be part of the blob
1226 """
1227 try:
1228 its_fp = open(self.its_fname, "wb")
1229 except IOError, e:
1230 error("error opening its file '%s'" % self.its_fname, e)
1231
1232 desc = "Flashing %s %x %x"
1233 desc = desc % (self.flinfo.type, self.flinfo.pagesize,
1234 self.flinfo.blocksize)
1235
1236 image_data = []
1237 for (section, fname, imtype) in images:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301238 fname = fname.replace("\\", "\\\\")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301239 subs = dict(name=section, desc=fname, fname=fname, imtype=imtype)
1240 image_data.append(its_image_tmpl.substitute(subs))
1241
1242 image_data = "".join(image_data)
1243 its_data = its_tmpl.substitute(desc=desc, images=image_data)
1244
1245 its_fp.write(its_data)
1246 its_fp.close()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301247
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301248 try:
1249 cmd = ["mkimage", "-f", self.its_fname, self.img_fname]
1250 ret = subprocess.call(cmd)
1251 if ret != 0:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301252 print ret
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301253 error("failed to create u-boot image from script")
1254 except OSError, e:
1255 error("error executing mkimage", e)
1256
1257 def __create_fnames(self):
1258 """Populate the filenames."""
1259
1260 self.scr_fname = os.path.join(self.images_dname, "flash.scr")
1261 self.its_fname = os.path.join(self.images_dname, "flash.its")
1262
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301263 def __gen_board_script(self, flinfo, part_fname, images, root):
1264 global SRC_DIR
1265 global ARCH_NAME
1266
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301267 """Generate the flashing script for one board.
1268
1269 board_section -- string, board section in board config file
1270 machid -- string, board machine ID in hex format
1271 flinfo -- FlashInfo object, contains board specific flash params
1272 part_fname -- string, partition file specific to the board
1273 fconf_fname -- string, flash config file specific to the board
1274 images -- list of ImageInfo, append images used by the board here
1275 """
1276 script_fp = open(self.scr_fname, "a")
1277
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301278 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301279 flash_param = root.find(".//data[@type='NAND_PARAMETER']")
1280 pagesize = int(flash_param.find(".//page_size").text)
1281 pages_per_block = int(flash_param.find(".//pages_per_block").text)
1282 blocksize = pages_per_block * pagesize
1283 blocks_per_chip = int(flash_param.find(".//total_block").text)
1284 chipsize = blocks_per_chip * blocksize
1285
1286 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
1287 root_part = ET.parse(srcDir_part)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301288 mibib = MIBIB(part_fname, flinfo.pagesize, flinfo.blocksize,
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301289 flinfo.chipsize, blocksize, chipsize, root_part)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301290 self.partitions = mibib.get_parts()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301291 if flinfo.type == "nand":
1292 script = Flash_Script(flinfo, self.ipq_nand)
1293 elif flinfo.type == "nor":
1294 script = Flash_Script(flinfo, pagesize)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301295 else:
1296 gpt = GPT(part_fname, flinfo.pagesize, flinfo.blocksize, flinfo.chipsize)
1297 self.partitions = gpt.get_parts()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301298 script = Flash_Script(flinfo)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301299
1300 self.flinfo = flinfo
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301301
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301302 script.probe()
1303 self.__gen_script(script_fp, script, images, flinfo, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301304
1305 try:
1306 script_fp.write(script.dumps())
1307 except IOError, e:
1308 error("error writing to script '%s'" % script_fp.name, e)
1309
1310 script_fp.close()
1311
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301312 def __process_board_flash_emmc(self, ftype, images, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301313 """Extract board info from config and generate the flash script.
1314
1315 ftype -- string, flash type 'emmc'
1316 board_section -- string, board section in config file
1317 machid -- string, board machine ID in hex format
1318 images -- list of ImageInfo, append images used by the board here
1319 """
1320
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301321 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301322 part_info = root.find(".//data[@type='" + self.flash_type.upper() + "_PARAMETER']")
1323 part_fname = part_info.find(".//partition_mbn")
1324 part_fname = part_fname.text
1325 part_fname = os.path.join(self.images_dname, part_fname)
1326 if ftype == "norplusemmc":
1327 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1328 pagesize = int(part_info.find(".//page_size_flash").text)
1329 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1330 else:
1331 pagesize = self.emmc_page_size
1332 blocksize = self.emmc_block_size
1333 chipsize = int(part_info.find(".//total_block").text)
1334 if ftype.lower() == "norplusemmc":
1335 ftype = "emmc"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301336
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301337 except ValueError, e:
1338 error("invalid flash info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301339
1340 flinfo = FlashInfo(ftype, pagesize, blocksize, chipsize)
1341
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301342 self.__gen_board_script(flinfo, part_fname, images, root)
1343
1344 def __process_board_flash(self, ftype, images, root):
1345 global SRC_DIR
1346 global ARCH_NAME
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301347
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301348 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301349 part_info = root.find(".//data[@type='" + ftype.upper() + "_PARAMETER']")
1350 part_file = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + ftype + "-partition.xml"
1351 part_xml = ET.parse(part_file)
1352 partition = part_xml.find(".//partitions/partition[2]")
1353 part_fname = partition[8].text
1354 part_fname = os.path.join(self.images_dname, part_fname)
1355 pagesize = int(part_info.find(".//page_size").text)
1356 pages_per_block = int(part_info.find(".//pages_per_block").text)
1357 blocks_per_chip = int(part_info.find(".//total_block").text)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301358
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301359 if ftype == "norplusnand" or ftype == "norplusemmc":
1360 ftype = "nor"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301361
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301362 except ValueError, e:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301363 error("invalid flash info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301364
1365 blocksize = pages_per_block * pagesize
1366 chipsize = blocks_per_chip * blocksize
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301367
1368 flinfo = FlashInfo(ftype, pagesize, blocksize, chipsize)
1369
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301370 self.__gen_board_script(flinfo, part_fname, images, root)
1371
1372 def __process_board(self, images, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301373
1374 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301375 if self.flash_type in [ "nand", "nor", "norplusnand" ]:
1376 self.__process_board_flash(self.flash_type, images, root)
1377 elif self.flash_type == "emmc":
1378 self.__process_board_flash_emmc(self.flash_type, images, root)
1379 elif self.flash_type == "norplusemmc":
1380 self.__process_board_flash("norplusemmc", images, root)
1381 self.__process_board_flash_emmc("norplusemmc", images, root)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301382 except ValueError, e:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301383 error("error getting board info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301384
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301385 def main_bconf(self, flash_type, images_dname, out_fname, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301386 """Start the packing process, using board config.
1387
1388 flash_type -- string, indicates flash type, 'nand' or 'nor' or 'emmc' or 'norplusnand'
1389 images_dname -- string, name of images directory
1390 out_fname -- string, output file path
1391 """
1392 self.flash_type = flash_type
1393 self.images_dname = images_dname
1394 self.img_fname = out_fname
1395
1396 self.__create_fnames()
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301397 try:
1398 os.unlink(self.scr_fname)
1399 except OSError, e:
1400 pass
1401
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301402 images = []
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301403 self.__process_board(images, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301404 images.insert(0, ImageInfo("script", "flash.scr", "script"))
1405 self.__mkimage(images)
1406
1407class UsageError(Exception):
1408 """Indicates error in command arguments."""
1409 pass
1410
1411class ArgParser(object):
1412 """Class to parse command-line arguments."""
1413
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301414 DEFAULT_TYPE = "nor,nand,norplusnand,emmc,norplusemmc"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301415
1416 def __init__(self):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301417 self.flash_type = None
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301418 self.images_dname = None
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301419 self.out_dname = None
1420 self.scr_fname = None
1421 self.its_fname = None
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301422
1423 def parse(self, argv):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301424 global MODE
1425 global SRC_DIR
1426 global ARCH_NAME
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301427 global image_type
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301428
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301429 """Start the parsing process, and populate members with parsed value.
1430
1431 argv -- list of string, the command line arguments
1432 """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301433
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301434 cdir = os.path.abspath(os.path.dirname(""))
1435 if len(sys.argv) > 1:
1436 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301437 opts, args = getopt(sys.argv[1:], "", ["arch=", "fltype=", "srcPath=", "inImage=", "outImage=", "image_type="])
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301438 except GetoptError, e:
1439 raise UsageError(e.msg)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301440
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301441 for option, value in opts:
1442 if option == "--arch":
1443 ARCH_NAME = value
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301444
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301445 elif option == "--fltype":
1446 self.flash_type = value
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301447
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301448 elif option == "--srcPath":
1449 SRC_DIR = os.path.abspath(value)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301450
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301451 elif option == "--inImage":
1452 self.images_dname = os.path.join(cdir, value)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301453
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301454 elif option == "--outImage":
1455 self.out_dname = os.path.join(cdir, value)
1456
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301457 elif option == "--image_type":
1458 image_type = value
1459
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301460#Verify Arguments passed by user
1461
1462# Verify arch type
1463 if ARCH_NAME not in ["ipq40xx", "ipq806x", "ipq807x", "ipq807x_64"]:
1464 raise UsageError("Invalid arch type '%s'" % arch)
1465
1466 if ARCH_NAME == "ipq807x":
1467 MODE = "32"
1468 elif ARCH_NAME == "ipq807x_64":
1469 MODE = "64"
1470 ARCH_NAME = "ipq807x"
1471
1472# Set flash type to default type (nand) if not given by user
1473 if self.flash_type == None:
1474 self.flash_type = ArgParser.DEFAULT_TYPE
1475 for flash_type in self.flash_type.split(","):
1476 if flash_type not in [ "nand", "nor", "emmc", "norplusnand", "norplusemmc" ]:
1477 raise UsageError("invalid flash type '%s'" % flash_type)
1478
1479# Verify src Path
1480 if SRC_DIR == "":
1481 raise UsageError("Source Path is not provided")
1482
1483#Verify input image path
1484 if self.images_dname == None:
1485 raise UsageError("input images' Path is not provided")
1486
1487#Verify Output image path
1488 if self.out_dname == None:
1489 raise UsageError("Output Path is not provided")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301490
1491 def usage(self, msg):
1492 """Print error message and command usage information.
1493
1494 msg -- string, the error message
1495 """
1496 print "pack: %s" % msg
1497 print
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301498 print "Usage:"
1499 print "python pack_hk.py [options] [Value] ..."
1500 print
1501 print "options:"
1502 print " --arch \tARCH_TYPE [ipq40xx/ipq806x/ipq807x/ipq807x_64]"
1503 print
1504 print " --fltype \tFlash Type [nor/nand/emmc/norplusnand/norplusemmc]"
1505 print " \t\tMultiple flashtypes can be passed by a comma separated string"
1506 print " \t\tDefault is all. i.e If \"--fltype\" is not passed image for all the flash-type will be created.\n"
1507 print " --srcPath \tPath to the directory containg the meta scripts and configs"
1508 print
1509 print " --inImage \tPath to the direcory containg binaries and images needed for singleimage"
1510 print
1511 print " --outImage \tPath to the directory where single image will be generated"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301512 print
1513 print "Pack Version: %s" % version
1514
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301515def main():
1516 """Main script entry point.
1517
1518 Created to avoid polluting the global namespace.
1519 """
1520 try:
1521 parser = ArgParser()
1522 parser.parse(sys.argv)
1523 except UsageError, e:
1524 parser.usage(e.args[0])
1525 sys.exit(1)
1526
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301527 pack = Pack()
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301528
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301529 if not os.path.exists(parser.out_dname):
1530 os.makedirs(parser.out_dname)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301531
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301532 config = SRC_DIR + "/" + ARCH_NAME + "/config.xml"
1533 root = ET.parse(config)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301534
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301535# Format the output image name from Arch, flash type and mode
1536 for flash_type in parser.flash_type.split(","):
1537 if MODE == "64":
1538 parser.out_fname = flash_type + "-" + ARCH_NAME + "_" + MODE + "-single.img"
1539 else:
1540 parser.out_fname = flash_type + "-" + ARCH_NAME + "-single.img"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301541
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301542 parser.out_fname = os.path.join(parser.out_dname, parser.out_fname)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301543
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301544 pack.main_bconf(flash_type, parser.images_dname,
1545 parser.out_fname, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301546
1547if __name__ == "__main__":
1548 main()