blob: a07eb9866e055d73d1719c5ee69a75d9db68c16a [file] [log] [blame]
John Stultzb2313ea2017-08-08 14:18:44 -07001#!/usr/bin/env python
2
3import os
4import os.path
5import sys, getopt
6import binascii
7import struct
8import string
9
10# --------------------------
11# | loader | BL1 | NS BL1U |
12# --------------------------
13
14class generator(object):
15 #
16 # struct l_loader_head {
17 # unsigned int first_instr;
18 # unsigned char magic[16]; @ BOOTMAGICNUMBER!
19 # unsigned int l_loader_start; @ start of loader
20 # unsigned int l_loader_end; @ end of BL1 (without ns_bl1u)
21 # };
22 file_header = [0, 0, 0, 0, 0, 0, 0]
23
24 #
25 # struct entry_head {
26 # unsigned char magic[8]; @ ENTY
27 # unsigned char name[8]; @ loader/bl1/ns_bl1u
28 # unsigned int start_lba;
29 # unsigned int count_lba;
30 # unsigned int flag; @ boot partition or not
31 # };
32 # size of struct entry_head is 28
33 #
34
35 s1_entry_name = ['loader', 'bl1', 'ns_bl1u']
36
37 block_size = 512
38
39 # set in self.add()
40 idx = 0
41
42 # file pointer
43 p_entry = 0 # pointer in header
44 p_file = 0 # pointer in file
45 p_loader_end = 0 # pointer in header
46
47 def __init__(self, out_img):
48 try:
49 self.fp = open(out_img, "wb+")
50 except IOError, e:
51 print "*** file open error:", e
52 sys.exit(3)
53 else:
54 self.entry_hd = [[0 for col in range(7)] for row in range(5)]
55
56 def __del__(self):
57 self.fp.close()
58
59 def add(self, lba, fname):
60 try:
61 fsize = os.path.getsize(fname)
62 except IOError, e:
63 print "*** file open error:", e
64 sys.exit(4)
65 else:
66 blocks = (fsize + self.block_size - 1) / self.block_size
67 # Boot Area1 in eMMC
68 bootp = 1
69 if self.idx == 0:
70 # both loader and bl1.bin locates in l-loader.bin bias 2KB
71 self.p_entry = 28
72 elif (self.idx > 1):
73 # image: ns_bl1u
74 # Record the end of loader & BL1. ns_bl1u won't be loaded by BootROM.
75 self.p_loader_end = self.p_file
76 # ns_bl1u should locates in l-loader.bin bias 2KB too
77 if (self.p_file < (lba * self.block_size - 2048)):
78 self.p_file = lba * self.block_size - 2048
79
80 # Maybe the file size isn't aligned. So pad it.
81 if (self.idx == 0):
82 if fsize > 2048:
83 print 'loader size exceeds 2KB. file size: ', fsize
84 sys.exit(4)
85 else:
86 left_bytes = 2048 - fsize
87 else:
88 left_bytes = fsize % self.block_size
89 if left_bytes:
90 left_bytes = self.block_size - left_bytes
91 print 'lba: ', lba, 'blocks: ', blocks, 'bootp: ', bootp, 'fname: ', fname
92 # write images
93 fimg = open(fname, "rb")
94 for i in range (0, blocks):
95 buf = fimg.read(self.block_size)
96 # loader's p_file is 0 at here
97 self.fp.seek(self.p_file)
98 self.fp.write(buf)
99 # p_file is the file pointer of the new binary file
100 # At last, it means the total block size of the new binary file
101 self.p_file += self.block_size
102
103 if (self.idx == 0):
104 self.p_file = 2048
105 print 'p_file: ', self.p_file, 'last block is ', fsize % self.block_size, 'bytes', ' tell: ', self.fp.tell(), 'left_bytes: ', left_bytes
106 if left_bytes:
107 for i in range (0, left_bytes):
108 zero = struct.pack('x')
109 self.fp.write(zero)
110 print 'p_file: ', self.p_file, ' pad to: ', self.fp.tell()
111
112 # write entry information at the header
113 byte = struct.pack('8s8siii', 'ENTRYHDR', self.s1_entry_name[self.idx], lba, blocks, bootp)
114 self.fp.seek(self.p_entry)
115 self.fp.write(byte)
116 self.p_entry += 28
117 self.idx += 1
118
119 fimg.close()
120
121 def hex2(self, data):
122 return data > 0 and hex(data) or hex(data & 0xffffffff)
123
124 def end(self):
125 self.fp.seek(20)
126 start,end = struct.unpack("ii", self.fp.read(8))
127 print "start: ", self.hex2(start), 'end: ', self.hex2(end)
128 end = start + self.p_loader_end
129 print "start: ", self.hex2(start), 'end: ', self.hex2(end)
130 self.fp.seek(24)
131 byte = struct.pack('i', end)
132 self.fp.write(byte)
133 self.fp.close()
134
135 def create(self, img_loader, img_bl1, img_ns_bl1u, output_img):
136 print '+-----------------------------------------------------------+'
137 print ' Input Images:'
138 print ' loader: ', img_loader
139 print ' bl1: ', img_bl1
140 print ' ns_bl1u: ', img_ns_bl1u
141 print ' Ouput Image: ', output_img
142 print '+-----------------------------------------------------------+\n'
143
144 self.stage = 1
145
146 # The first 2KB is reserved
147 # The next 2KB is for loader image
148 self.add(4, img_loader)
149 print 'self.idx: ', self.idx
150 # bl1.bin starts from 4KB
151 self.add(8, img_bl1)
152 if img_ns_bl1u != 0:
153 # ns_bl1u.bin starts from 96KB
154 self.add(192, img_ns_bl1u)
155
156def main(argv):
157 img_ns_bl1u = 0
158 try:
159 opts, args = getopt.getopt(argv,"ho:",["img_loader=","img_bl1=","img_ns_bl1u="])
160 except getopt.GetoptError:
161 print 'gen_loader.py -o <l-loader.bin> --img_loader <l-loader> --img_bl1 <bl1.bin> --img_ns_bl1u <ns_bl1u.bin>'
162 sys.exit(2)
163 for opt, arg in opts:
164 if opt == '-h':
165 print 'gen_loader.py -o <l-loader.bin> --img_loader <l-loader> --img_bl1 <bl1.bin> --img_ns_bl1u <ns_bl1u.bin>'
166 sys.exit(1)
167 elif opt == '-o':
168 output_img = arg
169 elif opt in ("--img_loader"):
170 img_loader = arg
171 elif opt in ("--img_bl1"):
172 img_bl1 = arg
173 elif opt in ("--img_ns_bl1u"):
174 img_ns_bl1u = arg
175
176 loader = generator(output_img)
177 loader.idx = 0
178
179 loader.create(img_loader, img_bl1, img_ns_bl1u, output_img)
180
181 loader.end()
182
183if __name__ == "__main__":
184 main(sys.argv[1:])