[e8c180f] | 1 | #!/usr/bin/env python2 |
---|
| 2 | |
---|
[fc078db] | 3 | # A quickly bashed together replacement for u-boot's mkimage written in python |
---|
| 4 | # |
---|
[90713f7] | 5 | # Copyright 2010 Craig Barker |
---|
[e29d0a6] | 6 | # Copyright 2020 Amar Takhar <amar@rtems.org> |
---|
[fc078db] | 7 | # |
---|
[90713f7] | 8 | # Redistribution and use in source and binary forms, with or without |
---|
[fc078db] | 9 | # modification, are permitted provided that the following conditions are met: |
---|
| 10 | # |
---|
[90713f7] | 11 | # 1. Redistributions of source code must retain the above copyright notice, |
---|
[fc078db] | 12 | # this list of conditions and the following disclaimer. |
---|
| 13 | # |
---|
| 14 | # 2. Redistributions in binary form must reproduce the above copyright notice, |
---|
| 15 | # this list of conditions and the following disclaimer in the documentation |
---|
| 16 | # and/or other materials provided with the distribution. |
---|
| 17 | # |
---|
[90713f7] | 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
| 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
| 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
| 21 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
---|
| 22 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
| 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
| 24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
---|
| 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
| 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
| 27 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
---|
[fc078db] | 28 | # POSSIBILITY OF SUCH DAMAGE. |
---|
| 29 | |
---|
| 30 | |
---|
[e29d0a6] | 31 | import argparse |
---|
[fc078db] | 32 | from struct import * |
---|
| 33 | import sys |
---|
| 34 | import os.path |
---|
| 35 | import time |
---|
| 36 | import binascii |
---|
| 37 | |
---|
| 38 | MAGIC = 0x27051956 |
---|
| 39 | IMG_NAME_LENGTH = 32 |
---|
| 40 | |
---|
| 41 | archs = {'invalid':0, 'alpha':1, 'arm':2, 'x86':3, 'ia64':4, 'm68k':12, |
---|
| 42 | 'microblaze':14, 'mips':5, 'mips64':6, 'nios':13, 'nios2':15, |
---|
| 43 | 'powerpc':7, 'ppc':7, 's390':8, 'sh':9, 'sparc':10, |
---|
| 44 | 'sparc64':11, 'blackfin':16, 'arv32':17, 'st200':18 } |
---|
| 45 | |
---|
| 46 | oss = {'invalid':0, 'openbsd':1, 'netbsd':2, 'freebsd':3, '4_4bsd':4, |
---|
| 47 | 'linux':5, 'svr4':6, 'esix':7, 'solaris':8, 'irix':9, |
---|
| 48 | 'sco':10, 'dell':11, 'ncr':12, 'lynos':13, 'vxworks':14, |
---|
| 49 | 'psos':15, 'qnx':16, 'u-boot':17, 'rtems':18, 'artos':19, |
---|
| 50 | 'unity':20, 'integrity':21 } |
---|
| 51 | |
---|
| 52 | types = {'invalid':0, 'standalone':1, 'kernel':2, 'ramdisk':3, 'multi':4, |
---|
| 53 | 'firmware':5,'script':6, 'filesystem':7, 'flat_dt':8 } |
---|
| 54 | |
---|
| 55 | comps = {'none':0, 'bzip2':2, 'gzip':1, 'lzma':3 } |
---|
| 56 | |
---|
[e29d0a6] | 57 | parser = argparse.ArgumentParser() |
---|
| 58 | |
---|
| 59 | parser.add_argument("-A","--arch", dest="arch", default="powerpc", |
---|
[fc078db] | 60 | help="set architecture to 'arch'", metavar="ARCH") |
---|
[e29d0a6] | 61 | parser.add_argument("-O","--os", dest="os", default="linux", |
---|
[fc078db] | 62 | help="set operating system to 'os'", metavar="OS") |
---|
[e29d0a6] | 63 | parser.add_argument("-T","--type", dest="type", default="kernel", |
---|
[fc078db] | 64 | help="set image type to 'type'", metavar="TYPE") |
---|
[e29d0a6] | 65 | parser.add_argument("-C","--comp", dest="comp", default="gzip", |
---|
[fc078db] | 66 | help="set compression type 'comp'", metavar="COMP") |
---|
[e29d0a6] | 67 | parser.add_argument("-a","--addr", dest="addr", default="0", |
---|
[fc078db] | 68 | help="set load address to 'addr' (hex)", metavar="ADDR") |
---|
[e29d0a6] | 69 | parser.add_argument("-e","--ep", dest="ep", default="0", |
---|
[fc078db] | 70 | help="set entry point to 'ep' (hex)", metavar="EP") |
---|
[e29d0a6] | 71 | parser.add_argument("-n","--name", dest="name", default="", |
---|
[fc078db] | 72 | help="set image name to 'name'", metavar="NAME") |
---|
[e29d0a6] | 73 | parser.add_argument("-d","--datafile", dest="datafile", |
---|
| 74 | help="use image data from 'datafile'", metavar="DATAFILE", required=True) |
---|
| 75 | parser.add_argument("-x","--xip", action="store_true", dest="xip", default=False, |
---|
[fc078db] | 76 | help="set XIP (execute in place)") |
---|
[e29d0a6] | 77 | parser.add_argument("outputfile", |
---|
| 78 | help="Output file.", metavar="OUTPUTFILE") |
---|
[fc078db] | 79 | |
---|
| 80 | |
---|
[e29d0a6] | 81 | options = parser.parse_args() |
---|
[fc078db] | 82 | |
---|
[90713f7] | 83 | if options.arch not in archs: |
---|
[fc078db] | 84 | print "Invalid architecture specified, aborting" |
---|
| 85 | sys.exit(2) |
---|
| 86 | |
---|
| 87 | if options.os not in oss: |
---|
| 88 | print "Invalid operating system specified, aborting" |
---|
[90713f7] | 89 | sys.exit(2) |
---|
[fc078db] | 90 | |
---|
| 91 | if options.comp not in comps: |
---|
| 92 | print "Invalid compression specified, aborting" |
---|
[90713f7] | 93 | sys.exit(2) |
---|
[fc078db] | 94 | |
---|
| 95 | if options.type not in types: |
---|
| 96 | print "Invalid image type specified, aborting" |
---|
[90713f7] | 97 | sys.exit(2) |
---|
[fc078db] | 98 | |
---|
| 99 | try: |
---|
| 100 | inputsize = os.path.getsize(options.datafile) |
---|
| 101 | inputfile = open(options.datafile, 'rb') |
---|
| 102 | |
---|
[e29d0a6] | 103 | except OSError as e: |
---|
| 104 | print "Invalid datafile specified, aborting: %s" % e |
---|
[fc078db] | 105 | sys.exit(2) |
---|
| 106 | |
---|
| 107 | try: |
---|
[e29d0a6] | 108 | outputfile = open(options.outputfile,'wb') |
---|
[fc078db] | 109 | |
---|
[e29d0a6] | 110 | except IOError as e: |
---|
| 111 | print "Error opening output file for writing, aborting: %s" % e |
---|
[fc078db] | 112 | sys.exit(1) |
---|
| 113 | |
---|
| 114 | struct = Struct("!IIIIIIIBBBB"+str(IMG_NAME_LENGTH)+"s") |
---|
| 115 | |
---|
| 116 | outputfile.seek(struct.size); |
---|
| 117 | |
---|
| 118 | inputcrc = 0; |
---|
| 119 | |
---|
| 120 | while True: |
---|
| 121 | inputblock = inputfile.read(4096) |
---|
| 122 | if not inputblock: break |
---|
| 123 | inputcrc = binascii.crc32(inputblock, inputcrc) |
---|
| 124 | outputfile.write(inputblock) |
---|
| 125 | |
---|
| 126 | inputcrc = inputcrc & 0xffffffff |
---|
| 127 | |
---|
[90713f7] | 128 | structdata = struct.pack(MAGIC, 0, int(time.time()), inputsize, |
---|
| 129 | int(options.addr,16), int(options.ep,16), inputcrc, |
---|
| 130 | oss[options.os], archs[options.arch], types[options.type], |
---|
[fc078db] | 131 | comps[options.comp], options.name) |
---|
| 132 | |
---|
| 133 | headercrc = binascii.crc32(structdata) & 0xFFFFFFFF |
---|
| 134 | |
---|
| 135 | structdata = struct.pack(MAGIC, headercrc, int(time.time()), inputsize, |
---|
| 136 | int(options.addr,16), int(options.ep,16), inputcrc, |
---|
| 137 | oss[options.os], archs[options.arch], types[options.type], |
---|
| 138 | comps[options.comp], options.name) |
---|
| 139 | |
---|
| 140 | outputfile.seek(0) |
---|
| 141 | outputfile.write(structdata) |
---|
| 142 | outputfile.close() |
---|
| 143 | inputfile.close() |
---|