4
0
mirror of https://github.com/RT-Thread/rt-thread.git synced 2025-02-26 00:17:23 +08:00
Chen Wang 7836e6ee4d bsp: cvitek: update combine.sh for arm64
Move the combine.sh to under cv18xx_aarch64, so we can
run this script the same as scons and no need to change
cwd.

Rename the folder boot to prebuild just becuase all the
files under boot are prebuild binaries.
Move the prebuilt fip.bin to under prebuild/milkv-duo256m
because it's only for 256.

Update combine.sh accordingly and output fip.bin to the output
folder where we create fip.bin/boot.sd as other bsp.

Signed-off-by: Chen Wang <unicorn_wang@outlook.com>
2024-12-30 11:32:10 +08:00

804 lines
25 KiB
Python
Executable File

#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause
# PYTHON_ARGCOMPLETE_OK
import sys
import logging
import os
import os.path
import argparse
from collections import OrderedDict
import binascii
from struct import pack, unpack
import lzma
import pprint
PYTHON_MIN_VERSION = (3, 5, 2) # Ubuntu 16.04 LTS contains Python v3.5.2 by default
if sys.version_info < PYTHON_MIN_VERSION:
print("Python >= %r is required" % (PYTHON_MIN_VERSION,))
sys.exit(-1)
try:
import coloredlogs
except ImportError:
coloredlogs = None
try:
import argcomplete
except ImportError:
argcomplete = None
LOADER_2ND_MAGIC_ORIG = b"BL33"
LOADER_2ND_MAGIC_LZMA = b"B3MA"
LOADER_2ND_MAGIC_LZ4 = b"B3Z4"
LOADER_2ND_MAGIC_LIST = [
LOADER_2ND_MAGIC_ORIG,
LOADER_2ND_MAGIC_LZMA,
LOADER_2ND_MAGIC_LZ4,
]
IMAGE_ALIGN = 512
PARAM1_SIZE = 0x1000
PARAM1_SIZE_WO_SIG = 0x800
PARAM2_SIZE = 0x1000
def round_up(divident, divisor):
return ((divident + divisor - 1) // divisor) * divisor
def lzma_compress(body):
z = lzma.LZMACompressor(lzma.FORMAT_ALONE, preset=lzma.PRESET_EXTREME)
compressed = z.compress(body)
compressed += z.flush()
return compressed
def lz4_compress(body):
try:
import lz4.frame
except ImportError:
logging.error("lz4 is not installed. Run 'pip install lz4'.")
raise
compressed = lz4.frame.compress(body)
return compressed
class Entry:
__slots__ = "name", "type", "addr", "_content", "entry_size"
def __init__(self):
self.addr = None
self._content = None
@property
def end(self):
return self.addr + self.entry_size
@property
def content(self):
return self._content
@content.setter
def content(self, value):
if type(value) == int:
value = value.to_bytes(self.entry_size, "little")
if self.entry_size is not None:
if len(value) > self.entry_size:
raise ValueError("%s (%d bytes) must <= %#r" % (self.name, len(value), self.entry_size))
value = value + b"\0" * (self.entry_size - len(value))
self._content = value
@classmethod
def make(cls, name, entry_size, _type, init=None):
entry = Entry()
entry.name = name
entry.type = _type
entry.entry_size = entry_size
if type(init) in (bytes, bytearray):
entry.content = bytes(init)
elif entry_size is not None:
entry.content = b"\0" * entry.entry_size
else:
entry.content = b""
return (name, entry)
def toint(self):
if self.type != int:
raise TypeError("%s is not int type" % self.name)
return int.from_bytes(self.content, "little")
def tostr(self):
v = self.content
if self.type == int:
v = "%#08x" % self.toint()
elif type(self.content) in [bytes, bytearray]:
v = v.hex()
if len(v) > 32:
v = v[:32] + "..."
return v
def __str__(self):
v = self.tostr()
return "<%s=%s (%dbytes)>" % (self.name, v, self.entry_size)
def __repr__(self):
v = self.tostr()
return "<%s: a=%#x s=%#x c=%s %r>" % (self.name, self.addr, self.entry_size, v, self.type)
class FIP:
param1 = OrderedDict(
[
Entry.make("MAGIC1", 8, int, b"CVBL01\n\0"),
Entry.make("MAGIC2", 4, int),
Entry.make("PARAM_CKSUM", 4, int),
Entry.make("NAND_INFO", 128, int),
Entry.make("NOR_INFO", 36, int),
Entry.make("FIP_FLAGS", 8, int),
Entry.make("CHIP_CONF_SIZE", 4, int),
Entry.make("BLCP_IMG_CKSUM", 4, int),
Entry.make("BLCP_IMG_SIZE", 4, int),
Entry.make("BLCP_IMG_RUNADDR", 4, int),
Entry.make("BLCP_PARAM_LOADADDR", 4, int),
Entry.make("BLCP_PARAM_SIZE", 4, int),
Entry.make("BL2_IMG_CKSUM", 4, int),
Entry.make("BL2_IMG_SIZE", 4, int),
Entry.make("BLD_IMG_SIZE", 4, int),
Entry.make("PARAM2_LOADADDR", 4, int),
Entry.make("RESERVED1", 4, int),
Entry.make("CHIP_CONF", 760, bytes),
Entry.make("BL_EK", 32, bytes),
Entry.make("ROOT_PK", 512, bytes),
Entry.make("BL_PK", 512, bytes),
Entry.make("BL_PK_SIG", 512, bytes),
Entry.make("CHIP_CONF_SIG", 512, bytes),
Entry.make("BL2_IMG_SIG", 512, bytes),
Entry.make("BLCP_IMG_SIG", 512, bytes),
]
)
body1 = OrderedDict(
[
Entry.make("BLCP", None, bytes),
Entry.make("BL2", None, bytes),
]
)
param2 = OrderedDict(
[
Entry.make("MAGIC1", 8, int, b"CVLD02\n\0"),
Entry.make("PARAM2_CKSUM", 4, int),
Entry.make("RESERVED1", 4, bytes),
# DDR param
Entry.make("DDR_PARAM_CKSUM", 4, int),
Entry.make("DDR_PARAM_LOADADDR", 4, int),
Entry.make("DDR_PARAM_SIZE", 4, int),
Entry.make("DDR_PARAM_RESERVED", 4, int),
# BLCP_2ND
Entry.make("BLCP_2ND_CKSUM", 4, int),
Entry.make("BLCP_2ND_LOADADDR", 4, int),
Entry.make("BLCP_2ND_SIZE", 4, int),
Entry.make("BLCP_2ND_RUNADDR", 4, int),
# ATF-BL31 or OpenSBI
Entry.make("MONITOR_CKSUM", 4, int),
Entry.make("MONITOR_LOADADDR", 4, int),
Entry.make("MONITOR_SIZE", 4, int),
Entry.make("MONITOR_RUNADDR", 4, int),
# u-boot
Entry.make("LOADER_2ND_RESERVED0", 4, int),
Entry.make("LOADER_2ND_LOADADDR", 4, int),
Entry.make("LOADER_2ND_RESERVED1", 4, int),
Entry.make("LOADER_2ND_RESERVED2", 4, int),
# Reserved
Entry.make("RESERVED_LAST", 4096 - 16 * 5, bytes),
]
)
body2 = OrderedDict(
[
Entry.make("DDR_PARAM", None, bytes),
Entry.make("BLCP_2ND", None, bytes),
Entry.make("MONITOR", None, bytes),
Entry.make("LOADER_2ND", None, bytes),
]
)
ldr_2nd_hdr = OrderedDict(
[
Entry.make("JUMP0", 4, int),
Entry.make("MAGIC", 4, int),
Entry.make("CKSUM", 4, int),
Entry.make("SIZE", 4, int),
Entry.make("RUNADDR", 8, int),
Entry.make("RESERVED1", 4, int),
Entry.make("RESERVED2", 4, int),
]
)
FIP_FLAGS_SCS_MASK = 0x000c
FIP_FLAGS_ENCRYPTED_MASK = 0x0030
def _param_size(self, param):
return max((e.end for e in param.values()))
def _gen_param(self):
addr = 0
for entry in self.param1.values():
entry.addr = addr
addr += entry.entry_size
assert PARAM1_SIZE_WO_SIG == self.param1["BL_PK_SIG"].addr
addr = 0
for entry in self.param2.values():
entry.addr = addr
addr += entry.entry_size
assert PARAM2_SIZE == self.param2["RESERVED_LAST"].addr + self.param2["RESERVED_LAST"].entry_size
addr = 0
for entry in self.ldr_2nd_hdr.values():
entry.addr = addr
addr += entry.entry_size
def __init__(self):
self.compress_algo = None
self._gen_param()
def image_crc(self, image):
crc = binascii.crc_hqx(image, 0)
crc = pack("<H", crc) + b"\xFE\xCA"
return crc
def pad(self, data, block_size):
if type(data) not in [bytearray, bytes]:
raise TypeError("Need bytearray or bytes")
r = len(data) % block_size
if r:
data += b"\0" * (block_size - r)
return data
def _pprint_attr(self, name):
v = getattr(self, name)
if type(v) == OrderedDict:
v = list(v.values())
logging.info("print(%s):\n" % name + pprint.pformat(v, 4, 140))
def print_fip_params(self):
self._pprint_attr("param1")
self._pprint_attr("param2")
self._pprint_attr("ldr_2nd_hdr")
def read_fip(self, path):
logging.debug("read_fip:")
with open(path, "rb") as fp:
fip_bin = fp.read()
fip_bin = bytearray(fip_bin)
e = self.param1["MAGIC1"]
if fip_bin[e.addr : e.end] != e.content:
raise ValueError("Unknown magic %r" % fip_bin[e.addr : e.end])
# Read param1 from fip.bin
for e in self.param1.values():
e.content = fip_bin[e.addr : e.end]
self.read_end = PARAM1_SIZE
# Read BLCP
e = self.param1["BLCP_IMG_SIZE"]
blcp_img_size = unpack("<I", fip_bin[e.addr : e.end])[0]
if blcp_img_size:
start = self.read_end
self.read_end = start + blcp_img_size
self.body1["BLCP"].content = fip_bin[start : self.read_end]
# Read FSBL as BL2
e = self.param1["BL2_IMG_SIZE"]
bl2_img_size = unpack("<I", fip_bin[e.addr : e.end])[0]
if bl2_img_size:
start = self.read_end
self.read_end = start + bl2_img_size
self.body1["BL2"].content = fip_bin[start : self.read_end]
logging.info("read_fip end=%#x", self.read_end)
self.rest_fip = fip_bin[self.read_end :]
self.read_fip2(fip_bin)
def read_fip2(self, fip_bin):
param2_loadaddr = self.param1["PARAM2_LOADADDR"].toint()
param2_bin = fip_bin[param2_loadaddr : param2_loadaddr + PARAM2_SIZE]
for e in self.param2.values():
e.content = param2_bin[e.addr : e.end]
self.read_end = param2_loadaddr + PARAM2_SIZE
# Read DDR_PARAM, BLCP_2ND, and MONITOR
for name in ["DDR_PARAM", "BLCP_2ND", "MONITOR"]:
size = self.param2[name + "_SIZE"].toint()
loadaddr = self.param2[name + "_LOADADDR"].toint()
self.body2[name].content = fip_bin[loadaddr : loadaddr + size]
self.read_end = loadaddr + size
# Read LOADER_2ND
loader_2nd_loadaddr = self.param2["LOADER_2ND_LOADADDR"].toint()
if loader_2nd_loadaddr:
self.read_loader_2nd(fip_bin)
logging.info("read_fip2 end=%#x", self.read_end)
self.rest_fip = fip_bin[self.read_end :]
def read_loader_2nd(self, fip_bin):
loader_2nd_loadaddr = self.param2["LOADER_2ND_LOADADDR"].toint()
self._parse_ldr_2nd_hdr(fip_bin[loader_2nd_loadaddr:])
if self.ldr_2nd_hdr["MAGIC"].content not in LOADER_2ND_MAGIC_LIST:
raise ValueError("%r" % self.ldr_2nd_hdr["MAGIC"].content)
ldr_2nd_size = self.ldr_2nd_hdr["SIZE"].toint()
self.body2["LOADER_2ND"].content = fip_bin[loader_2nd_loadaddr : loader_2nd_loadaddr + ldr_2nd_size]
self.read_end = loader_2nd_loadaddr + ldr_2nd_size
self.rest_fip = fip_bin[self.read_end :]
def add_chip_conf(self, args):
logging.debug("add_chip_conf:")
with open(args.CHIP_CONF, "rb") as fp:
image = fp.read()
if image.startswith(b"APLB"):
image = image[8:] # strip old BLP header
self.param1["CHIP_CONF"].content = image
def add_blcp(self, args):
logging.debug("add_blcp:")
with open(args.BLCP, "rb") as fp:
image = fp.read()
image = self.pad(image, IMAGE_ALIGN)
self.param1["BLCP_IMG_RUNADDR"].content = args.BLCP_IMG_RUNADDR
self.body1["BLCP"].content = image
def add_bl2(self, args):
logging.debug("add_bl2:")
with open(args.BL2, "rb") as fp:
image = fp.read()
bl2_fill = 0
if args.BL2_FILL:
bl2_fill = args.BL2_FILL
image += b"\xA9" * (bl2_fill - len(image))
image = self.pad(image, IMAGE_ALIGN)
self.body1["BL2"].content = image
def add_nor_info(self, args):
logging.debug("add_nor_info:")
self.param1["NOR_INFO"].content = args.NOR_INFO
def add_nand_info(self, args):
logging.debug("add_nand_info:")
self.param1["NAND_INFO"].content = args.NAND_INFO
def update_param1_cksum(self, image):
image = bytearray(image)
crc = self.image_crc(image[self.param1["NAND_INFO"].addr : PARAM1_SIZE_WO_SIG])
param_cksum = self.param1["PARAM_CKSUM"]
param_cksum.content = crc
image[param_cksum.addr : param_cksum.end] = crc
return image
def make_fip1(self):
logging.debug("make_fip1:")
chip_conf = self.param1["CHIP_CONF"].content
self.param1["CHIP_CONF_SIZE"].content = len(chip_conf)
blcp = self.body1["BLCP"].content
self.param1["BLCP_IMG_CKSUM"].content = self.image_crc(blcp)
self.param1["BLCP_IMG_SIZE"].content = len(blcp)
bl2 = self.body1["BL2"].content
self.param1["BL2_IMG_CKSUM"].content = self.image_crc(bl2)
self.param1["BL2_IMG_SIZE"].content = len(bl2)
# Pack body1
body1_bin = b""
for entry in self.body1.values():
if len(entry.content) % IMAGE_ALIGN:
raise ValueError("%s (%d) is not align to %d" % (entry.name, len(entry.content), IMAGE_ALIGN))
logging.info("add %s (%#x)", entry.name, len(entry.content))
body1_bin += entry.content
logging.debug("len(body1_bin) is %d", len(body1_bin))
# Param1 cksum
param1_bin = b"".join((entry.content for entry in self.param1.values()))
param1_bin = self.update_param1_cksum(param1_bin)
if len(param1_bin) != PARAM1_SIZE:
raise ValueError("param1_bin is %d bytes" % len(param1_bin))
fip1_bin = param1_bin + body1_bin
logging.debug("len(fip1_bin) is %d", len(fip1_bin))
return fip1_bin
def add_ddr_param(self, args):
with open(args.DDR_PARAM, "rb") as fp:
ddr_param = fp.read()
logging.debug("ddr_param=%#x bytes", len(ddr_param))
self.body2["DDR_PARAM"].content = ddr_param
def add_blcp_2nd(self, args):
with open(args.BLCP_2ND, "rb") as fp:
blcp_2nd = fp.read()
logging.debug("blcp_2nd=%#x bytes", len(blcp_2nd))
self.body2["BLCP_2ND"].content = blcp_2nd
def add_monitor(self, args):
with open(args.MONITOR, "rb") as fp:
monitor = fp.read()
logging.debug("monitor=%#x bytes", len(monitor))
self.body2["MONITOR"].content = monitor
def add_loader_2nd(self, args):
with open(args.LOADER_2ND, "rb") as fp:
loader_2nd = fp.read()
logging.debug("loader_2nd=%#x bytes", len(loader_2nd))
e = self.ldr_2nd_hdr["MAGIC"]
magic = loader_2nd[e.addr : e.end]
if magic != LOADER_2ND_MAGIC_ORIG:
raise ValueError("loader_2nd's magic should be %r, but %r" % (LOADER_2ND_MAGIC_ORIG, magic))
self.compress_algo = args.compress
self.body2["LOADER_2ND"].content = loader_2nd
def pack_ddr_param(self, fip_bin):
if not len(self.body2["DDR_PARAM"].content):
return
fip_bin = self.pad(fip_bin, IMAGE_ALIGN)
# Pack DDR_PARAM to body2
ddr_param = self.pad(self.body2["DDR_PARAM"].content, IMAGE_ALIGN)
self.param2["DDR_PARAM_CKSUM"].content = self.image_crc(ddr_param)
self.param2["DDR_PARAM_SIZE"].content = len(ddr_param)
self.param2["DDR_PARAM_LOADADDR"].content = len(fip_bin)
return fip_bin + ddr_param
def pack_blcp_2nd(self, fip_bin, blcp_2nd_runaddr):
logging.debug("pack_blcp_2nd:")
if not len(self.body2["BLCP_2ND"].content):
return
runaddr = int(blcp_2nd_runaddr)
fip_bin = self.pad(fip_bin, IMAGE_ALIGN)
# Pack MONITOR to body2
body = self.pad(self.body2["BLCP_2ND"].content, IMAGE_ALIGN)
self.param2["BLCP_2ND_CKSUM"].content = self.image_crc(body)
self.param2["BLCP_2ND_SIZE"].content = len(body)
self.param2["BLCP_2ND_LOADADDR"].content = len(fip_bin)
self.param2["BLCP_2ND_RUNADDR"].content = runaddr
return fip_bin + body
def pack_monitor(self, fip_bin, monitor_runaddr):
logging.debug("pack_monitor:")
if not len(self.body2["MONITOR"].content):
return
monitor_runaddr = int(monitor_runaddr)
fip_bin = self.pad(fip_bin, IMAGE_ALIGN)
# Pack MONITOR to body2
monitor = self.pad(self.body2["MONITOR"].content, IMAGE_ALIGN)
self.param2["MONITOR_CKSUM"].content = self.image_crc(monitor)
self.param2["MONITOR_SIZE"].content = len(monitor)
self.param2["MONITOR_LOADADDR"].content = len(fip_bin)
self.param2["MONITOR_RUNADDR"].content = monitor_runaddr
return fip_bin + monitor
def _parse_ldr_2nd_hdr(self, image):
for e in self.ldr_2nd_hdr.values():
e.content = image[e.addr : e.end]
def _update_ldr_2nd_hdr(self):
image = self.body2["LOADER_2ND"].content
hdr_size = self._param_size(self.ldr_2nd_hdr)
hdr, body = image[:hdr_size], image[hdr_size:]
# Update SIZE
self.ldr_2nd_hdr["SIZE"].content = len(image)
# Update CKSUM
hdr = bytearray(b"".join((e.content for e in self.ldr_2nd_hdr.values())))
# CKSUM is calculated after "CKSUM" field
hdr_cksum = self.ldr_2nd_hdr["CKSUM"]
crc = self.image_crc((hdr + body)[hdr_cksum.end :])
hdr_cksum.content = crc
hdr = bytearray(b"".join((e.content for e in self.ldr_2nd_hdr.values())))
self.body2["LOADER_2ND"].content = hdr + body
def _compress_ldr_2nd(self):
image = self.body2["LOADER_2ND"].content
hdr_size = self._param_size(self.ldr_2nd_hdr)
hdr, body = image[:hdr_size], image[hdr_size:]
magic = self.ldr_2nd_hdr["MAGIC"].content
if magic == LOADER_2ND_MAGIC_ORIG:
# if image is uncompressed, compress it.
if self.compress_algo is None:
pass
elif self.compress_algo == "lzma":
self.ldr_2nd_hdr["MAGIC"].content = LOADER_2ND_MAGIC_LZMA
body = lzma_compress(body)
logging.info("lzma loader_2nd=%#x bytes wo header", len(body))
elif self.compress_algo == "lz4":
self.ldr_2nd_hdr["MAGIC"].content = LOADER_2ND_MAGIC_LZ4
body = lz4_compress(body)
logging.info("lz4 loader_2nd=%#x bytes wo header", len(body))
else:
raise NotImplementedError("'%r' is not supported." % self.compress_algo)
elif magic in LOADER_2ND_MAGIC_LIST:
logging.info("loader_2nd is already compressed")
else:
raise ValueError("unknown loader_2nd magic (%r)", magic)
self.body2["LOADER_2ND"].content = self.pad(hdr + body, IMAGE_ALIGN)
def pack_loader_2nd(self, fip_bin):
logging.debug("pack_loader_2nd:")
if not len(self.body2["LOADER_2ND"].content):
return
fip_bin = self.pad(fip_bin, IMAGE_ALIGN)
self.param2["LOADER_2ND_LOADADDR"].content = len(fip_bin)
self._parse_ldr_2nd_hdr(self.body2["LOADER_2ND"].content)
self._compress_ldr_2nd()
self._update_ldr_2nd_hdr()
# Append LOADER_2ND to body2
return fip_bin + self.body2["LOADER_2ND"].content
def insert_param1(self, fip_bin, name, value):
fip_bin = bytearray(fip_bin)
e = self.param1[name]
e.content = value
fip_bin[e.addr : e.end] = value
return self.update_param1_cksum(fip_bin)
def append_fip2(self, fip1_bin, args):
logging.debug("make_fip2:")
fip_bin = bytearray(fip1_bin)
# Update PARAM2_LOADADDR
param2_loadaddr = len(fip1_bin)
fip_bin = self.insert_param1(fip_bin, "PARAM2_LOADADDR", pack("<I", param2_loadaddr))
# Add an empty PARAM2
fip_bin += b"\0" * PARAM2_SIZE
# Pack body
fip_bin = self.pack_ddr_param(fip_bin)
if len(self.body2["BLCP_2ND"].content):
runaddr = self.param2["BLCP_2ND_RUNADDR"].toint()
if not runaddr:
runaddr = int(args.BLCP_2ND_RUNADDR)
fip_bin = self.pack_blcp_2nd(fip_bin, runaddr)
if len(self.body2["MONITOR"].content):
runaddr = self.param2["MONITOR_RUNADDR"].toint()
if not runaddr:
runaddr = int(args.MONITOR_RUNADDR)
fip_bin = self.pack_monitor(fip_bin, runaddr)
if len(self.body2["LOADER_2ND"].content):
fip_bin = self.pack_loader_2nd(fip_bin)
# Pack param2_bin
param2_bin = b"".join((entry.content for entry in self.param2.values()))
self.param2["PARAM2_CKSUM"].content = self.image_crc(param2_bin[self.param2["PARAM2_CKSUM"].end :])
param2_bin = b"".join((entry.content for entry in self.param2.values())) # update cksum
logging.debug("len(param2_bin) is %d", len(param2_bin))
assert len(param2_bin) == PARAM2_SIZE
fip_bin[param2_loadaddr : param2_loadaddr + PARAM2_SIZE] = param2_bin
return fip_bin
def make(self, args=None):
fip_bin = self.make_fip1()
if len(self.body2["DDR_PARAM"].content):
fip_bin = self.append_fip2(fip_bin, args)
logging.info("generated fip_bin is %d bytes", len(fip_bin))
if getattr(self, "rest_fip", None):
logging.error("the rest of fip is not used: %#x bytes ", len(self.rest_fip))
return fip_bin
METHODS = {
"NOR_INFO": FIP.add_nor_info,
"NAND_INFO": FIP.add_nand_info,
"CHIP_CONF": FIP.add_chip_conf,
"BLCP": FIP.add_blcp,
"BL2": FIP.add_bl2,
"DDR_PARAM": FIP.add_ddr_param,
"BLCP_2ND": FIP.add_blcp_2nd,
"MONITOR": FIP.add_monitor,
"LOADER_2ND": FIP.add_loader_2nd,
}
def generate_fip(args):
logging.debug("generate_fip:")
fip = FIP()
if args.OLD_FIP:
fip.read_fip(args.OLD_FIP)
for m, f in METHODS.items():
if getattr(args, m):
f(fip, args)
fip_bin = fip.make(args)
fip.print_fip_params()
if args.output:
with open(args.output, "wb") as fp:
fp.write(fip_bin)
def parse_args():
parser = argparse.ArgumentParser(description="FIP tools")
parser.add_argument(
"-v",
"--verbose",
help="Increase output verbosity",
action="store_const",
const=logging.DEBUG,
default=logging.INFO,
)
subparsers = parser.add_subparsers(dest="subcmd", help="Sub-command help")
pr_gen = subparsers.add_parser("genfip", help="Generate keys")
for name in list(METHODS):
if name in ["NOR_INFO", "NAND_INFO"]:
pr_gen.add_argument("--" + name, type=bytes.fromhex)
else:
pr_gen.add_argument("--" + name, dest=name, type=str, help="Add %s into FIP" % name)
def auto_int(x):
return int(x, 0)
pr_gen.add_argument("--BLCP_IMG_RUNADDR", type=auto_int)
pr_gen.add_argument("--BLCP_PARAM_LOADADDR", type=auto_int)
pr_gen.add_argument("--BLCP_2ND_RUNADDR", type=auto_int)
pr_gen.add_argument("--MONITOR_RUNADDR", type=auto_int)
pr_gen.add_argument("--compress", choices=["lzma", "lz4", ""])
pr_gen.add_argument("--OLD_FIP", type=str)
pr_gen.add_argument("--BLOCK_SIZE", type=auto_int)
pr_gen.add_argument("--BL2_FILL", type=auto_int)
pr_gen.add_argument("output", type=str, help="Output filename")
pr_gen.set_defaults(func=generate_fip)
if argcomplete:
argcomplete.autocomplete(parser)
args = parser.parse_args()
init_logging(stdout_level=args.verbose)
logging.info("PROG: %s", parser.prog)
if not args.subcmd:
parser.print_help()
raise SystemExit(1)
for a, v in sorted(vars(args).items()):
logging.debug(" %s=%r", a, v)
return args
def main():
args = parse_args()
args.func(args)
def init_logging(log_file=None, file_level="DEBUG", stdout_level="WARNING"):
root_logger = logging.getLogger()
root_logger.setLevel(logging.NOTSET)
fmt = "%(asctime)s %(levelname)8s:%(name)s:%(message)s"
if log_file is not None:
file_handler = logging.FileHandler(log_file, encoding="utf-8")
file_handler.setFormatter(logging.Formatter(fmt))
file_handler.setLevel(file_level)
root_logger.addHandler(file_handler)
if coloredlogs:
os.environ["COLOREDLOGS_DATE_FORMAT"] = "%H:%M:%S"
field_styles = {
"asctime": {"color": "green"},
"hostname": {"color": "magenta"},
"levelname": {"color": "black", "bold": True},
"name": {"color": "blue"},
"programname": {"color": "cyan"},
}
level_styles = coloredlogs.DEFAULT_LEVEL_STYLES
level_styles["debug"]["color"] = "cyan"
coloredlogs.install(
level=stdout_level,
fmt=fmt,
field_styles=field_styles,
level_styles=level_styles,
milliseconds=True,
)
if __name__ == "__main__":
main()