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