[PATCH 02/21] tools: sysfw: Add script for generating configuration blobs

Neha Malcom Francis n-francis at ti.com
Tue Jan 24 11:04:32 CET 2023


Hi Simon,

On 24/01/23 00:12, Simon Glass wrote:
> Hi Neha,
> 
> On Mon, 23 Jan 2023 at 07:19, Neha Malcom Francis <n-francis at ti.com> wrote:
>>
>> Hi Simon,
>>
>> On 20/01/23 15:48, Neha Malcom Francis wrote:
>>> Certain devices in the K3 architecture such as AM64x require board
>>> configuration binaries packed along with their descriptions into a
>>> sysfw_data binary. The final binary is required to be packed into the
>>> final system firmware images.
>>>
>>> Signed-off-by: Neha Malcom Francis <n-francis at ti.com>
>>> ---
>>>    tools/k3_sysfw_boardcfg_blob_creator.py | 116 ++++++++++++++++++++++++
>>>    1 file changed, 116 insertions(+)
>>>    create mode 100755 tools/k3_sysfw_boardcfg_blob_creator.py
>>>
>>> diff --git a/tools/k3_sysfw_boardcfg_blob_creator.py b/tools/k3_sysfw_boardcfg_blob_creator.py
>>> new file mode 100755
>>> index 0000000000..da99808521
>>> --- /dev/null
>>> +++ b/tools/k3_sysfw_boardcfg_blob_creator.py
>>> @@ -0,0 +1,116 @@
>>> +# SPDX-License-Identifier: GPL-2.0+
>>> +# Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
>>> +#
>>> +# TI Script for Board Configuration Packaging
>>> +#
>>> +
>>> +import argparse
>>> +import logging
>>> +import os
>>> +import struct
>>> +import tempfile
>>> +from shutil import copyfileobj
>>> +from shutil import rmtree
>>> +
>>> +BOARDCFG = 0xB
>>> +BOARDCFG_SEC = 0xD
>>> +BOARDCFG_PM = 0xE
>>> +BOARDCFG_RM = 0xC
>>> +BOARDCFG_NUM_ELEMS = 4
>>> +
>>> +class BoardCfgDesc():
>>> +    """Get board config descriptor for a given file """
>>> +
>>> +    fmt = '<HHHBB'
>>> +    index = 0
>>> +    offset = 0
>>> +
>>> +    def __init__(self, outfile, devgrp,
>>> +                    sw_rev = 0,
>>> +                    num_elems = BOARDCFG_NUM_ELEMS):
>>> +        self.devgrp = devgrp
>>> +        try:
>>> +            self.fh = open(outfile, 'wb')
>>> +            bytes = self.fh.write(struct.pack('<BB', num_elems, sw_rev))
>>> +            self.offset += bytes
>>> +            self.offset += num_elems * struct.calcsize(self.fmt)
>>> +            self.tmpdir = tempfile.mkdtemp()
>>> +            descfile = os.path.join(self.tmpdir, "desc")
>>> +            bcfgfile = os.path.join(self.tmpdir, "bcfg")
>>> +            self.desc_fh = open(descfile, "wb+")
>>> +            self.bcfg_fh = open(bcfgfile, "wb+")
>>> +        except:
>>> +            raise Exception("File Error")
>>> +
>>> +    def add_boardcfg(self, bcfgtype, bcfgfile):
>>> +        with open(bcfgfile, 'rb') as bfh:
>>> +            bcfg = bfh.read()
>>> +            size = len(bcfg)
>>> +            desc = struct.pack(self.fmt, bcfgtype, self.offset, size, self.devgrp, 0)
>>> +            self.desc_fh.write(desc)
>>> +            self.bcfg_fh.write(bcfg)
>>> +            logging.debug("Packing boardcfg data of size [%d bytes] from file %s", size, bcfgfile)
>>> +            self.offset += size
>>> +            self.index += 1
>>> +
>>> +    def finalize(self):
>>> +        try:
>>> +            self.desc_fh.seek(0)
>>> +            self.bcfg_fh.seek(0)
>>> +            copyfileobj(self.desc_fh, self.fh)
>>> +            copyfileobj(self.bcfg_fh, self.fh)
>>> +        except:
>>> +            logging.error("**** Error in finalizing boardcfg file ****")
>>> +            raise Exception("File Error")
>>> +        finally:
>>> +            self.fh.close()
>>> +            self.desc_fh.close()
>>> +            self.bcfg_fh.close()
>>> +            rmtree(self.tmpdir)
>>> +
>>> +def create_sysfw_blob(args):
>>> +    """Create a SYSFW data blob to be used as a component in combined image """
>>> +
>>> +    logging.info("#### Creating SYSFW data blob - %s ####", args.output_file.name)
>>> +    logging.info("#### SW Rev = %d", args.sw_rev)
>>> +    logging.info("#### Device Group = %d", args.devgrp)
>>> +
>>> +    cnt = 0
>>> +    if args.boardcfg is not None: cnt = cnt + 1
>>> +    if args.boardcfg_sec is not None: cnt = cnt + 1
>>> +    if args.boardcfg_pm is not None: cnt = cnt + 1
>>> +    if args.boardcfg_rm is not None: cnt = cnt + 1
>>> +
>>> +    blob = BoardCfgDesc(args.output_file.name, args.devgrp, args.sw_rev, cnt)
>>> +    if args.boardcfg is not None:
>>> +        logging.info("#### Board config binary - %s", args.boardcfg.name)
>>> +        blob.add_boardcfg(BOARDCFG, args.boardcfg.name)
>>> +    if args.boardcfg_sec is not None:
>>> +        logging.info("#### Board config security binary - %s", args.boardcfg_sec.name)
>>> +        blob.add_boardcfg(BOARDCFG_SEC, args.boardcfg_sec.name)
>>> +    if args.boardcfg_pm is not None:
>>> +        logging.info("#### Board config PM binary - %s", args.boardcfg_pm.name)
>>> +        blob.add_boardcfg(BOARDCFG_PM, args.boardcfg_pm.name)
>>> +    if args.boardcfg_rm is not None:
>>> +        logging.info("#### Board config RM binary - %s", args.boardcfg_rm.name)
>>> +        blob.add_boardcfg(BOARDCFG_RM, args.boardcfg_rm.name)
>>> +
>>> +    blob.finalize()
>>> +
>>> +# options -> device, sw_rev, boardcfg, security boardcfg, pm boardcfg, rm boardcfg, output file
>>> +
>>> +# parser for mandatory arguments
>>> +pp = argparse.ArgumentParser(add_help=False)
>>> +pp.add_argument('-l', '--log-level', type=str, default="INFO", choices=["INFO", "DEBUG"])
>>> +pp.add_argument('--sw-rev', type=int, default=1)
>>> +pp.add_argument('-o', '--output-file', type=argparse.FileType('wb'), default="./sysfw-data.bin")
>>> +pp.add_argument('-d', '--devgrp', type=int, default=0)
>>> +pp.add_argument('-b', '--boardcfg', type=argparse.FileType('rb'))
>>> +pp.add_argument('-s', '--boardcfg-sec', type=argparse.FileType('rb'))
>>> +pp.add_argument('-p', '--boardcfg-pm', type=argparse.FileType('rb'))
>>> +pp.add_argument('-r', '--boardcfg-rm', type=argparse.FileType('rb'))
>>> +
>>> +args = pp.parse_args()
>>> +logging.getLogger().setLevel(args.log_level)
>>> +logging.debug(args)
>>> +create_sysfw_blob(args)
>>
>> Working on your reviews, I'm trying to get rid of all external scripts
>> and putting them into btools/etypes which seems fit.
>>          * ti_secure_path can be nicely put into a btool
>>          * ti_boardcfg can also be an etype that outputs <type>-cfg.bins
>>
>> But... I am not sure about this script above
>> k3_sysfw_boardcfg_blob_creator.py. This script essentially does a more
>> detailed packing of the <type>-cfg.bins that have been generated by
>> binman. Since binman doesn't account for dependencies as of now; I am
>> not sure how to go about it. Any pointers?
>>
>> I could have something like
>>
>> combined-sysfw-cfg.bin {
>>          sysfw-boardcfg {
>>                  ti-boardcfg {
>>                          config = "board-cfg.yaml";
>>                          schema = "schema.yaml";
>>                  }
>>                  ti-boardcfg {
>>                          config = "sec-cfg.yaml";
>>                          ...
>>
>> But is there any way to not have to implement this entry within entry
>> coupled with packaging, which I think might get a little messy?
> 
> Yes you can have entries within entries and it should work fine. See
> [1] for an example of that. It is a correct description of how the
> image is put together, so I don't really see a better way.
> 
> BTW perhaps 'config' and 'schema' are a bit too generic, but we can
> worry about that later. There is no schema validation for binman at
> present but I suspect I'll be looking at later in the year.
> 
> Regarding accounting for dependencies, it is possible to put a
> 'filename' property in a section such that binman outputs the contents
> of the section to a separate file.
> 
> Regards,
> SImon
> 
> [1] https://patchwork.ozlabs.org/project/uboot/patch/20220110031413.1970836-39-sjg@chromium.org/

Thanks for the help! The referenced patch shows a good guideline of how 
to enable this. I am currently trying to implement this, will reach out 
in case any confusion arises.

-- 
Thanking You
Neha Malcom Francis


More information about the U-Boot mailing list