• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/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:])
185