#!/usr/bin/env python
import os
import os.path
import sys, getopt
import binascii
import struct
import string
# --------------------------
# | loader | BL1 | NS BL1U |
# --------------------------
class generator(object):
#
# struct l_loader_head {
# unsigned int first_instr;
# unsigned char magic[16]; @ BOOTMAGICNUMBER!
# unsigned int l_loader_start; @ start of loader
# unsigned int l_loader_end; @ end of BL1 (without ns_bl1u)
# };
file_header = [0, 0, 0, 0, 0, 0, 0]
#
# struct entry_head {
# unsigned char magic[8]; @ ENTY
# unsigned char name[8]; @ loader/bl1/ns_bl1u
# unsigned int start_lba;
# unsigned int count_lba;
# unsigned int flag; @ boot partition or not
# };
# size of struct entry_head is 28
#
s1_entry_name = ['loader', 'bl1', 'ns_bl1u']
block_size = 512
# set in self.add()
idx = 0
# file pointer
p_entry = 0 # pointer in header
p_file = 0 # pointer in file
p_loader_end = 0 # pointer in header
def __init__(self, out_img):
try:
self.fp = open(out_img, "wb+")
except IOError, e:
print "*** file open error:", e
sys.exit(3)
else:
self.entry_hd = [[0 for col in range(7)] for row in range(5)]
def __del__(self):
self.fp.close()
def add(self, lba, fname):
try:
fsize = os.path.getsize(fname)
except IOError, e:
print "*** file open error:", e
sys.exit(4)
else:
blocks = (fsize + self.block_size - 1) / self.block_size
# Boot Area1 in eMMC
bootp = 1
if self.idx == 0:
# both loader and bl1.bin locates in l-loader.bin bias 2KB
self.p_entry = 28
elif (self.idx > 1):
# image: ns_bl1u
# Record the end of loader & BL1. ns_bl1u won't be loaded by BootROM.
self.p_loader_end = self.p_file
# ns_bl1u should locates in l-loader.bin bias 2KB too
if (self.p_file < (lba * self.block_size - 2048)):
self.p_file = lba * self.block_size - 2048
# Maybe the file size isn't aligned. So pad it.
if (self.idx == 0):
if fsize > 2048:
print 'loader size exceeds 2KB. file size: ', fsize
sys.exit(4)
else:
left_bytes = 2048 - fsize
else:
left_bytes = fsize % self.block_size
if left_bytes:
left_bytes = self.block_size - left_bytes
print 'lba: ', lba, 'blocks: ', blocks, 'bootp: ', bootp, 'fname: ', fname
# write images
fimg = open(fname, "rb")
for i in range (0, blocks):
buf = fimg.read(self.block_size)
# loader's p_file is 0 at here
self.fp.seek(self.p_file)
self.fp.write(buf)
# p_file is the file pointer of the new binary file
# At last, it means the total block size of the new binary file
self.p_file += self.block_size
if (self.idx == 0):
self.p_file = 2048
print 'p_file: ', self.p_file, 'last block is ', fsize % self.block_size, 'bytes', ' tell: ', self.fp.tell(), 'left_bytes: ', left_bytes
if left_bytes:
for i in range (0, left_bytes):
zero = struct.pack('x')
self.fp.write(zero)
print 'p_file: ', self.p_file, ' pad to: ', self.fp.tell()
# write entry information at the header
byte = struct.pack('8s8siii', 'ENTRYHDR', self.s1_entry_name[self.idx], lba, blocks, bootp)
self.fp.seek(self.p_entry)
self.fp.write(byte)
self.p_entry += 28
self.idx += 1
fimg.close()
def hex2(self, data):
return data > 0 and hex(data) or hex(data & 0xffffffff)
def end(self):
self.fp.seek(20)
start,end = struct.unpack("ii", self.fp.read(8))
print "start: ", self.hex2(start), 'end: ', self.hex2(end)
end = start + self.p_loader_end
print "start: ", self.hex2(start), 'end: ', self.hex2(end)
self.fp.seek(24)
byte = struct.pack('i', end)
self.fp.write(byte)
self.fp.close()
def create(self, img_loader, img_bl1, img_ns_bl1u, output_img):
print '+-----------------------------------------------------------+'
print ' Input Images:'
print ' loader: ', img_loader
print ' bl1: ', img_bl1
print ' ns_bl1u: ', img_ns_bl1u
print ' Ouput Image: ', output_img
print '+-----------------------------------------------------------+\n'
self.stage = 1
# The first 2KB is reserved
# The next 2KB is for loader image
self.add(4, img_loader)
print 'self.idx: ', self.idx
# bl1.bin starts from 4KB
self.add(8, img_bl1)
if img_ns_bl1u != 0:
# ns_bl1u.bin starts from 96KB
self.add(192, img_ns_bl1u)
def main(argv):
img_ns_bl1u = 0
try:
opts, args = getopt.getopt(argv,"ho:",["img_loader=","img_bl1=","img_ns_bl1u="])
except getopt.GetoptError:
print 'gen_loader.py -o <l-loader.bin> --img_loader <l-loader> --img_bl1 <bl1.bin> --img_ns_bl1u <ns_bl1u.bin>'
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print 'gen_loader.py -o <l-loader.bin> --img_loader <l-loader> --img_bl1 <bl1.bin> --img_ns_bl1u <ns_bl1u.bin>'
sys.exit(1)
elif opt == '-o':
output_img = arg
elif opt in ("--img_loader"):
img_loader = arg
elif opt in ("--img_bl1"):
img_bl1 = arg
elif opt in ("--img_ns_bl1u"):
img_ns_bl1u = arg
loader = generator(output_img)
loader.idx = 0
loader.create(img_loader, img_bl1, img_ns_bl1u, output_img)
loader.end()
if __name__ == "__main__":
main(sys.argv[1:])