All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alper Nebi Yasak <alpernebiyasak@gmail.com>
To: Simon Glass <sjg@chromium.org>
Cc: Ivan Mikhaylov <ivan.mikhaylov@siemens.com>,
	Tom Rini <trini@konsulko.com>,
	Philippe Reynes <philippe.reynes@softathome.com>,
	huang lin <hl@rock-chips.com>,
	Jeffy Chen <jeffy.chen@rock-chips.com>,
	Kever Yang <kever.yang@rock-chips.com>,
	U-Boot Mailing List <u-boot@lists.denx.de>
Subject: Re: [PATCH v2 20/25] binman: Support splitting an ELF file into multiple nodes
Date: Fri, 4 Mar 2022 00:10:45 +0300	[thread overview]
Message-ID: <aea4bf25-ed0b-609c-1bf1-0f6162aebfe0@gmail.com> (raw)
In-Reply-To: <20220223230040.159317-21-sjg@chromium.org>

On 24/02/2022 02:00, Simon Glass wrote:
> Some boards need to load an ELF file using the 'loadables' property, but
> the file has segments at different memory addresses. This means that it
> cannot be supplied as a flat binary.
> 
> Allow generating a separate node in the FIT for each segment in the ELF,
> with a different load address for each.
> 
> Also add checks that the fit,xxx directives are valid.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> Changes in v2:
> - Rewrite this to use the new FIT entry-type implementation
> - Rename op-tee to tee-os
> 
>  tools/binman/entries.rst                     | 146 ++++++++++++
>  tools/binman/etype/fit.py                    | 230 ++++++++++++++++++-
>  tools/binman/ftest.py                        | 147 ++++++++++++
>  tools/binman/test/226_fit_split_elf.dts      |  67 ++++++
>  tools/binman/test/227_fit_bad_dir.dts        |   9 +
>  tools/binman/test/228_fit_bad_dir_config.dts |   9 +
>  6 files changed, 598 insertions(+), 10 deletions(-)
>  create mode 100644 tools/binman/test/226_fit_split_elf.dts
>  create mode 100644 tools/binman/test/227_fit_bad_dir.dts
>  create mode 100644 tools/binman/test/228_fit_bad_dir_config.dts
> 
> [...]
> 
> diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
> index 30b20a07a2..63d552ed19 100644> > [...]
> 
> @@ -154,6 +159,149 @@ class Entry_fit(Entry_section):
>  
>      Note that if no devicetree files are provided (with '-a of-list' as above)
>      then no nodes will be generated.
> +
> +    Generating nodes from an ELF file (split-elf)
> +    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +    This uses the node as a template to generate multiple nodes. The following
> +    special properties are available:
> +
> +    split-elf
> +        Split an ELF file into a separate node for each segment. This uses the
> +        node as a template to generate multiple nodes. The following special
> +        properties are available:
> +
> +        fit,load
> +            Generates a `load = <...>` property with the load address of the
> +            segmnet

segmnet -> segment, missed it the first time around.

> +
> +        fit,entry
> +            Generates a `entry = <...>` property with the entry address of the
> +            ELF. This is only produced for the first entry
> +
> +        fit,data
> +            Generates a `data = <...>` property with the contents of the segment
> +
> +        fit,loadables
> +            Generates a `loadable = <...>` property with a list of the generated
> +            nodes (including all nodes if this operation is used multiple times)
> 
> [...]
>  
> @@ -363,11 +514,20 @@ class Entry_fit(Entry_section):
>                      fname = tools.get_input_filename(fdt_fname + '.dtb')
>                      with fsw.add_node(node_name):
>                          for pname, prop in node.props.items():
> -                            val = prop.bytes.replace(
> -                                b'NAME', tools.to_bytes(fdt_fname))
> -                            val = val.replace(
> -                                b'SEQ', tools.to_bytes(str(seq + 1)))
> -                            fsw.property(pname, val)
> +                            if pname == 'fit,loadables':
> +                                val = '\0'.join(self._loadables) + '\0'
> +                                fsw.property('loadables', val.encode('utf-8'))
> +                            elif pname == 'fit,operation':
> +                                pass
> +                            elif pname.startswith('fit,'):
> +                                self._raise(base_node, node,
> +                                            f"Unknown directive '{pname}'")
> +                            else:
> +                                val = prop.bytes.replace(
> +                                    b'NAME', tools.to_bytes(fdt_fname))
> +                                val = val.replace(
> +                                    b'SEQ', tools.to_bytes(str(seq + 1)))
> +                                fsw.property(pname, val)

I get two distinct "loadables" properties with this config fragment,
and fdtget and mkimage -l only considers the first one:

  @config-SEQ {
     description = "NAME.dtb";
     fdt = "fdt-SEQ";
     firmware = "atf-1";
     loadables = "u-boot";
     fit,loadables;
  };

  $ fdtget simple-bin.fit.fit /configurations/config-1 -p
  description
  fdt
  firmware
  loadables
  loadables

  $ fdtget simple-bin.fit.fit /configurations/config-1 loadables
  u-boot

  $ mkimage -l simple-bin.fit.fit
  FIT description: FIT image for U-Boot with bl31 (TF-A)
  Created:         Thu Feb 24 17:36:36 2022
   Image 0 (u-boot)
    Description:  U-Boot (64-bit)
    Created:      Thu Feb 24 17:36:36 2022
    Type:         Standalone Program
    Compression:  uncompressed
    Data Size:    727192 Bytes = 710.15 KiB = 0.69 MiB
    Architecture: AArch64
    Load Address: 0x00200000
    Entry Point:  unavailable
   Image 1 (atf-1)
    Description:  ARM Trusted Firmware
    Created:      Thu Feb 24 17:36:36 2022
    Type:         Firmware
    Compression:  uncompressed
    Data Size:    139342 Bytes = 136.08 KiB = 0.13 MiB
    Architecture: AArch64
    OS:           ARM Trusted Firmware
    Load Address: 0x00040000
   Image 2 (atf-2)
    Description:  ARM Trusted Firmware
    Created:      Thu Feb 24 17:36:36 2022
    Type:         Firmware
    Compression:  uncompressed
    Data Size:    8024 Bytes = 7.84 KiB = 0.01 MiB
    Architecture: AArch64
    OS:           ARM Trusted Firmware
    Load Address: 0xff3b0000
   Image 3 (atf-3)
    Description:  ARM Trusted Firmware
    Created:      Thu Feb 24 17:36:36 2022
    Type:         Firmware
    Compression:  uncompressed
    Data Size:    8192 Bytes = 8.00 KiB = 0.01 MiB
    Architecture: AArch64
    OS:           ARM Trusted Firmware
    Load Address: 0xff8c0000
   Image 4 (fdt-1)
    Description:  fdt-rk3399-gru-bob
    Created:      Thu Feb 24 17:36:36 2022
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Size:    69392 Bytes = 67.77 KiB = 0.07 MiB
    Architecture: Unknown Architecture
   Default Configuration: 'config-1'
   Configuration 0 (config-1)
    Description:  rk3399-gru-bob.dtb
    Kernel:       unavailable
    Firmware:     atf-1
    FDT:          fdt-1
    Loadables:    u-boot

I didn't test if my chromebook_kevin boots in this double-loadables
configuration, though.

>  
>                          # Add data for 'images' nodes (but not 'config')
>                          if depth == 1 and in_images:
> @@ -380,7 +540,43 @@ class Entry_fit(Entry_section):
>                      else:
>                          self.Raise("Generator node requires 'fit,fdt-list' property")
>  
> -        def _gen_node(base_node, node, depth, in_images):
> +        def _gen_split_elf(base_node, node, elf_data, missing):
> +            """Add nodes for the ELF file, one per group of contiguous segments
> +
> +            Args:
> +                node (Node): Template node from the binman definition

node -> base_node

> +                node (Node): Node to replace (in the FIT being built)
> +                data (bytes): ELF-format data to process (may be empty)
> +                missing (bool): True if any of the data is missing
> +
> +            """
> +            # If any pieces are missing, skip this. The missing entries will
> +            # show an error
> +            if not missing:
> +                try:
> +                    segments, entry = elf.read_loadable_segments(elf_data)
> +                except ValueError as exc:
> +                    self._raise(base_node, node,
> +                                f'Failed to read ELF file: {str(exc)}')
> +                for (seq, start, data) in segments:
> +                    node_name = node.name[1:].replace('SEQ', str(seq + 1))
> +                    with fsw.add_node(node_name):
> +                        loadables.append(node_name)
> +                        for pname, prop in node.props.items():
> +                            if not pname.startswith('fit,'):
> +                                fsw.property(pname, prop.bytes)
> +                            elif pname == 'fit,load':
> +                                fsw.property_u32('load', start)
> +                            elif pname == 'fit,entry':
> +                                if not seq:

I'd prefer seq == 0 as it's a number.

> +                                    fsw.property_u32('entry', entry)
> +                            elif pname == 'fit,data':
> +                                fsw.property('data', bytes(data))
> +                            elif pname != 'fit,operation':
> +                                self._raise(base_node, node,
> +                                            f"Unknown directive '{pname}'")
> +
> +        def _gen_node(base_node, node, depth, in_images, entry):
>              """Generate nodes from a template
>  
>              This creates one node for each member of self._fdts using the
> [...]

  reply	other threads:[~2022-03-03 21:19 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-23 23:00 [PATCH v2 00/25] binman: rockchip: Migrate from rockchip SPL_FIT_GENERATOR script Simon Glass
2022-02-23 23:00 ` [PATCH v2 01/25] dtoc: Make GetArgs() more flexible Simon Glass
2022-03-03 21:07   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 02/25] moveconfig: Remove remove_defconfig() Simon Glass
2022-03-03 21:07   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 03/25] moveconfig: Use re.fullmatch() to avoid extra check Simon Glass
2022-03-03 21:07   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 04/25] spl: Correct Kconfig help for TPL_BINMAN_SYMBOLS Simon Glass
2022-03-03 21:08   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 05/25] dtoc: Tidy up implementation of AddStringList() Simon Glass
2022-03-03 21:08   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 06/25] elf: Rename load_segments() and module failure Simon Glass
2022-03-03 21:08   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 07/25] binman: Tweak collect_contents_to_file() and docs Simon Glass
2022-03-03 21:08   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 08/25] binman: Rename ExpandToLimit to extend_to_limit Simon Glass
2022-03-03 21:08   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 09/25] binman: Rename ExpandEntries to gen_entries Simon Glass
2022-03-03 21:09   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 10/25] binman: Refactor fit to generate output at the end Simon Glass
2022-03-03 21:09   ` Alper Nebi Yasak
2022-03-06  3:08     ` Simon Glass
2022-02-23 23:00 ` [PATCH v2 11/25] binman: Rename tools parameter to btools Simon Glass
2022-03-03 21:09   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 12/25] binman: Change how faked blobs are created Simon Glass
2022-03-03 21:09   ` Alper Nebi Yasak
2022-03-06  3:08     ` Simon Glass
2022-03-10 19:29       ` Alper Nebi Yasak
2022-03-12  5:02         ` Simon Glass
2022-03-14 21:29           ` Alper Nebi Yasak
2022-03-14 22:20             ` Simon Glass
2022-02-23 23:00 ` [PATCH v2 13/25] binman: Make fake blobs zero-sized by default Simon Glass
2022-03-03 21:09   ` Alper Nebi Yasak
2022-03-06  3:08     ` Simon Glass
2022-02-23 23:00 ` [PATCH v2 14/25] binman: Allow mkimage to use a non-zero fake-blob size Simon Glass
2022-03-03 21:09   ` Alper Nebi Yasak
2022-03-06  3:08     ` Simon Glass
2022-03-10 19:30       ` Alper Nebi Yasak
2022-03-12  5:02         ` Simon Glass
2022-02-23 23:00 ` [PATCH v2 15/25] binman: Read the fit entries only once Simon Glass
2022-03-03 21:10   ` Alper Nebi Yasak
2022-03-06  3:08     ` Simon Glass
2022-02-23 23:00 ` [PATCH v2 16/25] binman: Fix some pylint warnings in fit Simon Glass
2022-03-03 21:10   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 17/25] binman: Add a consistent way to report errors with fit Simon Glass
2022-03-03 21:10   ` Alper Nebi Yasak
2022-03-06  3:08     ` Simon Glass
2022-02-23 23:00 ` [PATCH v2 18/25] binman: Update fit to use node instead of subnode Simon Glass
2022-03-03 21:10   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 19/25] binman: Keep a separate list of entries for fit Simon Glass
2022-03-03 21:10   ` Alper Nebi Yasak
2022-03-06  3:08     ` Simon Glass
2022-03-10 19:30       ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 20/25] binman: Support splitting an ELF file into multiple nodes Simon Glass
2022-03-03 21:10   ` Alper Nebi Yasak [this message]
2022-03-06  3:08     ` Simon Glass
2022-02-23 23:00 ` [PATCH v2 21/25] rockchip: evb-rk3288: Drop raw-image support Simon Glass
2022-02-23 23:00 ` [PATCH v2 22/25] rockchip: Include binman script in 64-bit boards Simon Glass
2022-03-03 21:10   ` Alper Nebi Yasak
2022-02-23 23:00 ` [PATCH v2 23/25] rockchip: Support building the all output files in binman Simon Glass
2022-03-02 22:16   ` Peter Geis
2022-03-03 21:11     ` Alper Nebi Yasak
2022-03-03 22:34       ` Peter Geis
2022-03-06  3:08         ` Simon Glass
2022-02-23 23:00 ` [PATCH v2 24/25] rockchip: Convert all boards to use binman Simon Glass
2022-02-23 23:00 ` [PATCH v2 25/25] rockchip: Drop the FIT generator script Simon Glass
2022-03-01  2:48 ` [RFC] [PATCH] binman: support mkimage split files Peter Geis
2022-03-03 21:11   ` Alper Nebi Yasak
2022-03-04 17:47     ` Peter Geis
2022-03-04 19:56       ` [PATCH v2] binman: support mkimage separate files Peter Geis
2022-03-06  3:08         ` Simon Glass
2022-03-06 14:44           ` Peter Geis
2022-03-10 19:29             ` Alper Nebi Yasak
2022-03-10 23:19               ` Peter Geis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aea4bf25-ed0b-609c-1bf1-0f6162aebfe0@gmail.com \
    --to=alpernebiyasak@gmail.com \
    --cc=hl@rock-chips.com \
    --cc=ivan.mikhaylov@siemens.com \
    --cc=jeffy.chen@rock-chips.com \
    --cc=kever.yang@rock-chips.com \
    --cc=philippe.reynes@softathome.com \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.