123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #!/usr/bin/env python3
- # Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
- # All rights reserved.
- #
- # This software is supplied "AS IS" without any warranties.
- # RDA assumes no responsibility or liability for the use of the software,
- # conveys no license or title under any patent, copyright, or mask work
- # right to the product. RDA reserves the right to make changes in the
- # software without notification. RDA also make no representation or
- # warranty that such application will be suitable for the specified use
- # without further testing or modification.
- import argparse
- import sys
- import os
- import struct
- import json
- import binascii
- DESCRIPTION = """
- Generate binary partition information file from json.
- Configuration json format:
- * version: it should be 0x100 now
- * descriptions (array)
- * flash block device
- * type: FBD1 or FBD2
- * flash: SFL1 or SFL2 (for external flash)
- * name: device name, will be referred later
- * offset: flash offset
- * size: block device size in byte
- * erase_block: erase block size
- * logic_block: logic block size
- * bootloader_ignore: (optional) flag for ignore by bootloader
- * application_ignore: (optional) flag for ignore by application
- * bootloader_format_on_fail: (optional) flag for format on fail in bootloader
- * application_format_on_fail: (optional) flag for format on fail in application
- * SFFS file system
- * type: SFFS
- * device: block device or partition name
- * mount: mount point
- * reserve_block: (optional) safe file reserved block count
- * bootloader_ignore: (optional) flag for ignore by bootloader
- * application_ignore: (optional) flag for ignore by application
- * bootloader_ro: (optional) flag for read only by bootloader
- * application_ro: (optional) flag for read only by application
- * bootloader_format_on_fail: (optional) flag for format on fail in bootloader
- * application_format_on_fail: (optional) flag for format on fail in application
- * macros: it will only be used to generate partinfo.cmake for definitions
- all keys start with "CONFIG_" will be written to cmake.
- """
- MAGIC = b'PRTI'
- VERSION = 0x100
- HEADER_SIZE = 16
- BOOTLOADER_RO = 0x01
- APPLICATION_RO = 0x02
- BOOTLOADER_IGNORE = 0x04
- APPLICATION_IGNORE = 0x08
- BOOTLOADER_FORMAT_ON_FAIL = 0x10
- APPLICATION_FORMAT_ON_FAIL = 0x20
- class Partinfo(object):
- def __init__(self):
- self._des = []
- pass
- def loadjson(self, fname):
- fh = open(fname, "r")
- self._des = json.load(fh)
- fh.close()
- def storebin(self, fname):
- data = bytearray()
- for p in self._des['descriptions']:
- dtype = p['type']
- if dtype == 'FBD1' or dtype == 'FBD2':
- flags = 0
- if p.get('bootloader_ignore', False):
- flags |= BOOTLOADER_IGNORE
- if p.get('application_ignore', False):
- flags |= APPLICATION_IGNORE
- if p.get('bootloader_format_on_fail', False):
- flags |= BOOTLOADER_FORMAT_ON_FAIL
- if p.get('application_format_on_fail', False):
- flags |= APPLICATION_FORMAT_ON_FAIL
- pdata = struct.pack(
- '4s4s4siiiii',
- bytes(dtype, 'utf-8'),
- bytes(p['flash'], 'utf-8'),
- bytes(p['name'], 'utf-8'),
- int(p['offset'], 0),
- int(p['size'], 0),
- int(p['erase_block'], 0),
- int(p['logic_block'], 0),
- flags)
- data += pdata
- elif dtype == 'BPRT':
- flags = 0
- if p.get('bootloader_ignore', False):
- flags |= BOOTLOADER_IGNORE
- if p.get('application_ignore', False):
- flags |= APPLICATION_IGNORE
- pdata = struct.pack(
- '4s4s4siii',
- bytes(dtype, 'utf-8'),
- bytes(p['device'], 'utf-8'),
- bytes(p['name'], 'utf-8'),
- int(p['offset'], 0),
- int(p['count'], 0),
- flags)
- data += pdata
- elif dtype == 'SFFS':
- flags = 0
- if p.get('bootloader_ro', False):
- flags |= BOOTLOADER_RO
- if p.get('application_ro', False):
- flags |= APPLICATION_RO
- if p.get('bootloader_ignore', False):
- flags |= BOOTLOADER_IGNORE
- if p.get('application_ignore', False):
- flags |= APPLICATION_IGNORE
- if p.get('bootloader_format_on_fail', False):
- flags |= BOOTLOADER_FORMAT_ON_FAIL
- if p.get('application_format_on_fail', False):
- flags |= APPLICATION_FORMAT_ON_FAIL
- reserve_block = 0
- if 'reserve_block' in p:
- reserve_block = int(p['reserve_block'], 0)
- pdata = struct.pack(
- '4s4s64sii',
- bytes(dtype, 'utf-8'),
- bytes(p['device'], 'utf-8'),
- bytes(p['mount'], 'utf-8'),
- reserve_block,
- flags)
- data += pdata
- size = HEADER_SIZE + len(data)
- version = struct.pack('ii', size, VERSION)
- crc = binascii.crc32(version + data)
- header = struct.pack('4sIii', MAGIC, crc, size, VERSION)
- if not os.path.exists(os.path.dirname(fname)):
- os.makedirs(os.path.dirname(fname))
- fh = open(fname, 'wb')
- fh.write(header)
- fh.write(data)
- fh.close()
- def storecmake(self, fname, json_fname):
- if not os.path.exists(os.path.dirname(fname)):
- os.makedirs(os.path.dirname(fname))
- fh = open(fname, "w")
- fh.write("# Auto Generated\n")
- kv = self._des.get("macros", {})
- for k, v in kv.items():
- if k.startswith("CONFIG_"):
- fh.write("set(%s %s)\n" % (k, v))
- fh.close()
- def main():
- parser = argparse.ArgumentParser(description=DESCRIPTION,
- formatter_class=argparse.RawTextHelpFormatter)
- parser.add_argument("json", help="partinfo.json for partition information")
- parser.add_argument("bin", help="partinfo.bin for partition information")
- parser.add_argument("cmake", help="partinfo.cmake for definitions")
- args = parser.parse_args()
- parti = Partinfo()
- parti.loadjson(args.json)
- parti.storebin(args.bin)
- parti.storecmake(args.cmake, args.json)
- if __name__ == "__main__":
- main()
|