[PATCH v8 06/13] binman: Support new op-tee binary format

Simon Glass sjg at chromium.org
Sat Jan 7 19:55:54 CET 2023


Hi Quentin,

On Mon, 2 Jan 2023 at 10:54, Quentin Schulz
<quentin.schulz at theobroma-systems.com> wrote:
>
> Hi Simon,
>
> On 12/22/22 00:07, Simon Glass wrote:
> > OP-TEE has a format with a binary header that can be used instead of the
> > ELF file. With newer versions of OP-TEE this may be required on some
> > platforms.
> >
> > Add support for this in binman. First, add a method to obtain the ELF
> > sections from an entry, then use that in the FIT support. We then end up
> > with the ability to support both types of OP-TEE files, depending on which
> > one is passed in with the entry argument (TEE=xxx in the U-Boot build).
> >
> > Signed-off-by: Simon Glass <sjg at chromium.org>
> > ---
> >
> > (no changes since v7)
> >
> > Changes in v7:
> > - Correct missing test coverage
> >
> > Changes in v6:
> > - Update op-tee to support new v1 binary header
> >
> >   tools/binman/entries.rst                     | 35 ++++++++-
> >   tools/binman/entry.py                        | 13 +++
> >   tools/binman/etype/fit.py                    | 69 +++++++++-------
> >   tools/binman/etype/section.py                |  9 +++
> >   tools/binman/etype/tee_os.py                 | 68 +++++++++++++++-
> >   tools/binman/ftest.py                        | 83 ++++++++++++++++++++
> >   tools/binman/test/263_tee_os_opt.dts         | 22 ++++++
> >   tools/binman/test/264_tee_os_opt_fit.dts     | 33 ++++++++
> >   tools/binman/test/265_tee_os_opt_fit_bad.dts | 40 ++++++++++
> >   9 files changed, 340 insertions(+), 32 deletions(-)
> >   create mode 100644 tools/binman/test/263_tee_os_opt.dts
> >   create mode 100644 tools/binman/test/264_tee_os_opt_fit.dts
> >   create mode 100644 tools/binman/test/265_tee_os_opt_fit_bad.dts
> >
> > diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
> > index b2ce7960d3b..a3e4493a44f 100644
> > --- a/tools/binman/entries.rst
> > +++ b/tools/binman/entries.rst
> > @@ -1508,12 +1508,45 @@ Entry: tee-os: Entry containing an OP-TEE Trusted OS (TEE) blob
> >
> >   Properties / Entry arguments:
> >       - tee-os-path: Filename of file to read into entry. This is typically
> > -        called tee-pager.bin
> > +        called tee.bin or tee.elf
> >
> >   This entry holds the run-time firmware, typically started by U-Boot SPL.
> >   See the U-Boot README for your architecture or board for how to use it. See
> >   https://urldefense.com/v3/__https://github.com/OP-TEE/optee_os__;!!OOPJP91ZZw!kx6SLv4sPusmg1TyYMw-Ho5G9jxeVMf9HOYx_4yq3ZNl_TpoGJoUyICZMgEiv0Zd6l_Bl8f5OAFYyJxm8wDUevhARIs$  for more information about OP-TEE.
> >
> > +Note that if the file is in ELF format, it must go in a FIT. In that case,
> > +this entry will mark itself as absent, providing the data only through the
> > +read_elf_segments() method.
> > +
> > +Marking this entry as absent means that it if is used in the wrong context
> > +it can be automatically dropped. Thus it is possible to add anb OP-TEE entry
>
> s/anb/an/
>
> > +like this::
> > +
> > +    binman {
> > +        tee-os {
> > +        };
> > +    };
> > +
> > +and pass either an ELF or plain binary in with -a tee-os-path <filename>
> > +and have binman do the right thing:
> > +
> > +   - include the entry if tee.bin is provided and it doesn't have the v1
> > +     header
> > +   - drop it otherwise
> > +
>
> Is there an actual usecase for this? (sorry if this was mentioned in the
> earlier versions of the patch) Are we expecting to be able to append the
> content of tee-os to some raw binary instead of putting OP-TEE OS in a
> u-boot.itb image?

Yes, that is my understanding. Perhaps it is for some archs or some
old versions. But in any case, we can always drop it later if not
needed, refine the warnings, etc. etc. But please let's land this mess
and move on. If I had pushed a little harder a year ago we would have
be talking about how to do this properly in binman rather than me
trying to retrofit everything.

[..]

>
> You can use a reference here since we have a _etype_fit target for "Flat
> Image Tree / FIT".
>
> > +the binary v1 format is provided.
> > +
> >
>
> I'm a bit worried this is OP-TEE OS specific? We could also point to the
> documentation here:
> https://optee.readthedocs.io/en/latest/architecture/core.html#partitioning-of-the-binary?

Yes it is...I believe there will be other use cases for absent
entries....in a way it is quite a big hold in binman's functionality.
Will link to the docs.

>
> >
> >   .. _etype_text:
> > diff --git a/tools/binman/entry.py b/tools/binman/entry.py
> > index 637aece3705..de51d295891 100644
> > --- a/tools/binman/entry.py
> > +++ b/tools/binman/entry.py
> > @@ -1290,3 +1290,16 @@ features to produce new behaviours.
> >       def mark_absent(self, msg):
> >           tout.info("Entry '%s' marked absent: %s" % (self._node.path, msg))
> >           self.absent = True
> > +
> > +    def read_elf_segments(self):
> > +        """Read segments from an entry that can generate an ELF file
> > +
> > +        Returns:
> > +            tuple:
> > +                list of segments, each:
> > +                    int: Segment number (0 = first)
> > +                    int: Start address of segment in memory
> > +                    bytes: Contents of segment
> > +                int: entry address of ELF file
> > +        """
> > +        return None
>
> Does it really make sense to have this function available to all Entry
> objects?

Yes we must define functions in the base class to avoid confusion.
Also it does actually get called from the FIT implementation, to see
if this function can provide the segments...failing that it tries to
parse an ELF blob.

[..]

> > +    @staticmethod
> > +    def is_optee_bin(data):
>
> Here you are checking it's a binary with v1 header, so please explicit
> in the function name. (there's already a v2 header available FWIW).

OMG

>
> > +        return len(data) >= 8 and data[0:5] == b'OPTE\x01'
> > +
> > +    def ObtainContents(self, fake_size=0):
> > +        super().ObtainContents(fake_size)
>
> Do not silence the return code of the parent class here? I know it's
> only returning True ATM but nothing guarantees it'll stay this way.
>
> > +        if not self.missing:
> > +            if elf.is_valid(self.data):
> > +                self.mark_absent('uses Elf format which must be in a FIT')
> > +            elif self.is_optee_bin(self.data):
> > +                self.mark_absent('uses v1 format which must be in a FIT')
>
> What should this support then if neither ELF not binary with v1 header
> are supported? I don't see support for binary with v2 header anywhere so
> I'm quite confused by what this piece of code is supposed to handle?
>
> I'm also very much against displaying a warning if the user has TEE set
> in their environment and the file exists but it won't be used in the
> final image. If it's not compatible based on the binman DT node, error
> out. If it's the wrong file or it's missing, error out. Is there some
> scenario where displaying a warning (and/or removing the entry with
> mark_absent like you did here) make sense?

We need to deal with this later, sorry. I have come to the end of the
time I can bear to spend dealing with the strangeness of OP-TEE. If
you are able to tidy this up after it lands, or have ideas on how to
do better, please let me know.

>
> In any case, thanks Simon and Jerome for looking into this, it's a
> bigger task than I had anticipated but am looking forward to this
> Rockchip-specific behavior to be dropped from mainline :)

Thanks. This has been beyond painful. We have to stop all these
scripts and strange workflows...it is making firmware impossible to
understand.

Regards,
Simon


More information about the U-Boot mailing list