Make the requirement of python2 explicit in scripts that are incompatible with python3. Change-Id: I77f150bdb3aab316fc3c3a21b911db397fa0106f Signed-off-by: Nico Huber <nico.h@gmx.de> Reviewed-on: https://review.coreboot.org/13286 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
		
			
				
	
	
		
			201 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python2
 | 
						|
# Copyright (c) 2014, The Linux Foundation. All rights reserved.
 | 
						|
#
 | 
						|
# Redistribution and use in source and binary forms, with or without
 | 
						|
# modification, are permitted provided that the following conditions are
 | 
						|
# met:
 | 
						|
#    * Redistributions of source code must retain the above copyright
 | 
						|
#      notice, this list of conditions and the following disclaimer.
 | 
						|
#    * Redistributions in binary form must reproduce the above
 | 
						|
#      copyright notice, this list of conditions and the following
 | 
						|
#      disclaimer in the documentation and/or other materials provided
 | 
						|
#      with the distribution.
 | 
						|
#    * Neither the name of The Linux Foundation nor the names of its
 | 
						|
#      contributors may be used to endorse or promote products derived
 | 
						|
#      from this software without specific prior written permission.
 | 
						|
 | 
						|
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
						|
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
						|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 | 
						|
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 | 
						|
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
						|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
						|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 | 
						|
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 | 
						|
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 | 
						|
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 | 
						|
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
 | 
						|
import struct
 | 
						|
import sys
 | 
						|
import os
 | 
						|
 | 
						|
"""A utility to generate ipq8064 uber SBL..
 | 
						|
 | 
						|
The very first blob (aka 'uber SBL') read out of NOR SPI flash by the IPQ8064
 | 
						|
maskrom is supposed to be a concatenation of up to three binaries: one to run
 | 
						|
on the RPM, another one to run on the AP, and the third one - the actual
 | 
						|
coreboot bootblock.
 | 
						|
 | 
						|
The uber SBL starts with the combined header descriptor of 80 bytes, with the
 | 
						|
first two 4 byte words set to certain values, and the total size of the
 | 
						|
payload saved at offsets 28 and 32.
 | 
						|
 | 
						|
To generate the uber SBL this utility expects two or three input file names in
 | 
						|
the command line, the first file including the described header, and the
 | 
						|
following one(s) - in QCA MBN format. This allows to create the uber SBL in
 | 
						|
one or two invocations.
 | 
						|
 | 
						|
The input files are concatenated together aligned at 256 byte boundary offset
 | 
						|
from the combined header. See Usage() below for more details.
 | 
						|
 | 
						|
The resulting uber SBL file is prepended by the same combined header adjusted
 | 
						|
to reflect the new total file size.
 | 
						|
"""
 | 
						|
 | 
						|
DEFAULT_OUTPUT_FILE_NAME = 'sbl-ro.mbn'
 | 
						|
 | 
						|
class NorSbl:
 | 
						|
    """Object representing the uber SBL."""
 | 
						|
 | 
						|
    NOR_SBL1_HEADER    = '<II72s'
 | 
						|
    NOR_SBL1_HEADER_SZ = struct.calcsize(NOR_SBL1_HEADER)
 | 
						|
    ALIGNMENT          = 256    # Make sure this == UBER_SBL_PAD_SIZE
 | 
						|
    NOR_CODE_WORD      = 0x844bdcd1
 | 
						|
    MAGIC_NUM          = 0x73d71034
 | 
						|
 | 
						|
    def __init__(self, sbl1, verbose):
 | 
						|
        """Initialize the object and verify the first file in the sequence.
 | 
						|
 | 
						|
        Args:
 | 
						|
          sbl1: string, the name of the first out of the three input blobs,
 | 
						|
                must be prepended by the combined header.
 | 
						|
          verbose: boolean, if True - print debug information on the console.
 | 
						|
        """
 | 
						|
        self.verbose = verbose
 | 
						|
        self.mbn_file_names = []
 | 
						|
        if self.verbose:
 | 
						|
            print 'Reading ' + sbl1
 | 
						|
 | 
						|
        try:
 | 
						|
            self.sbl1 = open(sbl1, 'rb').read()
 | 
						|
        except IOError as e:
 | 
						|
            print 'I/O error({0}): {1}'.format(e.errno, e.strerror)
 | 
						|
            raise
 | 
						|
 | 
						|
        (codeword, magic,  _) = struct.unpack_from(
 | 
						|
            self.NOR_SBL1_HEADER, self.sbl1)
 | 
						|
 | 
						|
        if codeword != self.NOR_CODE_WORD:
 | 
						|
            print '\n\nError: Unexpected Codeword!'
 | 
						|
            print 'Codeword    : ' + ('0x%x' % self.NOR_CODE_WORD) + \
 | 
						|
                ' != ' + ('0x%x' % codeword)
 | 
						|
            sys.exit(-1)
 | 
						|
 | 
						|
        if magic != self.MAGIC_NUM:
 | 
						|
            print '\n\nError: Unexpected Magic!'
 | 
						|
            print 'Magic    : ' + ('0x%x' % self.MAGIC_NUM) + \
 | 
						|
                ' != ' + ('0x%x' % magic)
 | 
						|
            sys.exit(-1)
 | 
						|
 | 
						|
    def Append(self, src):
 | 
						|
        """Add a file to the list of files to be concatenated"""
 | 
						|
        self.mbn_file_names.append(src)
 | 
						|
 | 
						|
    def PadOutput(self, outfile, size):
 | 
						|
        """Pad output file to the required alignment.
 | 
						|
 | 
						|
        Adds 0xff to the passed in file to get its size to the ALIGNMENT
 | 
						|
        boundary.
 | 
						|
 | 
						|
        Args:
 | 
						|
          outfile: file handle of the file to be padded
 | 
						|
          size: int, current size of the file
 | 
						|
 | 
						|
       Returns number of bytes in the added padding.
 | 
						|
       """
 | 
						|
 | 
						|
        # Is padding needed?
 | 
						|
        overflow = size % self.ALIGNMENT
 | 
						|
        if overflow:
 | 
						|
            pad_size = self.ALIGNMENT - overflow
 | 
						|
            pad = '\377' * pad_size
 | 
						|
            outfile.write(pad)
 | 
						|
            if self.verbose:
 | 
						|
                print 'Added %d byte padding' % pad_size
 | 
						|
            return pad_size
 | 
						|
        return 0
 | 
						|
 | 
						|
    def Create(self, out_file_name):
 | 
						|
        """Create the uber SBL.
 | 
						|
 | 
						|
        Concatenate input files with the appropriate padding and update the
 | 
						|
        combined header to reflect the new blob size.
 | 
						|
 | 
						|
        Args:
 | 
						|
          out_file_name: string, name of the file to save the generated uber
 | 
						|
                         SBL in.
 | 
						|
       """
 | 
						|
        outfile = open(out_file_name, 'wb')
 | 
						|
        total_size = len(self.sbl1) - self.NOR_SBL1_HEADER_SZ
 | 
						|
        outfile.write(self.sbl1)
 | 
						|
 | 
						|
        for mbn_file_name in self.mbn_file_names:
 | 
						|
            total_size += self.PadOutput(outfile, total_size)
 | 
						|
            mbn_file_data = open(mbn_file_name, 'r').read()
 | 
						|
            outfile.write(mbn_file_data)
 | 
						|
            if self.verbose:
 | 
						|
                print 'Added %s (%d bytes)' % (mbn_file_name,
 | 
						|
                                               len(mbn_file_data))
 | 
						|
            total_size += len(mbn_file_data)
 | 
						|
 | 
						|
        outfile.seek(28)
 | 
						|
        outfile.write(struct.pack('<I', total_size))
 | 
						|
        outfile.write(struct.pack('<I', total_size))
 | 
						|
 | 
						|
 | 
						|
def Usage(v):
 | 
						|
    print '%s: [-v] [-h] [-o Output MBN] sbl1 sbl2 [bootblock]' % (
 | 
						|
        os.path.basename(sys.argv[0]))
 | 
						|
    print
 | 
						|
    print 'Concatenates up to three mbn files: two SBLs and a coreboot bootblock'
 | 
						|
    print '    -h This message'
 | 
						|
    print '    -v verbose'
 | 
						|
    print '    -o Output file name, (default: %s)\n' % DEFAULT_OUTPUT_FILE_NAME
 | 
						|
    sys.exit(v)
 | 
						|
 | 
						|
def main():
 | 
						|
    verbose = 0
 | 
						|
    mbn_output = DEFAULT_OUTPUT_FILE_NAME
 | 
						|
    i = 0
 | 
						|
 | 
						|
    while i < (len(sys.argv) - 1):
 | 
						|
        i += 1
 | 
						|
        if (sys.argv[i] == '-h'):
 | 
						|
            Usage(0)    # doesn't return
 | 
						|
 | 
						|
        if (sys.argv[i] == '-o'):
 | 
						|
            mbn_output = sys.argv[i + 1]
 | 
						|
            i += 1
 | 
						|
            continue
 | 
						|
 | 
						|
        if (sys.argv[i] == '-v'):
 | 
						|
            verbose = 1
 | 
						|
            continue
 | 
						|
 | 
						|
        break
 | 
						|
 | 
						|
    argv = sys.argv[i:]
 | 
						|
    if len(argv) < 2 or len(argv) > 3:
 | 
						|
        Usage(-1)
 | 
						|
 | 
						|
    nsbl = NorSbl(argv[0], verbose)
 | 
						|
 | 
						|
    for mbnf in argv[1:]:
 | 
						|
        nsbl.Append(mbnf)
 | 
						|
 | 
						|
    nsbl.Create(mbn_output)
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    main()
 |