blob: ed35e808a51698278b647d9efa6c4ae354ea185f [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
Gokul Sriram Palanisamyae792312019-01-22 14:33:15 +053072from shutil import copy
73from shutil import rmtree
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053074
75import os
76import sys
77import os.path
78import subprocess
79import struct
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053080import hashlib
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +053081import xml.etree.ElementTree as ET
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053082
83version = "1.1"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +053084ARCH_NAME = ""
85SRC_DIR = ""
86MODE = ""
Saravanan Jaganathan7d086402017-09-22 15:35:01 +053087image_type = "all"
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +053088lk = "false"
89
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +053090#
91# Python 2.6 and earlier did not have OrderedDict use the backport
92# from ordereddict package. If that is not available report error.
93#
94try:
95 from collections import OrderedDict
96except ImportError:
97 try:
98 from ordereddict import OrderedDict
99 except ImportError:
100 print "error: this script requires the 'ordereddict' class."
101 print "Try 'pip install --user ordereddict'"
102 print "Or 'easy_install --user ordereddict'"
103 sys.exit(1)
104
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530105def error(msg, ex=None):
106 """Print an error message and exit.
107
108 msg -- string, the message to print
109 ex -- exception, the associate exception, if any
110 """
111
112 sys.stderr.write("pack: %s" % msg)
113 if ex != None: sys.stderr.write(": %s" % str(ex))
114 sys.stderr.write("\n")
115 sys.exit(1)
116
117FlashInfo = namedtuple("FlashInfo", "type pagesize blocksize chipsize")
118ImageInfo = namedtuple("ProgInfo", "name filename type")
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530119PartInfo = namedtuple("PartInfo", "name offset length which_flash")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530120
121def roundup(value, roundto):
122 """Return the next largest multiple of 'roundto'."""
123
124 return ((value + roundto - 1) // roundto) * roundto
125
126class GPT(object):
127 GPTheader = namedtuple("GPTheader", "signature revision header_size"
128 " crc32 current_lba backup_lba first_usable_lba"
129 " last_usable_lba disk_guid start_lba_part_entry"
130 " num_part_entry part_entry_size part_crc32")
131 GPT_SIGNATURE = 'EFI PART'
132 GPT_REVISION = '\x00\x00\x01\x00'
133 GPT_HEADER_SIZE = 0x5C
134 GPT_HEADER_FMT = "<8s4sLL4xQQQQ16sQLLL"
135
136 GPTtable = namedtuple("GPTtable", "part_type unique_guid first_lba"
137 " last_lba attribute_flag part_name")
138 GPT_TABLE_FMT = "<16s16sQQQ72s"
139
140 def __init__(self, filename, pagesize, blocksize, chipsize):
141 self.filename = filename
142 self.pagesize = pagesize
143 self.blocksize = blocksize
144 self.chipsize = chipsize
145 self.__partitions = OrderedDict()
146
147 def __validate_and_read_parts(self, part_fp):
148 """Validate the GPT and read the partition"""
149 part_fp.seek(self.blocksize, os.SEEK_SET)
150 gptheader_str = part_fp.read(struct.calcsize(GPT.GPT_HEADER_FMT))
151 gptheader = struct.unpack(GPT.GPT_HEADER_FMT, gptheader_str)
152 gptheader = GPT.GPTheader._make(gptheader)
153
154 if gptheader.signature != GPT.GPT_SIGNATURE:
155 error("Invalid signature")
156
157 if gptheader.revision != GPT.GPT_REVISION:
158 error("Unsupported GPT Revision")
159
160 if gptheader.header_size != GPT.GPT_HEADER_SIZE:
161 error("Invalid Header size")
162
163 # Adding GPT partition info. This has to be flashed first.
164 # GPT Header starts at LBA1 so (current_lba -1) will give the
165 # starting of primary GPT.
166 # blocksize will equal to gptheader.first_usuable_lba - current_lba + 1
167
168 name = "0:GPT"
169 block_start = gptheader.current_lba - 1
170 block_count = gptheader.first_usable_lba - gptheader.current_lba + 1
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530171 which_flash = 0
172 part_info = PartInfo(name, block_start, block_count, which_flash)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530173 self.__partitions[name] = part_info
174
175 part_fp.seek(2 * self.blocksize, os.SEEK_SET)
176
177 for i in range(gptheader.num_part_entry):
178 gpt_table_str = part_fp.read(struct.calcsize(GPT.GPT_TABLE_FMT))
179 gpt_table = struct.unpack(GPT.GPT_TABLE_FMT, gpt_table_str)
180 gpt_table = GPT.GPTtable._make(gpt_table)
181
182 block_start = gpt_table.first_lba
183 block_count = gpt_table.last_lba - gpt_table.first_lba + 1
184
185 part_name = gpt_table.part_name.strip(chr(0))
186 name = part_name.replace('\0','')
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530187 part_info = PartInfo(name, block_start, block_count, which_flash)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530188 self.__partitions[name] = part_info
189
190 # Adding the GPT Backup partition.
191 # GPT header backup_lba gives block number where the GPT backup header will be.
192 # GPT Backup header will start from offset of 32 blocks before
193 # the GPTheader.backup_lba. Backup GPT size is 33 blocks.
194 name = "0:GPTBACKUP"
195 block_start = gptheader.backup_lba - 32
196 block_count = 33
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530197 part_info = PartInfo(name, block_start, block_count, which_flash)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530198 self.__partitions[name] = part_info
199
200 def get_parts(self):
201 """Returns a list of partitions present in the GPT."""
202
203 try:
204 with open(self.filename, "r") as part_fp:
205 self.__validate_and_read_parts(part_fp)
206 except IOError, e:
207 error("error opening %s" % self.filename, e)
208
209 return self.__partitions
210
211class MIBIB(object):
212 Header = namedtuple("Header", "magic1 magic2 version age")
213 HEADER_FMT = "<LLLL"
214 HEADER_MAGIC1 = 0xFE569FAC
215 HEADER_MAGIC2 = 0xCD7F127A
216 HEADER_VERSION = 4
217
218 Table = namedtuple("Table", "magic1 magic2 version numparts")
219 TABLE_FMT = "<LLLL"
220 TABLE_MAGIC1 = 0x55EE73AA
221 TABLE_MAGIC2 = 0xE35EBDDB
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530222 TABLE_VERSION_IPQ806X = 3
223 TABLE_VERSION_OTHERS = 4
224
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530225
226 Entry = namedtuple("Entry", "name offset length"
227 " attr1 attr2 attr3 which_flash")
228 ENTRY_FMT = "<16sLLBBBB"
229
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530230 def __init__(self, filename, pagesize, blocksize, chipsize, nand_blocksize, nand_chipsize, root_part):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530231 self.filename = filename
232 self.pagesize = pagesize
233 self.blocksize = blocksize
234 self.chipsize = chipsize
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530235 self.nand_blocksize = nand_blocksize
236 self.nand_chipsize = nand_chipsize
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530237 self.__partitions = OrderedDict()
238
239 def __validate(self, part_fp):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530240 """Validate the MIBIB by checking for magic bytes."""
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530241
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530242 mheader_str = part_fp.read(struct.calcsize(MIBIB.HEADER_FMT))
243 mheader = struct.unpack(MIBIB.HEADER_FMT, mheader_str)
244 mheader = MIBIB.Header._make(mheader)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530245
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530246 if (mheader.magic1 != MIBIB.HEADER_MAGIC1
247 or mheader.magic2 != MIBIB.HEADER_MAGIC2):
248 """ mheader.magic1 = MIBIB.HEADER_MAGIC1
249 mheader.magic2 = MIBIB.HEADER_MAGIC2 """
250 error("invalid partition table, magic byte not present")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530251
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530252 if mheader.version != MIBIB.HEADER_VERSION:
253 error("unsupport mibib version")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530254
255 def __read_parts(self, part_fp):
256 """Read the partitions from the MIBIB."""
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530257 global ARCH_NAME
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530258 part_fp.seek(self.pagesize, os.SEEK_SET)
259 mtable_str = part_fp.read(struct.calcsize(MIBIB.TABLE_FMT))
260 mtable = struct.unpack(MIBIB.TABLE_FMT, mtable_str)
261 mtable = MIBIB.Table._make(mtable)
262
263 if (mtable.magic1 != MIBIB.TABLE_MAGIC1
264 or mtable.magic2 != MIBIB.TABLE_MAGIC2):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530265 """ mtable.magic1 = MIBIB.TABLE_MAGIC1
266 mtable.magic2 = MIBIB.TABLE_MAGIC2 """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530267 error("invalid sys part. table, magic byte not present")
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530268 if ARCH_NAME == "ipq806x":
269 if mtable.version != MIBIB.TABLE_VERSION_IPQ806X:
270 error("unsupported partition table version")
271 else:
272 if mtable.version != MIBIB.TABLE_VERSION_OTHERS:
273 error("unsupported partition table version")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530274
275 for i in range(mtable.numparts):
276 mentry_str = part_fp.read(struct.calcsize(MIBIB.ENTRY_FMT))
277 mentry = struct.unpack(MIBIB.ENTRY_FMT, mentry_str)
278 mentry = MIBIB.Entry._make(mentry)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530279 self.flash_flag = self.blocksize
280 self.chip_flag = self.chipsize
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530281
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530282 if mentry.which_flash != 0:
283 self.flash_flag = self.nand_blocksize
284 self.chip_flag = self.nand_chipsize
285
286 byte_offset = mentry.offset * self.flash_flag
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530287
288 if mentry.length == 0xFFFFFFFF:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530289 byte_length = self.chip_flag - byte_offset
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530290 else:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530291 byte_length = mentry.length * self.flash_flag
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530292
293 part_name = mentry.name.strip(chr(0))
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530294 part_info = PartInfo(part_name, byte_offset, byte_length, mentry.which_flash)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530295 self.__partitions[part_name] = part_info
296
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530297 def get_parts(self):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530298 """Returns a list of partitions present in the MIBIB. CE """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530299
300 try:
301 with open(self.filename, "r") as part_fp:
302 self.__validate(part_fp)
303 self.__read_parts(part_fp)
304 except IOError, e:
305 error("error opening %s" % self.filename, e)
306
307 return self.__partitions
308
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530309class FlashScript(object):
310 """Base class for creating flash scripts."""
311
312 def __init__(self, flinfo):
313 self.pagesize = flinfo.pagesize
314 self.blocksize = flinfo.blocksize
315 self.script = []
316 self.parts = []
317 self.curr_stdout = "serial"
318 self.activity = None
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530319 self.flash_type = flinfo.type
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530320
321 self.script.append('if test "x$verbose" = "x"; then\n')
322 self.script.append("failedmsg='[failed]'\n")
323 self.script.append('else\n')
324 self.script.append("failedmsg='%s Failed'\n" % ("#" * 40))
325 self.script.append('fi\n')
326
327 def append(self, cmd, fatal=True):
328 """Add a command to the script.
329
330 Add additional code, to terminate on error. This can be
331 supressed by passing 'fatal' as False.
332 """
333
334 if fatal:
Pavithra Palanisamy77ed38c2018-02-21 12:32:59 +0530335 """Check cmd strings to display reason for failure."""
336
337 if "imxtract" in cmd:
338 self.script.append("failreason='error: failed on image extraction'\n")
339 elif "erase" in cmd:
340 self.script.append("failreason='error: failed on partition erase'\n")
341 elif "write" in cmd:
342 self.script.append("failreason='error: failed on partition write'\n")
343 else:
344 pass
345
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530346 self.script.append(cmd
347 + ' || setenv stdout serial'
348 + ' && echo "$failedmsg"'
Pavithra Palanisamy77ed38c2018-02-21 12:32:59 +0530349 + ' && echo "$failreason"'
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530350 + ' && exit 1\n')
351 else:
352 self.script.append(cmd + "\n")
353
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530354 def dumps(self):
355 """Return the created script as a string."""
356 return "".join(self.script)
357
358 def redirect(self, dev):
359 """Generate code, to redirect command output to a device."""
360
361 if self.curr_stdout == dev:
362 return
363
364 self.append("setenv stdout %s" % dev, fatal=False)
365 self.curr_stdout = dev
366
367 def start_activity(self, activity):
368 """Generate code, to indicate start of an activity."""
369
370 self.script.append('if test "x$verbose" = "x"; then\n')
371 self.echo("'%-40.40s'" % activity, nl=False)
372 self.script.append('else\n')
373 self.echo("'%s %s Started'" % ("#" * 40, activity), verbose=True)
374 self.script.append('fi\n')
375 self.activity = activity
376
377 def finish_activity(self):
378 """Generate code, to indicate end of an activity."""
379
380 self.script.append('if test "x$verbose" = "x"; then\n')
381 self.echo("'[ done ]'")
382 self.redirect("serial")
383 self.script.append('else\n')
384 self.echo("'%s %s Done'" % ("#" * 40, self.activity), verbose=True)
385 self.script.append('fi\n')
386
387 def imxtract(self, part):
388 """Generate code, to extract image location, from a multi-image blob.
389
390 part -- string, name of the sub-image
391
392 Sets the $fileaddr environment variable, to point to the
393 location of the sub-image.
394 """
395
396 self.append("imxtract $imgaddr %s" % part)
397
398 def echo(self, msg, nl=True, verbose=False):
399 """Generate code, to print a message.
400
401 nl -- bool, indicates whether newline is to be printed
402 verbose -- bool, indicates whether printing in verbose mode
403 """
404
405 if not verbose:
406 self.redirect("serial")
407
408 if nl:
409 self.append("echo %s" % msg, fatal=False)
410 else:
411 self.append("echo %s%s" % (r"\\c", msg), fatal=False)
412
413 if not verbose:
414 self.redirect("nulldev")
415
416 def end(self):
417 """Generate code, to indicate successful completion of script."""
418
419 self.append("exit 0\n", fatal=False)
420
421 def start_if(self, var, value):
422 """Generate code, to check an environment variable.
423
424 var -- string, variable to check
425 value -- string, the value to compare with
426 """
427
428 self.append('if test "$%s" = "%s"; then\n' % (var, value),
429 fatal=False)
430
431 def end_if(self):
432 """Generate code, to end if statement."""
433
434 self.append('fi\n', fatal=False)
435
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530436class Flash_Script(FlashScript):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530437 """Class for creating NAND flash scripts."""
438
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530439 def __init__(self, *args):
440 FlashScript.__init__(self, args[0])
441 if args[0].type == "nand":
442 self.ipq_nand = args[1]
443 elif args[0].type == "nor" or args[0].type == "norplusnand":
444 self.nand_pagesize = args[1]
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530445
446 def erase(self, offset, size):
447 """Generate code, to erase the specified partition."""
448
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530449 if self.flash_type != "emmc":
450 size = roundup(size, self.blocksize)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530451
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530452 if self.flash_type == "nand":
453 self.append("nand device 0 && nand erase 0x%08x 0x%08x" % (offset, size))
454 elif self.flash_type == "nor":
455 self.append("sf erase 0x%08x +0x%08x" % (offset, size))
456 elif self.flash_type == "emmc":
457 self.append("mmc erase 0x%08x %x" % (offset, size))
458
459 def nand_write(self, offset, part_size, img_size, spi_nand):
460 """Handle the NOR + NAND case
461 All binaries upto HLOS will go to NOR and Root FS will go to NAND
462 Assumed all nand page sizes are less than are equal to 8KB
463 """
464
465 if spi_nand == "true":
466 self.append("nand device 1 && nand erase 0x%08x 0x%08x" % (offset, part_size))
467 else:
468 self.append("nand device 0 && nand erase 0x%08x 0x%08x" % (offset, part_size))
469
470 if img_size > 0:
471 self.append("nand write $fileaddr 0x%08x 0x%08x" % (offset, img_size))
472
473 def write(self, offset, size):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530474 """Generate code, to write to a partition."""
475
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530476 if self.flash_type == "nand":
477 if size > 0:
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530478 size = roundup(size, self.pagesize)
479 self.append("nand write $fileaddr 0x%08x 0x%08x" % (offset, size))
480
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530481 elif self.flash_type == "nor":
482 if size > 0:
483 self.append("sf write $fileaddr 0x%08x 0x%08x" % (offset, size))
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530484
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530485 elif self.flash_type == "emmc":
486 if size > 0:
487 size = roundup(size, self.blocksize)
488 blk_cnt = size / self.blocksize
489 self.append("mmc write $fileaddr 0x%08x %x" % (offset, blk_cnt))
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530490
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530491 def probe(self):
492 if self.flash_type == "nand":
493 pass
494 elif self.flash_type == "nor":
495 self.append("sf probe")
496 else:
497 pass
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +0530498
499 def switch_layout(self, layout):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530500 if self.flash_type == "nand":
501 self.append("ipq_nand %s" % layout)
502 else:
503 pass
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530504
505its_tmpl = Template("""
506/dts-v1/;
507
508/ {
509 description = "${desc}";
510 images {
511${images}
512 };
513};
514""")
515
516its_image_tmpl = Template("""
517 ${name} {
518 description = "${desc}";
519 data = /incbin/("./${fname}");
520 type = "${imtype}";
521 arch = "arm";
522 compression = "none";
523 hash@1 { algo = "crc32"; };
524 };
525""")
526
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530527def sha1(message):
528 """Returns SHA1 digest in hex format of the message."""
529
530 m = hashlib.sha1()
531 m.update(message)
532 return m.hexdigest()
533
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530534class Pack(object):
535 """Class to create a flashable, multi-image blob.
536
537 Combine multiple images present in a directory, and generate a
538 U-Boot script to flash the images.
539 """
540 # The maximum rootfs size is 64MB
541 norplusnand_rootfs_img_size = (64 * 1024 * 1024)
542
543 def __init__(self):
544 self.flinfo = None
545 self.images_dname = None
546 self.ipq_nand = None
547 self.partitions = {}
548
549 self.fconf_fname = None
550 self.scr_fname = None
551 self.its_fname = None
552 self.img_fname = None
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530553 self.emmc_page_size = 512
554 self.emmc_block_size = 512
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530555
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530556 def __get_machid(self, section):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530557 """Get the machid for a section.
558
559 info -- ConfigParser object, containing image flashing info
560 section -- section to retreive the machid from
561 """
562 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530563 machid = int(section.find("./machid").text, 0)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530564 machid = "%x" % machid
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530565 except ValueError, e:
566 error("invalid value for machid, should be integer")
567
568 return machid
569
570 def __get_img_size(self, filename):
571 """Get the size of the image to be flashed
572
573 filaneme -- string, filename of the image to be flashed
574 """
575
576 if filename.lower() == "none":
577 return 0
578 try:
579 return getsize(os.path.join(self.images_dname, filename))
580 except OSError, e:
581 error("error getting image size '%s'" % filename, e)
582
583 def __get_part_info(self, partition):
584 """Return partition info for the specified partition.
585
586 partition -- string, partition name
587 """
588 try:
589 return self.partitions[partition]
590 except KeyError, e:
591 return None
592
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530593 def __gen_flash_script_cdt(self, entries, partition, flinfo, script):
594 global ARCH_NAME
595 for section in entries:
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530596
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530597 machid = int(section.find(".//machid").text, 0)
598 machid = "%x" % machid
599 board = section.find(".//board").text
600 spi_nand = section.find(".//spi_nand").text
601 if ARCH_NAME != "ipq806x":
602 try:
603 memory = section.find(".//memory").text
604 except AttributeError, e:
605 memory = "128M16"
606 filename = "cdt-" + board + "_" + memory + ".bin"
607 else:
608 filename = "cdt-" + board + ".bin"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530609
610 img_size = self.__get_img_size(filename)
611 part_info = self.__get_part_info(partition)
612
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530613 section_label = partition.split(":")
614 if len(section_label) != 1:
615 section_conf = section_label[1]
616 else:
617 section_conf = section_label[0]
618
619 section_conf = section_conf.lower()
620
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530621 if self.flinfo.type == 'nand':
622 size = roundup(img_size, flinfo.pagesize)
623 tr = ' | tr \"\\000\" \"\\377\"'
624
625 if self.flinfo.type == 'emmc':
626 size = roundup(img_size, flinfo.blocksize)
627 tr = ''
628
629 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
630 pad_size = size - img_size
631 filename_abs = os.path.join(self.images_dname, filename)
632 filename_abs_pad = filename_abs + ".padded"
633 cmd = 'cat %s > %s' % (filename_abs, filename_abs_pad)
634 ret = subprocess.call(cmd, shell=True)
635 if ret != 0:
636 error("failed to copy image")
637 cmd = 'dd if=/dev/zero count=1 bs=%s %s >> %s' % (pad_size, tr, filename_abs_pad)
638 cmd = '(' + cmd + ') 1>/dev/null 2>/dev/null'
639 ret = subprocess.call(cmd, shell=True)
640 if ret != 0:
641 error("failed to create padded image from script")
642
643 if self.flinfo.type != "emmc":
644 if part_info == None:
645 if self.flinfo.type == 'norplusnand':
646 if count > 2:
647 error("More than 2 NAND images for NOR+NAND is not allowed")
648 elif img_size > part_info.length:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530649 error("img size is larger than part. len in '%s'" % section_conf)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530650 else:
651 if part_info != None:
652 if (img_size > 0):
653 if img_size > (part_info.length * self.flinfo.blocksize):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530654 error("img size is larger than part. len in '%s'" % section_conf)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530655
656 if part_info == None and self.flinfo.type != 'norplusnand':
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530657 print "Flash type is norplusemmc"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530658 continue
659
660 if machid:
661 script.start_if("machid", machid)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530662 if ARCH_NAME != "ipq806x":
663 script.start_activity("Flashing ddr-%s_%s:" % ( board, memory ))
664 if img_size > 0:
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +0530665 filename_pad = filename + ".padded"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530666 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
667 script.imxtract("ddr-" + board + "_" + memory + "-" + sha1(filename_pad))
668 else:
669 script.imxtract("ddr-" + board + "_" + memory + "-" + sha1(filename))
670 """ script.imxtract("cdt-" + board + "_" + memory + ".bin-" + sha1(filename_pad))
671 else:
672 script.imxtract("cdt-" + board + "_" + memory + ".bin-" + sha1(filename)) """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530673
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530674 else:
675 script.start_activity("Flashing ddr-%s:" % (board))
676 script.switch_layout("sbl")
677 if img_size > 0:
678 filename_pad = filename + ".padded"
679 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
680 script.imxtract("ddr-" + board + "-" + sha1(filename_pad))
681 else:
682 script.imxtract("ddr-" + board + "-" + sha1(filename))
683 """ script.imxtract("cdt-" + board + ".bin-" + sha1(filename_pad))
684 else:
685 script.imxtract("cdt-" + board + ".bin-" + sha1(filename)) """
686
687 part_size = Pack.norplusnand_rootfs_img_size
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530688 if part_info == None:
689 if self.flinfo.type == 'norplusnand':
690 offset = count * Pack.norplusnand_rootfs_img_size
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530691 script.nand_write(offset, part_size, img_size, spi_nand)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530692 count = count + 1
693 else:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530694 if part_info.which_flash == 0:
695 offset = part_info.offset
696 script.erase(offset, part_info.length)
697 script.write(offset, img_size)
698 else:
699 offset = part_info.offset
700 script.nand_write(offset, part_info.length, img_size, spi_nand)
701
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530702 script.finish_activity()
703
704 if machid:
705 script.end_if()
706
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530707 def __gen_flash_script_image(self, filename, soc_version, file_exists, machid, partition, flinfo, script):
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530708
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530709 img_size = 0
710 if file_exists == 1:
711 img_size = self.__get_img_size(filename)
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530712 part_info = self.__get_part_info(partition)
713
714 section_label = partition.split(":")
715 if len(section_label) != 1:
716 section_conf = section_label[1]
717 else:
718 section_conf = section_label[0]
719
720 section_conf = section_conf.lower()
721 spi_nand = False
722
723 if self.flinfo.type == 'nand':
724 size = roundup(img_size, flinfo.pagesize)
725 tr = ' | tr \"\\000\" \"\\377\"'
726
727 if self.flinfo.type == 'emmc':
728 size = roundup(img_size, flinfo.blocksize)
729 tr = ''
730
731 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
732 pad_size = size - img_size
733 filename_abs = os.path.join(self.images_dname, filename)
734 filename_abs_pad = filename_abs + ".padded"
735 cmd = 'cat %s > %s' % (filename_abs, filename_abs_pad)
736 ret = subprocess.call(cmd, shell=True)
737 if ret != 0:
738 error("failed to copy image")
739 cmd = 'dd if=/dev/zero count=1 bs=%s %s >> %s' % (pad_size, tr, filename_abs_pad)
740 cmd = '(' + cmd + ') 1>/dev/null 2>/dev/null'
741 ret = subprocess.call(cmd, shell=True)
742 if ret != 0:
743 error("failed to create padded image from script")
744
745 if self.flinfo.type != "emmc":
746 if part_info == None:
747 if self.flinfo.type == 'norplusnand':
748 if count > 2:
749 error("More than 2 NAND images for NOR+NAND is not allowed")
750 elif img_size > part_info.length:
751 error("img size is larger than part. len in '%s'" % section_conf)
752 else:
753 if part_info != None:
754 if (img_size > 0):
755 if img_size > (part_info.length * self.flinfo.blocksize):
756 error("img size is larger than part. len in '%s'" % section_conf)
757
758 if part_info == None and self.flinfo.type != 'norplusnand':
759 print "Flash type is norplusemmc"
760 return
761
762 if machid:
763 script.start_if("machid", machid)
764
765 if section_conf == "qsee":
766 section_conf = "tz"
767 elif section_conf == "appsbl":
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +0530768 if lk == "true":
769 section_conf = "lkboot"
770 else:
771 section_conf = "u-boot"
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530772 elif section_conf == "rootfs" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
773 section_conf = "ubi"
774 elif section_conf == "wififw" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
775 section_conf = "wififw_ubi"
776
777 if soc_version:
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +0530778 section_conf = section_conf + "_v" + str(soc_version)
Pavithra Palanisamy06f249a2018-09-11 12:49:50 +0530779 if str(soc_version) == "1":
780 script.append('if test "$soc_version_major" = "1" || test "$soc_version_major" = ""; then\n', fatal=False)
781 else:
782 script.start_if("soc_version_major", soc_version)
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530783
784 script.start_activity("Flashing %s:" % section_conf)
785
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530786 if file_exists == 0:
787 script.append('setenv stdout serial && echo "error: binary image not found" && exit 1', fatal=False)
788 if soc_version:
789 script.end_if()
790 return
791
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530792 if ARCH_NAME == "ipq806x":
793 script.switch_layout(layout)
794 if img_size > 0:
795 filename_pad = filename + ".padded"
796 if ((self.flinfo.type == 'nand' or self.flinfo.type == 'emmc') and (size != img_size)):
797 script.imxtract(section_conf + "-" + sha1(filename_pad))
798 else:
799 script.imxtract(section_conf + "-" + sha1(filename))
800
801 part_size = Pack.norplusnand_rootfs_img_size
802 if part_info == None:
803 if self.flinfo.type == 'norplusnand':
804 offset = count * Pack.norplusnand_rootfs_img_size
805 img_size = Pack.norplusnand_rootfs_img_size
806 script.nand_write(offset, part_size, img_size, spi_nand)
807 count = count + 1
808 else:
809 if part_info.which_flash == 0:
810 offset = part_info.offset
811 script.erase(offset, part_info.length)
812 script.write(offset, img_size)
813 else:
814 offset = part_info.offset
815 script.nand_write(offset, part_info.length, img_size, spi_nand)
816
817 script.finish_activity()
818
819 if soc_version:
820 script.end_if()
821
822 if machid:
823 script.end_if()
824
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530825 def __gen_flash_script(self, script, flinfo, root):
826 """Generate the script to flash the images.
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530827
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530828 info -- ConfigParser object, containing image flashing info
829 script -- Script object, to append commands to
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +0530830 """
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530831 global MODE
832 global SRC_DIR
833 global ARCH_NAME
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530834
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530835 diff_files = ""
836 count = 0
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530837 soc_version = 0
838 diff_soc_ver_files = 0
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530839 file_exists = 1
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530840
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530841 if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
842 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
843 else:
844 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
845
846 root_part = ET.parse(srcDir_part)
847 if self.flash_type != "emmc" and flinfo.type != "emmc":
848 parts = root_part.findall(".//partitions/partition")
849 elif self.flash_type != "emmc" and flinfo.type == "emmc":
850 parts = root_part.findall(".//physical_partition[@ref='norplusemmc']/partition")
851 else:
852 parts = root_part.findall(".//physical_partition[@ref='emmc']/partition")
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +0530853 if flinfo.type == "emmc" and image_type == "all":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530854 parts_length = len(parts) + 2
855 else:
856 parts_length = len(parts)
857 entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
858
859 first = False
860 section = None
861 part_index = 0
862
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +0530863 if flinfo.type == "emmc" and image_type == "all":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530864 first = True
865
866 for index in range(parts_length):
867
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +0530868 filename = ""
869 partition = ""
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530870 if first:
871 if self.flash_type == "norplusemmc":
872 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
873 else:
874 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
875 part_fname = part_info.find(".//partition_mbn")
876 filename = part_fname.text
877 partition = "0:GPT"
878 first = False
879
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +0530880 elif index == (parts_length - 1) and flinfo.type == "emmc" and image_type == "all":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530881 if self.flash_type == "norplusemmc":
882 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
883 else:
884 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
885 part_fname = part_info.find(".//partition_mbn_backup")
886 filename = part_fname.text
887 partition = "0:GPTBACKUP"
888
889 else:
890 section = parts[part_index]
891 part_index += 1
892 if flinfo.type != "emmc":
893 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530894 if image_type == "all" or section[8].attrib['image_type'] == image_type:
895 filename = section[8].text
896 try:
897 if section[8].attrib['mode'] != MODE:
898 filename = section[9].text
899 else:
900 pass
901 except AttributeError, e:
902 pass
903 except KeyError, e:
904 pass
905 else:
906 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530907 except IndexError, e:
908 if index == (parts_length - 1):
909 return
910 else:
911 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530912 except KeyError, e:
913 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530914 partition = section[0].text
915 else:
916 try:
917 diff_files = section.attrib['diff_files']
918 except KeyError, e:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530919 try:
920 diff_soc_ver_files = section.attrib['diff_soc_ver_files']
921 except KeyError, e:
922 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530923 if image_type == "all" or section.attrib['image_type'] == image_type:
924 filename = section.attrib['filename']
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +0530925 if lk == "true" and "u-boot" in filename:
926 filename = filename.replace("u-boot", "lkboot")
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530927 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530928 if filename == "":
929 continue
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530930 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530931 print "Skipping partition '%s'" % section.attrib['label']
932 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530933
934 if diff_files == "true":
935 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530936 if image_type == "all" or section.attrib['image_type'] == image_type:
937 filename = section.attrib['filename_' + MODE]
Gokul Sriram Palanisamy41eae482019-01-09 10:27:00 +0530938 if lk == "true" and "uImage" in filename:
939 if MODE == "32":
940 filename = 'openwrt-' + ARCH_NAME + '-kernelboot.img'
941 if MODE == "64":
942 filename = 'openwrt-' + ARCH_NAME + '_' + MODE + '-kernelboot.img'
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530943 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530944 if filename == "":
945 continue
946 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530947 print "Skipping partition '%s'" % section.attrib['label']
948 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530949 diff_files = "" # Clear for next iteration
950
951 # Get machID
952 if partition != "0:CDT" and partition != "0:DDRCONFIG":
953 machid = None
954 else:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530955 try:
956 if image_type == "all" or section.attrib['image_type'] == image_type:
957 self.__gen_flash_script_cdt(entries, partition, flinfo, script)
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +0530958 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +0530959 except KeyError, e:
960 continue
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +0530961
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530962 if ARCH_NAME == "ipq806x":
963 # Get Layout
964 try:
965 layout = section[9].text
966 except:
967 layout = None
968
969 if layout not in ("sbl", "linux", None):
970 error("invalid layout in '%s'" % section)
971
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530972 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530973
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530974 img = section.find('img_name')
975 if img != None and 'soc_version' in img.attrib:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530976
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530977 imgs = section.findall('img_name')
978 try:
979 for img in imgs:
980 filename = img.text
981 soc_version = img.get('soc_version')
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +0530982 if 'optional' in img.attrib:
983 if not os.path.exists(os.path.join(self.images_dname, filename)):
984 file_exists = 0
985 self.__gen_flash_script_image(filename, soc_version, file_exists, machid, partition, flinfo, script)
986 file_exists = 1 # generating flash script is mandatory by default
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530987
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530988 soc_version = 0 # Clear soc_version for next iteration
989 continue
990 except KeyError, e:
991 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +0530992
Pavithra Palanisamye34f3092018-08-29 19:30:41 +0530993 else:
994 if diff_soc_ver_files:
995 try:
996 for version in range(1, int(diff_soc_ver_files)+1):
997 if image_type == "all" or section.attrib['image_type'] == image_type:
998 filename = section.attrib['filename_v' + str(version)]
999 partition = section.attrib['label']
1000 if filename == "":
1001 continue
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +05301002 if section.attrib['optional']:
1003 if not os.path.exists(os.path.join(self.images_dname, filename)):
1004 file_exists = 0
1005 self.__gen_flash_script_image(filename, version, file_exists, machid, partition, flinfo, script)
1006 file_exists = 1
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301007 diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
1008 continue
1009 except KeyError, e:
1010 print "Skipping partition '%s'" % section.attrib['label']
1011 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301012
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301013 if filename != "":
1014 self.__gen_flash_script_image(filename, soc_version, file_exists, machid, partition, flinfo, script)
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301015
1016 def __gen_script_cdt(self, images, flinfo, root, section_conf, partition):
1017 global ARCH_NAME
1018
1019 entries = root.findall(".//data[@type='MACH_ID_BOARD_MAP']/entry")
1020
1021 for section in entries:
1022
1023 board = section.find(".//board").text
1024 if ARCH_NAME != "ipq806x":
1025 try:
1026 memory = section.find(".//memory").text
1027 except AttributeError, e:
1028 memory = "128M16"
1029
1030 filename = "cdt-" + board + "_" + memory + ".bin"
1031 file_info = "ddr-" + board + "_" + memory
1032 else:
1033 filename = "cdt-" + board + ".bin"
1034 file_info = "ddr-" + board
1035
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301036 part_info = self.__get_part_info(partition)
1037
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +05301038 if part_info == None and self.flinfo.type != 'norplusnand':
1039 continue
1040
1041 if self.flinfo.type == 'nand':
1042 img_size = self.__get_img_size(filename)
1043 size = roundup(img_size, flinfo.pagesize)
1044 if ( size != img_size ):
1045 filename = filename + ".padded"
1046 if self.flinfo.type == 'emmc':
1047 img_size = self.__get_img_size(filename)
1048 size = roundup(img_size, flinfo.blocksize)
1049 if ( size != img_size ):
1050 filename = filename + ".padded"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301051 image_info = ImageInfo(file_info + "-" + sha1(filename),
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301052 filename, "firmware")
Aditya Kumar Patra Sb68f13e2017-03-08 14:07:23 +05301053 if filename.lower() != "none":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301054 if image_info not in images:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301055 images.append(image_info)
1056
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301057 def __gen_script_append_images(self, filename, soc_version, images, flinfo, root, section_conf, partition):
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301058
1059 part_info = self.__get_part_info(partition)
1060 if part_info == None and self.flinfo.type != 'norplusnand':
1061 return
1062
1063 if self.flinfo.type == 'nand':
1064 img_size = self.__get_img_size(filename)
1065 size = roundup(img_size, flinfo.pagesize)
1066 if ( size != img_size ):
1067 filename = filename + ".padded"
1068 if self.flinfo.type == 'emmc':
1069 img_size = self.__get_img_size(filename)
1070 size = roundup(img_size, flinfo.blocksize)
1071 if ( size != img_size ):
1072 filename = filename + ".padded"
1073 if section_conf == "qsee":
1074 section_conf = "tz"
1075 elif section_conf == "appsbl":
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +05301076 if lk == "true":
1077 section_conf = "lkboot"
1078 else:
1079 print " Using u-boot..."
1080 section_conf = "u-boot"
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301081 elif section_conf == "rootfs" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
1082 section_conf = "ubi"
1083 elif section_conf == "wififw" and (self.flash_type == "nand" or self.flash_type == "norplusnand"):
1084 section_conf = "wififw_ubi"
1085
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301086 if soc_version:
1087 section_conf = section_conf + "_v" + str(soc_version)
1088
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301089 image_info = ImageInfo(section_conf + "-" + sha1(filename),
1090 filename, "firmware")
1091 if filename.lower() != "none":
1092 if image_info not in images:
1093 images.append(image_info)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301094
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301095 def __gen_script(self, script_fp, script, images, flinfo, root):
1096 """Generate the script to flash the multi-image blob.
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301097
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301098 script_fp -- file object, to write script to
1099 info_fp -- file object, to read flashing information from
1100 script -- Script object, to append the commands to
1101 images -- list of ImageInfo, appended to, based on images in config
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301102 """
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301103 global MODE
1104 global SRC_DIR
1105
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301106 soc_version = 0
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301107 diff_soc_ver_files = 0
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301108 diff_files = ""
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +05301109 file_exists = 1
1110
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301111 self.__gen_flash_script(script, flinfo, root)
1112 if (self.flash_type == "norplusemmc" and flinfo.type == "emmc") or (self.flash_type != "norplusemmc"):
1113 if flinfo.type == "emmc":
1114 script.start_activity("Flashing rootfs_data:")
1115 part_info = self.partitions["rootfs_data"]
1116 script.erase(part_info.offset, part_info.length)
1117 script.finish_activity()
1118 script.end()
1119
1120 if self.flash_type == "norplusemmc" and flinfo.type == "emmc":
1121 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
1122 else:
1123 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + self.flash_type.lower() + "-partition.xml"
1124 root_part = ET.parse(srcDir_part)
1125 if self.flash_type != "emmc" and flinfo.type != "emmc":
1126 parts = root_part.findall(".//partitions/partition")
1127 elif self.flash_type != "emmc" and flinfo.type == "emmc":
1128 parts = root_part.findall(".//physical_partition[@ref='norplusemmc']/partition")
1129 else:
1130 parts = root_part.findall(".//physical_partition[@ref='emmc']/partition")
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301131 if flinfo.type == "emmc" and image_type == "all":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301132 parts_length = len(parts) + 2
1133 else:
1134 parts_length = len(parts)
1135
1136 first = False
1137 section = None
1138 part_index = 0
1139
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301140 if flinfo.type == "emmc" and image_type == "all":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301141 first = True
1142
1143 for index in range(parts_length):
1144
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301145 filename = ""
1146 partition = ""
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301147 if first:
1148 if self.flash_type == "norplusemmc":
1149 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1150 else:
1151 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1152 part_fname = part_info.find(".//partition_mbn")
1153 filename = part_fname.text
1154 partition = "0:GPT"
1155 first = False
1156
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301157 elif index == (parts_length - 1) and flinfo.type == "emmc" and image_type == "all":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301158 if self.flash_type == "norplusemmc":
1159 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1160 else:
1161 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1162 part_fname = part_info.find(".//partition_mbn_backup")
1163 filename = part_fname.text
1164 partition = "0:GPTBACKUP"
1165
1166 else:
1167 section = parts[part_index]
1168 part_index += 1
1169 if flinfo.type != "emmc":
1170 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301171 if image_type == "all" or section[8].attrib['image_type'] == image_type:
1172 filename = section[8].text
1173 try:
1174 if section[8].attrib['mode'] != MODE:
1175 filename = section[9].text
1176 except AttributeError, e:
1177 pass
1178 except KeyError, e:
1179 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301180 except IndexError, e:
1181 if index == (parts_length - 1):
1182 return
1183 else:
1184 continue
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301185 except KeyError, e:
1186 continue
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301187 partition = section[0].text
1188 else:
1189
1190 try:
1191 diff_files = section.attrib['diff_files']
1192 except KeyError, e:
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301193 try:
1194 diff_soc_ver_files = section.attrib['diff_soc_ver_files']
1195 partition = section.attrib['label']
1196 except KeyError, e:
1197 try:
1198 if image_type == "all" or section.attrib['image_type'] == image_type:
1199 filename = section.attrib['filename']
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +05301200 if lk == "true" and "u-boot" in filename:
1201 filename = filename.replace("u-boot", "lkboot")
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301202 partition = section.attrib['label']
1203 if filename == "":
1204 continue
1205 except KeyError, e:
1206 print "Skipping partition '%s'" % section.attrib['label']
1207 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301208
1209 if diff_files == "true":
1210 try:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301211 if image_type == "all" or section.attrib['image_type'] == image_type:
1212 filename = section.attrib['filename_' + MODE]
Gokul Sriram Palanisamy41eae482019-01-09 10:27:00 +05301213 if lk == "true" and "uImage" in filename:
1214 if MODE == "32":
1215 filename = 'openwrt-' + ARCH_NAME + '-kernelboot.img'
1216 if MODE == "64":
1217 filename = 'openwrt-' + ARCH_NAME + '_' + MODE + '-kernelboot.img'
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301218 partition = section.attrib['label']
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301219 if filename == "":
1220 continue
1221
1222 except KeyError, e:
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301223 print "Skipping partition '%s'" % section.attrib['label']
1224 pass
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301225 diff_files = "" # Clear for next iteration
1226
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301227
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301228 part_info = self.__get_part_info(partition)
1229
1230 section_label = partition.split(":")
1231 if len(section_label) != 1:
1232 section_conf = section_label[1]
1233 else:
1234 section_conf = section_label[0]
1235
1236 section_conf = section_conf.lower()
1237
1238 if section_conf == "cdt" or section_conf == "ddrconfig":
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301239 try:
1240 if image_type == "all" or section[8].attrib['image_type'] == image_type:
1241 self.__gen_script_cdt(images, flinfo, root, section_conf, partition)
1242 continue
1243 except KeyError, e:
1244 continue
1245
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301246 if flinfo.type != "emmc":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301247
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301248 img = section.find('img_name')
1249 if img != None and 'soc_version' in img.attrib:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301250
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301251 imgs = section.findall('img_name')
1252 try:
1253 for img in imgs:
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301254 soc_version = img.get('soc_version')
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301255 filename = img.text
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +05301256 if 'optional' in img.attrib:
1257 if not os.path.exists(os.path.join(self.images_dname, filename)):
1258 file_exists = 0
1259
1260 if file_exists == 1:
1261 self.__gen_script_append_images(filename, soc_version, images, flinfo, root, section_conf, partition)
1262 file_exists = 1
Pavithra Palanisamy5a41b592018-09-03 16:31:52 +05301263 soc_version = 0 # Clear soc_version for next iteration
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301264 continue
1265 except KeyError, e:
1266 continue
1267
1268 else:
1269 if diff_soc_ver_files:
1270 try:
1271 for version in range(1, int(diff_soc_ver_files)+1):
1272 if image_type == "all" or section.attrib['image_type'] == image_type:
1273 filename = section.attrib['filename_v' + str(version)]
1274 partition = section.attrib['label']
1275 if filename == "":
1276 continue
Pavithra Palanisamyf29bf1f2018-10-25 19:50:03 +05301277 if section.attrib['optional']:
1278 if not os.path.exists(os.path.join(self.images_dname, filename)):
1279 file_exists = 0
1280
1281 if file_exists == 1:
1282 self.__gen_script_append_images(filename, version, images, flinfo, root, section_conf, partition)
1283 file_exists = 1
1284
Pavithra Palanisamye34f3092018-08-29 19:30:41 +05301285 diff_soc_ver_files = 0 # Clear diff_soc_ver_files for next iteration
1286 continue
1287 except KeyError, e:
1288 print "Skipping partition '%s'" % section.attrib['label']
1289 pass
1290
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301291 if filename != "":
1292 self.__gen_script_append_images(filename, soc_version, images, flinfo, root, section_conf, partition)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301293
1294 def __mkimage(self, images):
1295 """Create the multi-image blob.
1296
1297 images -- list of ImageInfo, containing images to be part of the blob
1298 """
1299 try:
1300 its_fp = open(self.its_fname, "wb")
1301 except IOError, e:
1302 error("error opening its file '%s'" % self.its_fname, e)
1303
1304 desc = "Flashing %s %x %x"
1305 desc = desc % (self.flinfo.type, self.flinfo.pagesize,
1306 self.flinfo.blocksize)
1307
1308 image_data = []
1309 for (section, fname, imtype) in images:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301310 fname = fname.replace("\\", "\\\\")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301311 subs = dict(name=section, desc=fname, fname=fname, imtype=imtype)
1312 image_data.append(its_image_tmpl.substitute(subs))
1313
1314 image_data = "".join(image_data)
1315 its_data = its_tmpl.substitute(desc=desc, images=image_data)
1316
1317 its_fp.write(its_data)
1318 its_fp.close()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301319
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301320 try:
Pavithra Palanisamybfb3a332018-12-12 19:42:24 +05301321 cmd = [SRC_DIR + "/mkimage", "-f", self.its_fname, self.img_fname]
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301322 ret = subprocess.call(cmd)
1323 if ret != 0:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301324 print ret
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301325 error("failed to create u-boot image from script")
1326 except OSError, e:
1327 error("error executing mkimage", e)
1328
1329 def __create_fnames(self):
1330 """Populate the filenames."""
1331
1332 self.scr_fname = os.path.join(self.images_dname, "flash.scr")
1333 self.its_fname = os.path.join(self.images_dname, "flash.its")
1334
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301335 def __gen_board_script(self, flinfo, part_fname, images, root):
1336 global SRC_DIR
1337 global ARCH_NAME
1338
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301339 """Generate the flashing script for one board.
1340
1341 board_section -- string, board section in board config file
1342 machid -- string, board machine ID in hex format
1343 flinfo -- FlashInfo object, contains board specific flash params
1344 part_fname -- string, partition file specific to the board
1345 fconf_fname -- string, flash config file specific to the board
1346 images -- list of ImageInfo, append images used by the board here
1347 """
1348 script_fp = open(self.scr_fname, "a")
1349
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301350 if flinfo.type != "emmc":
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301351 if root.find(".//data[@type='NAND_PARAMETER']/entry") != None:
Saravanan Jaganathan93d70cd2018-12-26 16:56:55 +05301352 if flinfo.type == "nand-4k":
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301353 flash_param = root.find(".//data[@type='NAND_PARAMETER']/entry[@type='4k']")
Saravanan Jaganathan93d70cd2018-12-26 16:56:55 +05301354 else:
1355 flash_param = root.find(".//data[@type='NAND_PARAMETER']/entry[@type='2k']")
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301356 else:
1357 flash_param = root.find(".//data[@type='NAND_PARAMETER']")
1358
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301359 pagesize = int(flash_param.find(".//page_size").text)
1360 pages_per_block = int(flash_param.find(".//pages_per_block").text)
1361 blocksize = pages_per_block * pagesize
1362 blocks_per_chip = int(flash_param.find(".//total_block").text)
1363 chipsize = blocks_per_chip * blocksize
1364
1365 srcDir_part = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + flinfo.type + "-partition.xml"
1366 root_part = ET.parse(srcDir_part)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301367 mibib = MIBIB(part_fname, flinfo.pagesize, flinfo.blocksize,
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301368 flinfo.chipsize, blocksize, chipsize, root_part)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301369 self.partitions = mibib.get_parts()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301370 if flinfo.type == "nand":
1371 script = Flash_Script(flinfo, self.ipq_nand)
1372 elif flinfo.type == "nor":
1373 script = Flash_Script(flinfo, pagesize)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301374 else:
1375 gpt = GPT(part_fname, flinfo.pagesize, flinfo.blocksize, flinfo.chipsize)
1376 self.partitions = gpt.get_parts()
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301377 script = Flash_Script(flinfo)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301378
1379 self.flinfo = flinfo
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301380
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301381 script.probe()
1382 self.__gen_script(script_fp, script, images, flinfo, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301383
1384 try:
1385 script_fp.write(script.dumps())
1386 except IOError, e:
1387 error("error writing to script '%s'" % script_fp.name, e)
1388
1389 script_fp.close()
1390
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301391 def __process_board_flash_emmc(self, ftype, images, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301392 """Extract board info from config and generate the flash script.
1393
1394 ftype -- string, flash type 'emmc'
1395 board_section -- string, board section in config file
1396 machid -- string, board machine ID in hex format
1397 images -- list of ImageInfo, append images used by the board here
1398 """
1399
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301400 try:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301401 part_info = root.find(".//data[@type='" + self.flash_type.upper() + "_PARAMETER']")
1402 part_fname = part_info.find(".//partition_mbn")
1403 part_fname = part_fname.text
1404 part_fname = os.path.join(self.images_dname, part_fname)
1405 if ftype == "norplusemmc":
1406 part_info = root.find(".//data[@type='NORPLUSEMMC_PARAMETER']")
1407 pagesize = int(part_info.find(".//page_size_flash").text)
1408 part_info = root.find(".//data[@type='EMMC_PARAMETER']")
1409 else:
1410 pagesize = self.emmc_page_size
1411 blocksize = self.emmc_block_size
1412 chipsize = int(part_info.find(".//total_block").text)
1413 if ftype.lower() == "norplusemmc":
1414 ftype = "emmc"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301415
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301416 except ValueError, e:
1417 error("invalid flash info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301418
1419 flinfo = FlashInfo(ftype, pagesize, blocksize, chipsize)
1420
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301421 self.__gen_board_script(flinfo, part_fname, images, root)
1422
1423 def __process_board_flash(self, ftype, images, root):
1424 global SRC_DIR
1425 global ARCH_NAME
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301426
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301427 try:
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301428 if ftype == "tiny-nor":
1429 part_info = root.find(".//data[@type='" + "NOR_PARAMETER']")
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301430 elif ftype == "nand" or ftype == "nand-4k":
1431 if root.find(".//data[@type='NAND_PARAMETER']/entry") != None:
1432 if ftype == "nand":
1433 part_info = root.find(".//data[@type='NAND_PARAMETER']/entry[@type='2k']")
1434 else:
1435 part_info = root.find(".//data[@type='NAND_PARAMETER']/entry[@type='4k']")
1436 else:
1437 part_info = root.find(".//data[@type='" + "NAND_PARAMETER']")
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301438 else:
1439 part_info = root.find(".//data[@type='" + ftype.upper() + "_PARAMETER']")
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301440
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301441 part_file = SRC_DIR + "/" + ARCH_NAME + "/flash_partition/" + ftype + "-partition.xml"
1442 part_xml = ET.parse(part_file)
1443 partition = part_xml.find(".//partitions/partition[2]")
1444 part_fname = partition[8].text
1445 part_fname = os.path.join(self.images_dname, part_fname)
1446 pagesize = int(part_info.find(".//page_size").text)
1447 pages_per_block = int(part_info.find(".//pages_per_block").text)
1448 blocks_per_chip = int(part_info.find(".//total_block").text)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301449
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301450 if ftype == "norplusnand" or ftype == "norplusemmc" or ftype == "tiny-nor":
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301451 ftype = "nor"
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301452 if ftype == "nand-4k":
1453 ftype = "nand"
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301454
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301455 except ValueError, e:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301456 error("invalid flash info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301457
1458 blocksize = pages_per_block * pagesize
1459 chipsize = blocks_per_chip * blocksize
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301460
1461 flinfo = FlashInfo(ftype, pagesize, blocksize, chipsize)
1462
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301463 self.__gen_board_script(flinfo, part_fname, images, root)
1464
1465 def __process_board(self, images, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301466
1467 try:
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301468 if self.flash_type in [ "nand", "nand-4k", "nor", "tiny-nor", "norplusnand" ]:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301469 self.__process_board_flash(self.flash_type, images, root)
1470 elif self.flash_type == "emmc":
1471 self.__process_board_flash_emmc(self.flash_type, images, root)
1472 elif self.flash_type == "norplusemmc":
1473 self.__process_board_flash("norplusemmc", images, root)
1474 self.__process_board_flash_emmc("norplusemmc", images, root)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301475 except ValueError, e:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301476 error("error getting board info in section '%s'" % board_section.find('machid').text, e)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301477
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301478 def main_bconf(self, flash_type, images_dname, out_fname, root):
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301479 """Start the packing process, using board config.
1480
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301481 flash_type -- string, indicates flash type, 'nand' or 'nor' or 'tiny-nor' or 'emmc' or 'norplusnand'
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301482 images_dname -- string, name of images directory
1483 out_fname -- string, output file path
1484 """
1485 self.flash_type = flash_type
1486 self.images_dname = images_dname
1487 self.img_fname = out_fname
1488
1489 self.__create_fnames()
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301490 try:
1491 os.unlink(self.scr_fname)
1492 except OSError, e:
1493 pass
1494
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301495 images = []
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301496 self.__process_board(images, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301497 images.insert(0, ImageInfo("script", "flash.scr", "script"))
1498 self.__mkimage(images)
1499
1500class UsageError(Exception):
1501 """Indicates error in command arguments."""
1502 pass
1503
1504class ArgParser(object):
1505 """Class to parse command-line arguments."""
1506
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301507 DEFAULT_TYPE = "nor,tiny-nor,nand,norplusnand,emmc,norplusemmc"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301508
1509 def __init__(self):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301510 self.flash_type = None
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301511 self.images_dname = None
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301512 self.out_dname = None
1513 self.scr_fname = None
1514 self.its_fname = None
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301515
1516 def parse(self, argv):
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301517 global MODE
1518 global SRC_DIR
1519 global ARCH_NAME
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301520 global image_type
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +05301521 global lk
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301522
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301523 """Start the parsing process, and populate members with parsed value.
1524
1525 argv -- list of string, the command line arguments
1526 """
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301527
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301528 cdir = os.path.abspath(os.path.dirname(""))
1529 if len(sys.argv) > 1:
1530 try:
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +05301531 opts, args = getopt(sys.argv[1:], "", ["arch=", "fltype=", "srcPath=", "inImage=", "outImage=", "image_type=", "lk"])
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301532 except GetoptError, e:
1533 raise UsageError(e.msg)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301534
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301535 for option, value in opts:
1536 if option == "--arch":
1537 ARCH_NAME = value
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301538
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301539 elif option == "--fltype":
1540 self.flash_type = value
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301541
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301542 elif option == "--srcPath":
1543 SRC_DIR = os.path.abspath(value)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301544
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301545 elif option == "--inImage":
1546 self.images_dname = os.path.join(cdir, value)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301547
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301548 elif option == "--outImage":
1549 self.out_dname = os.path.join(cdir, value)
1550
Saravanan Jaganathan7d086402017-09-22 15:35:01 +05301551 elif option == "--image_type":
1552 image_type = value
1553
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +05301554 elif option =="--lk":
1555 lk = "true"
1556
1557
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301558#Verify Arguments passed by user
1559
1560# Verify arch type
1561 if ARCH_NAME not in ["ipq40xx", "ipq806x", "ipq807x", "ipq807x_64"]:
1562 raise UsageError("Invalid arch type '%s'" % arch)
1563
1564 if ARCH_NAME == "ipq807x":
1565 MODE = "32"
1566 elif ARCH_NAME == "ipq807x_64":
1567 MODE = "64"
1568 ARCH_NAME = "ipq807x"
1569
1570# Set flash type to default type (nand) if not given by user
1571 if self.flash_type == None:
1572 self.flash_type = ArgParser.DEFAULT_TYPE
1573 for flash_type in self.flash_type.split(","):
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301574 if flash_type not in [ "nand", "nor", "tiny-nor", "emmc", "norplusnand", "norplusemmc" ]:
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301575 raise UsageError("invalid flash type '%s'" % flash_type)
1576
1577# Verify src Path
1578 if SRC_DIR == "":
1579 raise UsageError("Source Path is not provided")
1580
1581#Verify input image path
1582 if self.images_dname == None:
1583 raise UsageError("input images' Path is not provided")
1584
1585#Verify Output image path
1586 if self.out_dname == None:
1587 raise UsageError("Output Path is not provided")
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301588
1589 def usage(self, msg):
1590 """Print error message and command usage information.
1591
1592 msg -- string, the error message
1593 """
1594 print "pack: %s" % msg
1595 print
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301596 print "Usage:"
1597 print "python pack_hk.py [options] [Value] ..."
1598 print
1599 print "options:"
1600 print " --arch \tARCH_TYPE [ipq40xx/ipq806x/ipq807x/ipq807x_64]"
1601 print
Pavithra Palanisamy640bab82018-12-05 16:11:42 +05301602 print " --fltype \tFlash Type [nor/tiny-nor/nand/emmc/norplusnand/norplusemmc]"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301603 print " \t\tMultiple flashtypes can be passed by a comma separated string"
1604 print " \t\tDefault is all. i.e If \"--fltype\" is not passed image for all the flash-type will be created.\n"
1605 print " --srcPath \tPath to the directory containg the meta scripts and configs"
1606 print
1607 print " --inImage \tPath to the direcory containg binaries and images needed for singleimage"
1608 print
1609 print " --outImage \tPath to the directory where single image will be generated"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301610 print
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +05301611 print " --lk \t\tReplace u-boot with lkboot for appsbl"
1612 print " \t\tThis Argument does not take any value"
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301613 print "Pack Version: %s" % version
1614
Gokul Sriram Palanisamyae792312019-01-22 14:33:15 +05301615def gen_kernelboot_img(parser):
1616 """Generate kernelboot.img needed by LK bootloader"""
1617
1618 SKALES_DIR = parser.images_dname
1619 TMP_DIR = parser.out_dname + "tmp_dir"
1620
1621 try:
1622
1623 if os.path.exists(TMP_DIR):
1624 rmtree(TMP_DIR)
1625 os.makedirs(TMP_DIR)
1626
1627 if MODE == "64":
1628 KERNEL_IMG_NAME = "openwrt-" + ARCH_NAME + "_" + MODE + "-kernelboot.img"
1629 else:
1630 KERNEL_IMG_NAME = "openwrt-" + ARCH_NAME + "-kernelboot.img"
1631
1632 src = parser.images_dname + "qcom-" + ARCH_NAME + "-hk01.dtb"
1633 if not os.path.exists(src):
1634 error("%s file not found" % src)
1635 copy(src, TMP_DIR)
1636
1637 src = parser.images_dname + "Image"
1638 if not os.path.exists(src):
1639 error("%s file not found" % src)
1640 copy(src, TMP_DIR)
1641
1642 cmd = [SKALES_DIR + "dtbTool -o " + TMP_DIR + "/qcom-ipq807x-hk01-dt.img " + TMP_DIR]
1643 ret = subprocess.call(cmd, shell=True)
1644 if ret != 0:
1645 print ret
1646 error("Error executing dtbTools")
1647
1648 cmd = ["gzip -9 " + TMP_DIR + "/Image"]
1649 ret = subprocess.call(cmd, shell=True)
1650 if ret != 0:
1651 print ret
1652 error("Error executing gzip")
1653
1654 cmd = [SKALES_DIR + "mkbootimg",
1655 "--kernel=" + TMP_DIR + "/Image.gz",
1656 "--dt=" + TMP_DIR + "/qcom-ipq807x-hk01-dt.img",
1657 "--cmdline=\'rootfsname=rootfs rootwait nosmp\'",
1658 "--output=" + parser.out_dname + KERNEL_IMG_NAME,
1659 "--base=0x41200000"]
1660 ret = subprocess.call(cmd)
1661 if ret != 0:
1662 print ret
1663 error("Error executing mkbootimg")
1664
1665 rmtree(TMP_DIR)
1666 except OSError, e:
1667 error("error generating kernelboot.img", e)
1668
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301669def main():
1670 """Main script entry point.
1671
1672 Created to avoid polluting the global namespace.
1673 """
1674 try:
1675 parser = ArgParser()
1676 parser.parse(sys.argv)
1677 except UsageError, e:
1678 parser.usage(e.args[0])
1679 sys.exit(1)
1680
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301681 pack = Pack()
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301682
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301683 if not os.path.exists(parser.out_dname):
1684 os.makedirs(parser.out_dname)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301685
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301686 config = SRC_DIR + "/" + ARCH_NAME + "/config.xml"
1687 root = ET.parse(config)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301688
Gokul Sriram Palanisamyae792312019-01-22 14:33:15 +05301689
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301690# Add nand-4k flash type, if nand flash type is specified
Saravanan Jaganathan93d70cd2018-12-26 16:56:55 +05301691 if "nand" in parser.flash_type.split(","):
Pavithra Palanisamye3c24572018-12-12 19:33:42 +05301692 if root.find(".//data[@type='NAND_PARAMETER']/entry") != None:
1693 parser.flash_type = parser.flash_type + ",nand-4k"
1694
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301695# Format the output image name from Arch, flash type and mode
1696 for flash_type in parser.flash_type.split(","):
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301697 if image_type == "hlos":
1698 if MODE == "64":
1699 parser.out_fname = flash_type + "-" + ARCH_NAME + "_" + MODE + "-apps.img"
1700 else:
1701 parser.out_fname = flash_type + "-" + ARCH_NAME + "-apps.img"
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301702 else:
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301703 if flash_type == "emmc" and lk == "true":
1704 suffix = "-single-lkboot.img"
Gokul Sriram Palanisamyae792312019-01-22 14:33:15 +05301705 gen_kernelboot_img(parser)
1706
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301707 else:
1708 suffix = "-single.img"
Gokul Sriram Palanisamy7b83f682018-12-26 11:55:04 +05301709
Pavithra Palanisamyfb64e6d2019-01-04 12:38:16 +05301710 if MODE == "64":
1711 parser.out_fname = flash_type + "-" + ARCH_NAME + "_" + MODE + suffix
1712 else:
1713 parser.out_fname = flash_type + "-" + ARCH_NAME + suffix
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301714
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301715 parser.out_fname = os.path.join(parser.out_dname, parser.out_fname)
Aditya Kumar Patra S117caa32017-03-21 12:19:27 +05301716
Aditya Kumar Patra Sd6885532017-05-30 12:09:25 +05301717 pack.main_bconf(flash_type, parser.images_dname,
1718 parser.out_fname, root)
Aditya Kumar Patra S12f0be02016-10-25 18:41:15 +05301719
1720if __name__ == "__main__":
1721 main()