
Hi Quentin,
On Mon, 2 Jan 2023 at 10:54, Quentin Schulz quentin.schulz@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@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__;!!OOPJP91ZZ... 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-o...
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