blob: 6112d666792e4ce097935efd9a29342499f2aa11 [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:
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +0530769 section_conf = section_conf + "_v" + str(soc_version)
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530770 script.start_if("soc_version_major", soc_version)
771
772 script.start_activity("Flashing %s:" % section_conf)
773
774 if ARCH_NAME == "ipq806x":
775 script.switch_layout(layout)
776 if img_size > 0:
777 filename_pad = filename + ".padded"
778 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
779 script.imxtract(section_conf + "-" + sha1(filename_pad))
780 else:
781 script.imxtract(section_conf + "-" + sha1(filename))
782
783 part_size = Pack.norplusnand_rootfs_img_size
784 if part_info == None:
785 if self.flinfo.type == 'norplusnand':
786 offset = count * Pack.norplusnand_rootfs_img_size
787 img_size = Pack.norplusnand_rootfs_img_size
788 script.nand_write(offset, part_size, img_size, spi_nand)
789 count = count + 1
790 else:
791 if part_info.which_flash == 0:
792 offset = part_info.offset
793 script.erase(offset, part_info.length)
794 script.write(offset, img_size)
795 else:
796 offset = part_info.offset
797 script.nand_write(offset, part_info.length, img_size, spi_nand)
798
799 script.finish_activity()
800
801 if soc_version:
802 script.end_if()
803
804 if machid:
805 script.end_if()
806
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530807 def __gen_flash_script(self, script, flinfo, root):
808 """Generate the script to flash the images.
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530809
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530810 info -- ConfigParser object, containing image flashing info
811 script -- Script object, to append commands to
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530812 """
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530813 global MODE
814 global SRC_DIR
815 global ARCH_NAME
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530816
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530817 diff_files = ""
818 count = 0
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530819 soc_version = 0
820 diff_soc_ver_files = 0
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530821
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530822 if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
823 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
824 else:
825 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
826
827 root_part = ET.parse(srcDir_part)
828 if self.flash_type != "emmc" and flinfo.type != "emmc":
829 parts = root_part.findall(".//partitions/partition")
830 elif self.flash_type != "emmc" and flinfo.type == "emmc":
831 parts = root_part.findall(".//physical_partition[@ref='norplusemmc']/partition")
832 else:
833 parts = root_part.findall(".//physical_partition[@ref='emmc']/partition")
834 if flinfo.type == "emmc":
835 parts_length = len(parts) + 2
836 else:
837 parts_length = len(parts)
838 entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
839
840 first = False
841 section = None
842 part_index = 0
843
844 if flinfo.type == "emmc":
845 first = True
846
847 for index in range(parts_length):
848
849 if first:
850 if self.flash_type == "norplusemmc":
851 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
852 else:
853 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
854 part_fname = part_info.find(".//partition_mbn")
855 filename = part_fname.text
856 partition = "0:GPT"
857 first = False
858
859 elif index == (parts_length - 1) and flinfo.type == "emmc":
860 if self.flash_type == "norplusemmc":
861 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
862 else:
863 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
864 part_fname = part_info.find(".//partition_mbn_backup")
865 filename = part_fname.text
866 partition = "0:GPTBACKUP"
867
868 else:
869 section = parts[part_index]
870 part_index += 1
871 if flinfo.type != "emmc":
872 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530873 if image_type == "all" or section[8].attrib['image_type'] == image_type:
874 filename = section[8].text
875 try:
876 if section[8].attrib['mode'] != MODE:
877 filename = section[9].text
878 else:
879 pass
880 except AttributeError, e:
881 pass
882 except KeyError, e:
883 pass
884 else:
885 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530886 except IndexError, e:
887 if index == (parts_length - 1):
888 return
889 else:
890 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530891 except KeyError, e:
892 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530893 partition = section[0].text
894 else:
895 try:
896 diff_files = section.attrib['diff_files']
897 except KeyError, e:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530898 try:
899 diff_soc_ver_files = section.attrib['diff_soc_ver_files']
900 except KeyError, e:
901 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530902 if image_type == "all" or section.attrib['image_type'] == image_type:
903 filename = section.attrib['filename']
904 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530905 if filename == "":
906 continue
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530907 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530908 print "Skipping partition '%s'" % section.attrib['label']
909 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530910
911 if diff_files == "true":
912 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530913 if image_type == "all" or section.attrib['image_type'] == image_type:
914 filename = section.attrib['filename_' + MODE]
915 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530916 if filename == "":
917 continue
918 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530919 print "Skipping partition '%s'" % section.attrib['label']
920 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530921 diff_files = "" # Clear for next iteration
922
923 # Get machID
924 if partition != "0:CDT" and partition != "0:DDRCONFIG":
925 machid = None
926 else:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530927 try:
928 if image_type == "all" or section.attrib['image_type'] == image_type:
929 self.__gen_flash_script_cdt(entries, partition, flinfo, script)
930 continue
931 except KeyError, e:
932 continue
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530933
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530934 if ARCH_NAME == "ipq806x":
935 # Get Layout
936 try:
937 layout = section[9].text
938 except:
939 layout = None
940
941 if layout not in ("sbl", "linux", None):
942 error("invalid layout in '%s'" % section)
943
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530944 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530945
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530946 img = section.find('img_name')
947 if img != None and 'soc_version' in img.attrib:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530948
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530949 imgs = section.findall('img_name')
950 try:
951 for img in imgs:
952 filename = img.text
953 soc_version = img.get('soc_version')
954 self.__gen_flash_script_image(filename, soc_version, machid, partition, flinfo, script)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530955
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530956 soc_version = 0 # Clear soc_version for next iteration
957 continue
958 except KeyError, e:
959 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530960
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530961 else:
962 if diff_soc_ver_files:
963 try:
964 for version in range(1, int(diff_soc_ver_files)+1):
965 if image_type == "all" or section.attrib['image_type'] == image_type:
966 filename = section.attrib['filename_v' + str(version)]
967 partition = section.attrib['label']
968 if filename == "":
969 continue
970 self.__gen_flash_script_image(filename, version, machid, partition, flinfo, script)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530971
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530972 diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
973 continue
974 except KeyError, e:
975 print "Skipping partition '%s'" % section.attrib['label']
976 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530977
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530978 self.__gen_flash_script_image(filename, soc_version, machid, partition, flinfo, script)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530979
980 def __gen_script_cdt(self, images, flinfo, root, section_conf, partition):
981 global ARCH_NAME
982
983 entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
984
985 for section in entries:
986
987 board = section.find(".//board").text
988 if ARCH_NAME != "ipq806x":
989 try:
990 memory = section.find(".//memory").text
991 except AttributeError, e:
992 memory = "128M16"
993
994 filename = "cdt-" + board + "_" + memory + ".bin"
995 file_info = "ddr-" + board + "_" + memory
996 else:
997 filename = "cdt-" + board + ".bin"
998 file_info = "ddr-" + board
999
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301000 part_info = self.__get_part_info(partition)
1001
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +05301002 if part_info == None and self.flinfo.type != 'norplusnand':
1003 continue
1004
1005 if self.flinfo.type == 'nand':
1006 img_size = self.__get_img_size(filename)
1007 size = roundup(img_size, flinfo.pagesize)
1008 if ( size != img_size ):
1009 filename = filename + ".padded"
1010 if self.flinfo.type == 'emmc':
1011 img_size = self.__get_img_size(filename)
1012 size = roundup(img_size, flinfo.blocksize)
1013 if ( size != img_size ):
1014 filename = filename + ".padded"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301015 image_info = ImageInfo(file_info + "-" + sha1(filename),
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301016 filename, "firmware")
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +05301017 if filename.lower() != "none":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301018 if image_info not in images:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301019 images.append(image_info)
1020
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301021 def __gen_script_append_images(self, filename, soc_version, images, flinfo, root, section_conf, partition):
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301022
1023 part_info = self.__get_part_info(partition)
1024 if part_info == None and self.flinfo.type != 'norplusnand':
1025 return
1026
1027 if self.flinfo.type == 'nand':
1028 img_size = self.__get_img_size(filename)
1029 size = roundup(img_size, flinfo.pagesize)
1030 if ( size != img_size ):
1031 filename = filename + ".padded"
1032 if self.flinfo.type == 'emmc':
1033 img_size = self.__get_img_size(filename)
1034 size = roundup(img_size, flinfo.blocksize)
1035 if ( size != img_size ):
1036 filename = filename + ".padded"
1037 if section_conf == "qsee":
1038 section_conf = "tz"
1039 elif section_conf == "appsbl":
1040 section_conf = "u-boot"
1041 elif section_conf == "rootfs" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
1042 section_conf = "ubi"
1043 elif section_conf == "wififw" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
1044 section_conf = "wififw_ubi"
1045
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301046 if soc_version:
1047 section_conf = section_conf + "_v" + str(soc_version)
1048
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301049 image_info = ImageInfo(section_conf + "-" + sha1(filename),
1050 filename, "firmware")
1051 if filename.lower() != "none":
1052 if image_info not in images:
1053 images.append(image_info)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301054
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301055 def __gen_script(self, script_fp, script, images, flinfo, root):
1056 """Generate the script to flash the multi-image blob.
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301057
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301058 script_fp -- file object, to write script to
1059 info_fp -- file object, to read flashing information from
1060 script -- Script object, to append the commands to
1061 images -- list of ImageInfo, appended to, based on images in config
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301062 """
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301063 global MODE
1064 global SRC_DIR
1065
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301066 soc_version = 0
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301067 diff_soc_ver_files = 0
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301068 diff_files = ""
1069 self.__gen_flash_script(script, flinfo, root)
1070 if (self.flash_type == "norplusemmc" and flinfo.type == "emmc") or (self.flash_type != "norplusemmc"):
1071 if flinfo.type == "emmc":
1072 script.start_activity("Flashing rootfs_data:")
1073 part_info = self.partitions["rootfs_data"]
1074 script.erase(part_info.offset, part_info.length)
1075 script.finish_activity()
1076 script.end()
1077
1078 if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
1079 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
1080 else:
1081 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
1082 root_part = ET.parse(srcDir_part)
1083 if self.flash_type != "emmc" and flinfo.type != "emmc":
1084 parts = root_part.findall(".//partitions/partition")
1085 elif self.flash_type != "emmc" and flinfo.type == "emmc":
1086 parts = root_part.findall(".//physical_partition[@ref='norplusemmc']/partition")
1087 else:
1088 parts = root_part.findall(".//physical_partition[@ref='emmc']/partition")
1089 if flinfo.type == "emmc":
1090 parts_length = len(parts) + 2
1091 else:
1092 parts_length = len(parts)
1093
1094 first = False
1095 section = None
1096 part_index = 0
1097
1098 if flinfo.type == "emmc":
1099 first = True
1100
1101 for index in range(parts_length):
1102
1103 if first:
1104 if self.flash_type == "norplusemmc":
1105 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1106 else:
1107 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1108 part_fname = part_info.find(".//partition_mbn")
1109 filename = part_fname.text
1110 partition = "0:GPT"
1111 first = False
1112
1113 elif index == (parts_length - 1) and flinfo.type == "emmc":
1114 if self.flash_type == "norplusemmc":
1115 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1116 else:
1117 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1118 part_fname = part_info.find(".//partition_mbn_backup")
1119 filename = part_fname.text
1120 partition = "0:GPTBACKUP"
1121
1122 else:
1123 section = parts[part_index]
1124 part_index += 1
1125 if flinfo.type != "emmc":
1126 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301127 if image_type == "all" or section[8].attrib['image_type'] == image_type:
1128 filename = section[8].text
1129 try:
1130 if section[8].attrib['mode'] != MODE:
1131 filename = section[9].text
1132 except AttributeError, e:
1133 pass
1134 except KeyError, e:
1135 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301136 except IndexError, e:
1137 if index == (parts_length - 1):
1138 return
1139 else:
1140 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301141 except KeyError, e:
1142 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301143 partition = section[0].text
1144 else:
1145
1146 try:
1147 diff_files = section.attrib['diff_files']
1148 except KeyError, e:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301149 try:
1150 diff_soc_ver_files = section.attrib['diff_soc_ver_files']
1151 partition = section.attrib['label']
1152 except KeyError, e:
1153 try:
1154 if image_type == "all" or section.attrib['image_type'] == image_type:
1155 filename = section.attrib['filename']
1156 partition = section.attrib['label']
1157 if filename == "":
1158 continue
1159 except KeyError, e:
1160 print "Skipping partition '%s'" % section.attrib['label']
1161 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301162
1163 if diff_files == "true":
1164 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301165 if image_type == "all" or section.attrib['image_type'] == image_type:
1166 filename = section.attrib['filename_' + MODE]
1167 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301168 if filename == "":
1169 continue
1170
1171 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301172 print "Skipping partition '%s'" % section.attrib['label']
1173 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301174 diff_files = "" # Clear for next iteration
1175
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301176
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301177 part_info = self.__get_part_info(partition)
1178
1179 section_label = partition.split(":")
1180 if len(section_label) != 1:
1181 section_conf = section_label[1]
1182 else:
1183 section_conf = section_label[0]
1184
1185 section_conf = section_conf.lower()
1186
1187 if section_conf == "cdt" or section_conf == "ddrconfig":
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301188 try:
1189 if image_type == "all" or section[8].attrib['image_type'] == image_type:
1190 self.__gen_script_cdt(images, flinfo, root, section_conf, partition)
1191 continue
1192 except KeyError, e:
1193 continue
1194
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301195 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301196
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301197 img = section.find('img_name')
1198 if img != None and 'soc_version' in img.attrib:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301199
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301200 imgs = section.findall('img_name')
1201 try:
1202 for img in imgs:
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301203 soc_version = img.get('soc_version')
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301204 filename = img.text
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301205 self.__gen_script_append_images(filename, soc_version, images, flinfo, root, section_conf, partition)
1206 soc_version = 0 # Clear soc_version for next iteration
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301207 continue
1208 except KeyError, e:
1209 continue
1210
1211 else:
1212 if diff_soc_ver_files:
1213 try:
1214 for version in range(1, int(diff_soc_ver_files)+1):
1215 if image_type == "all" or section.attrib['image_type'] == image_type:
1216 filename = section.attrib['filename_v' + str(version)]
1217 partition = section.attrib['label']
1218 if filename == "":
1219 continue
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301220 self.__gen_script_append_images(filename, version, images, flinfo, root, section_conf, partition)
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301221 diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
1222 continue
1223 except KeyError, e:
1224 print "Skipping partition '%s'" % section.attrib['label']
1225 pass
1226
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301227 self.__gen_script_append_images(filename, soc_version, images, flinfo, root, section_conf, partition)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301228
1229 def __mkimage(self, images):
1230 """Create the multi-image blob.
1231
1232 images -- list of ImageInfo, containing images to be part of the blob
1233 """
1234 try:
1235 its_fp = open(self.its_fname, "wb")
1236 except IOError, e:
1237 error("error opening its file '%s'" % self.its_fname, e)
1238
1239 desc = "Flashing %s %x %x"
1240 desc = desc % (self.flinfo.type, self.flinfo.pagesize,
1241 self.flinfo.blocksize)
1242
1243 image_data = []
1244 for (section, fname, imtype) in images:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301245 fname = fname.replace("\\", "\\\\")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301246 subs = dict(name=section, desc=fname, fname=fname, imtype=imtype)
1247 image_data.append(its_image_tmpl.substitute(subs))
1248
1249 image_data = "".join(image_data)
1250 its_data = its_tmpl.substitute(desc=desc, images=image_data)
1251
1252 its_fp.write(its_data)
1253 its_fp.close()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301254
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301255 try:
1256 cmd = ["mkimage", "-f", self.its_fname, self.img_fname]
1257 ret = subprocess.call(cmd)
1258 if ret != 0:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301259 print ret
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301260 error("failed to create u-boot image from script")
1261 except OSError, e:
1262 error("error executing mkimage", e)
1263
1264 def __create_fnames(self):
1265 """Populate the filenames."""
1266
1267 self.scr_fname = os.path.join(self.images_dname, "flash.scr")
1268 self.its_fname = os.path.join(self.images_dname, "flash.its")
1269
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301270 def __gen_board_script(self, flinfo, part_fname, images, root):
1271 global SRC_DIR
1272 global ARCH_NAME
1273
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301274 """Generate the flashing script for one board.
1275
1276 board_section -- string, board section in board config file
1277 machid -- string, board machine ID in hex format
1278 flinfo -- FlashInfo object, contains board specific flash params
1279 part_fname -- string, partition file specific to the board
1280 fconf_fname -- string, flash config file specific to the board
1281 images -- list of ImageInfo, append images used by the board here
1282 """
1283 script_fp = open(self.scr_fname, "a")
1284
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301285 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301286 flash_param = root.find(".//data[@type='NAND_PARAMETER']")
1287 pagesize = int(flash_param.find(".//page_size").text)
1288 pages_per_block = int(flash_param.find(".//pages_per_block").text)
1289 blocksize = pages_per_block * pagesize
1290 blocks_per_chip = int(flash_param.find(".//total_block").text)
1291 chipsize = blocks_per_chip * blocksize
1292
1293 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
1294 root_part = ET.parse(srcDir_part)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301295 mibib = MIBIB(part_fname, flinfo.pagesize, flinfo.blocksize,
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301296 flinfo.chipsize, blocksize, chipsize, root_part)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301297 self.partitions = mibib.get_parts()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301298 if flinfo.type == "nand":
1299 script = Flash_Script(flinfo, self.ipq_nand)
1300 elif flinfo.type == "nor":
1301 script = Flash_Script(flinfo, pagesize)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301302 else:
1303 gpt = GPT(part_fname, flinfo.pagesize, flinfo.blocksize, flinfo.chipsize)
1304 self.partitions = gpt.get_parts()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301305 script = Flash_Script(flinfo)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301306
1307 self.flinfo = flinfo
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301308
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301309 script.probe()
1310 self.__gen_script(script_fp, script, images, flinfo, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301311
1312 try:
1313 script_fp.write(script.dumps())
1314 except IOError, e:
1315 error("error writing to script '%s'" % script_fp.name, e)
1316
1317 script_fp.close()
1318
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301319 def __process_board_flash_emmc(self, ftype, images, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301320 """Extract board info from config and generate the flash script.
1321
1322 ftype -- string, flash type 'emmc'
1323 board_section -- string, board section in config file
1324 machid -- string, board machine ID in hex format
1325 images -- list of ImageInfo, append images used by the board here
1326 """
1327
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301328 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301329 part_info = root.find(".//data[@type='" + self.flash_type.upper() + "_PARAMETER']")
1330 part_fname = part_info.find(".//partition_mbn")
1331 part_fname = part_fname.text
1332 part_fname = os.path.join(self.images_dname, part_fname)
1333 if ftype == "norplusemmc":
1334 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1335 pagesize = int(part_info.find(".//page_size_flash").text)
1336 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1337 else:
1338 pagesize = self.emmc_page_size
1339 blocksize = self.emmc_block_size
1340 chipsize = int(part_info.find(".//total_block").text)
1341 if ftype.lower() == "norplusemmc":
1342 ftype = "emmc"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301343
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301344 except ValueError, e:
1345 error("invalid flash info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301346
1347 flinfo = FlashInfo(ftype, pagesize, blocksize, chipsize)
1348
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301349 self.__gen_board_script(flinfo, part_fname, images, root)
1350
1351 def __process_board_flash(self, ftype, images, root):
1352 global SRC_DIR
1353 global ARCH_NAME
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301354
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301355 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301356 part_info = root.find(".//data[@type='" + ftype.upper() + "_PARAMETER']")
1357 part_file = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + ftype + "-partition.xml"
1358 part_xml = ET.parse(part_file)
1359 partition = part_xml.find(".//partitions/partition[2]")
1360 part_fname = partition[8].text
1361 part_fname = os.path.join(self.images_dname, part_fname)
1362 pagesize = int(part_info.find(".//page_size").text)
1363 pages_per_block = int(part_info.find(".//pages_per_block").text)
1364 blocks_per_chip = int(part_info.find(".//total_block").text)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301365
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301366 if ftype == "norplusnand" or ftype == "norplusemmc":
1367 ftype = "nor"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301368
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301369 except ValueError, e:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301370 error("invalid flash info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301371
1372 blocksize = pages_per_block * pagesize
1373 chipsize = blocks_per_chip * blocksize
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301374
1375 flinfo = FlashInfo(ftype, pagesize, blocksize, chipsize)
1376
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301377 self.__gen_board_script(flinfo, part_fname, images, root)
1378
1379 def __process_board(self, images, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301380
1381 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301382 if self.flash_type in [ "nand", "nor", "norplusnand" ]:
1383 self.__process_board_flash(self.flash_type, images, root)
1384 elif self.flash_type == "emmc":
1385 self.__process_board_flash_emmc(self.flash_type, images, root)
1386 elif self.flash_type == "norplusemmc":
1387 self.__process_board_flash("norplusemmc", images, root)
1388 self.__process_board_flash_emmc("norplusemmc", images, root)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301389 except ValueError, e:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301390 error("error getting board info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301391
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301392 def main_bconf(self, flash_type, images_dname, out_fname, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301393 """Start the packing process, using board config.
1394
1395 flash_type -- string, indicates flash type, 'nand' or 'nor' or 'emmc' or 'norplusnand'
1396 images_dname -- string, name of images directory
1397 out_fname -- string, output file path
1398 """
1399 self.flash_type = flash_type
1400 self.images_dname = images_dname
1401 self.img_fname = out_fname
1402
1403 self.__create_fnames()
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301404 try:
1405 os.unlink(self.scr_fname)
1406 except OSError, e:
1407 pass
1408
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301409 images = []
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301410 self.__process_board(images, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301411 images.insert(0, ImageInfo("script", "flash.scr", "script"))
1412 self.__mkimage(images)
1413
1414class UsageError(Exception):
1415 """Indicates error in command arguments."""
1416 pass
1417
1418class ArgParser(object):
1419 """Class to parse command-line arguments."""
1420
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301421 DEFAULT_TYPE = "nor,nand,norplusnand,emmc,norplusemmc"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301422
1423 def __init__(self):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301424 self.flash_type = None
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301425 self.images_dname = None
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301426 self.out_dname = None
1427 self.scr_fname = None
1428 self.its_fname = None
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301429
1430 def parse(self, argv):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301431 global MODE
1432 global SRC_DIR
1433 global ARCH_NAME
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301434 global image_type
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301435
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301436 """Start the parsing process, and populate members with parsed value.
1437
1438 argv -- list of string, the command line arguments
1439 """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301440
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301441 cdir = os.path.abspath(os.path.dirname(""))
1442 if len(sys.argv) > 1:
1443 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301444 opts, args = getopt(sys.argv[1:], "", ["arch=", "fltype=", "srcPath=", "inImage=", "outImage=", "image_type="])
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301445 except GetoptError, e:
1446 raise UsageError(e.msg)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301447
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301448 for option, value in opts:
1449 if option == "--arch":
1450 ARCH_NAME = value
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301451
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301452 elif option == "--fltype":
1453 self.flash_type = value
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301454
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301455 elif option == "--srcPath":
1456 SRC_DIR = os.path.abspath(value)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301457
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301458 elif option == "--inImage":
1459 self.images_dname = os.path.join(cdir, value)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301460
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301461 elif option == "--outImage":
1462 self.out_dname = os.path.join(cdir, value)
1463
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301464 elif option == "--image_type":
1465 image_type = value
1466
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301467#Verify Arguments passed by user
1468
1469# Verify arch type
1470 if ARCH_NAME not in ["ipq40xx", "ipq806x", "ipq807x", "ipq807x_64"]:
1471 raise UsageError("Invalid arch type '%s'" % arch)
1472
1473 if ARCH_NAME == "ipq807x":
1474 MODE = "32"
1475 elif ARCH_NAME == "ipq807x_64":
1476 MODE = "64"
1477 ARCH_NAME = "ipq807x"
1478
1479# Set flash type to default type (nand) if not given by user
1480 if self.flash_type == None:
1481 self.flash_type = ArgParser.DEFAULT_TYPE
1482 for flash_type in self.flash_type.split(","):
1483 if flash_type not in [ "nand", "nor", "emmc", "norplusnand", "norplusemmc" ]:
1484 raise UsageError("invalid flash type '%s'" % flash_type)
1485
1486# Verify src Path
1487 if SRC_DIR == "":
1488 raise UsageError("Source Path is not provided")
1489
1490#Verify input image path
1491 if self.images_dname == None:
1492 raise UsageError("input images' Path is not provided")
1493
1494#Verify Output image path
1495 if self.out_dname == None:
1496 raise UsageError("Output Path is not provided")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301497
1498 def usage(self, msg):
1499 """Print error message and command usage information.
1500
1501 msg -- string, the error message
1502 """
1503 print "pack: %s" % msg
1504 print
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301505 print "Usage:"
1506 print "python pack_hk.py [options] [Value] ..."
1507 print
1508 print "options:"
1509 print " --arch \tARCH_TYPE [ipq40xx/ipq806x/ipq807x/ipq807x_64]"
1510 print
1511 print " --fltype \tFlash Type [nor/nand/emmc/norplusnand/norplusemmc]"
1512 print " \t\tMultiple flashtypes can be passed by a comma separated string"
1513 print " \t\tDefault is all. i.e If \"--fltype\" is not passed image for all the flash-type will be created.\n"
1514 print " --srcPath \tPath to the directory containg the meta scripts and configs"
1515 print
1516 print " --inImage \tPath to the direcory containg binaries and images needed for singleimage"
1517 print
1518 print " --outImage \tPath to the directory where single image will be generated"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301519 print
1520 print "Pack Version: %s" % version
1521
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301522def main():
1523 """Main script entry point.
1524
1525 Created to avoid polluting the global namespace.
1526 """
1527 try:
1528 parser = ArgParser()
1529 parser.parse(sys.argv)
1530 except UsageError, e:
1531 parser.usage(e.args[0])
1532 sys.exit(1)
1533
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301534 pack = Pack()
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301535
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301536 if not os.path.exists(parser.out_dname):
1537 os.makedirs(parser.out_dname)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301538
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301539 config = SRC_DIR + "/" + ARCH_NAME + "/config.xml"
1540 root = ET.parse(config)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301541
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301542# Format the output image name from Arch, flash type and mode
1543 for flash_type in parser.flash_type.split(","):
1544 if MODE == "64":
1545 parser.out_fname = flash_type + "-" + ARCH_NAME + "_" + MODE + "-single.img"
1546 else:
1547 parser.out_fname = flash_type + "-" + ARCH_NAME + "-single.img"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301548
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301549 parser.out_fname = os.path.join(parser.out_dname, parser.out_fname)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301550
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301551 pack.main_bconf(flash_type, parser.images_dname,
1552 parser.out_fname, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301553
1554if __name__ == "__main__":
1555 main()