Mbed-os: Creating a non-TrustZone ARMv8 image

Created on 22 Jan 2019  路  30Comments  路  Source: ARMmbed/mbed-os

Description

This is prompted by https://github.com/ARMmbed/mbed-os/pull/9446

There seems to be no way to create a simple non-TrustZone ARMv8 image - the tooling is assuming a binary choice between

  • Cortex-M23: make a secure TrustZone library
  • Cortex-M23-NS: make a non-secure TrustZone image (which must link in a secure library, maybe generated by the above)

There needs to be a third choice - make a simple non-TrustZone image. (That image would work either on a chip without TrustZone extension, or work on a TrustZone-capable chip by running entirely in Secure state).

We could adjust the core suffix to be 3-way. For that, this naming would make sense:

  • Cortex-M33: make a non-TrustZone image
  • Cortex-M33-S: make a secure TrustZone library
  • Cortex-M33-NS: make a non-secure TrustZone image (which must link in a secure library, maybe generated by the above)

But it seems that the CPU options are starting to multiply out-of-hand there, what with the need to select DSP and FP too.

So, why is the secure choice part of the core name? It seems to me that it would be better handled like the SPE/NSPE choice for PSA - extra labels to indicate the "-S" and "-NS" variants, and the core is always just "Cortex-M33" (plus FP/DSP flags).

If you do that, the existing Python checks for "-NS" suffix or not convert like this:

    if target.is_TZ_secure_target:
        self.flags['cxx'].append("-mcmse")
        self.flags['c'].append("-mcmse")

    # Create Secure library
    if (target.is_TZ_secure_target and
        kwargs.get('build_dir', False)):
        build_dir = kwargs['build_dir']
        secure_file = join(build_dir, "cmse_lib.o")
        self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file]

    # Add linking time preprocessor macro DOMAIN_NS
    if target.is_TZ_nonsecure_target:
        define_string = self.make_ld_define("DOMAIN_NS", "0x1")
        self.flags["ld"].append(define_string)

Both conditions are false if it's a non-TrustZone image, making the build system act like ARMv7.

Issue request type

[ ] Question
[X] Enhancement
[ ] Bug
CLOSED mirrored

All 30 comments

So, why is the secure choice part of the core name? It seems to me that it would be better handled like the SPE/NSPE choice for PSA - extra labels to indicate the "-S" and "-NS" variants, and the core is always just "Cortex-M33" (plus FP/DSP flags).

In tools we did not have mechanism to build secure + non-secure binaries with single command or same core. Ideally it should be core selection - build SPE TF-M and NSPE mbed-os and merge binaries along with post build / pre-build operations.

S/NS variants were provided as a way to build secure / non-secure binaries separately with the help of .mbedignore

We don't need to build everything with a single command - I didn't think the SPE/NSPE does either. But it would be cute.

Having the secure+nonsecure halves remain built as separate targets that select different options seems fine to me - it just would be nice to make the option they specify separate from the core name, reducing the multiplications in the core-related stuff.

Using an extra label would still let you do "TARGET_TZ_NS" or "TARGET_TZ_S" for selection at the tree level. "DOMAIN_NS" as an option lets you do most of the logic you need in the Mbed OS code. The flags you'd have to play with would be:

  • Non-secure: TARGET_TZ_NS, DOMAIN_NS=1, TARGET_TFM=10
  • Secure: TARGET_TZ_S, DOMAIN_NS=0, TARGET_TFM=1
  • Non-TrustZone: DOMAIN_NS=0, TARGET_TFM=0

(If I'm understanding TARGET_TFM correctly?).

I am confused here for TARGET_TFM. Also we have COMPONENT_SPE / COMPONENT_NSPE coming in.
Should it be:

Non-secure: TARGET_NSPE, DOMAIN_NS=1, TARGET_TFM=0
Secure: TARGET_SPE, DOMAIN_NS=0, TARGET_TFM=1
Non-TrustZone: DOMAIN_NS=0, TARGET_TFM=0

I am yet to understand this https://github.com/ARMmbed/mbed-os/pull/9221, but I am not sure of COMPONENT_SPE / NSPE / PSA - and TFM as target... Should all that be Target as well (my brain says), but need to understand the reason to have them as component + target combination.
This will also play the role here, as we have more flags and combination

I just corrected (hopefully) what I put for TARGET_TFM, possibly while you were writing that.

Most code (drivers, OS) shouldn't care about the distinction, and DOMAIN_NS will be sufficient. But some code might need to tell the difference between "I'm the complete image" and "I'm the security library for the main image", so DOMAIN_NS isn't enough for them. Presumably the "TFM" flag covers that, but maybe you need something else.

The SPE/NSPE security distinction is higher level than the TrustZone thing - it might be implemented using TrustZone, but could actually be a completely different core. I'm not sure it's wise to borrow that option for the TrustZone S/NS split. It wouldn't work for the python tests I suggested above. I think we need a separate specific option. (Similarly you could be using TrustZone but without the PSA NSPE/SPE split).

+1 for Kevin's proposition:

  • Cortex-M33: make a non-TrustZone image
  • Cortex-M33-S: make a secure TrustZone library
  • Cortex-M33-NS: make a non-secure TrustZone image

Cortex-M33: make a non-TrustZone image
Cortex-M33-S: make a secure TrustZone library
Cortex-M33-NS: make a non-secure TrustZone image

This will impact all Armv8M targets in development or in Mbed OS. We need broad audience here to confirm. More information https://github.com/ARMmbed/mbed-os/pull/9446#issuecomment-457104220
@alzix @mikisch81 @jeromecoutant @cyliangtw @mmahadevan108

@deepikabhavnani Should @SenRamakri reach out to others?

@cmonr - Internal discussions on this are in progress

What about the internal discussions status ?
Thx

@kjbracey-arm @deepikabhavnani Any update?

Addition of multiple core names is not preferred, tools team (@bridadan) has proposed a solution, but implementation of that will be delayed (low priority for 5.12)

Addition of multiple core names is not preferred

OK, so we should have only 1 core: Cortex-M33
and then set secure features on another label or macro, or...

Hi

I think we need to conclude asap about the way of working in order to get the 3 expected compilations:

  • Cortex-M33: make a non-TrustZone image
  • Cortex-M33-S: make a secure TrustZone library
  • Cortex-M33-NS: make a non-secure TrustZone image

@ARMmbed/mbed-os-psa @LMESTM

Thx

@SenRamakri @bulislaw @donatieng ^^^

@deepikabhavnani @kjbracey-arm I'm favouring the one core + flags option, but I'm not privy to the internal discussion. Can you summarise it?

@bulislaw - @bridadan Proposed one core + flag option and did some analysis around that, but task was not picked based on priorities. @bridadan can provide more details, will have to wait for him to be back from vacation.

Bump

Thx

+1 on using the flags option - @bridadan I would be keen to hear the rationale

Hey everyone, I've been looking at this in my own time, so the idea is still in the early stages. Pretty much the idea is to separate the core names and the core extensions. We currently have a list of strings covering the core name and extension combinations: https://github.com/ARMmbed/mbed-os/blob/master/tools/targets/__init__.py#L39-L56

This is troublesome for many reasons:

  • When we're generating all the compiler flags, we have to parse these strings (generally not great)
  • Anytime a new configuration/core is added, we need to exhaustively come up with a unique name.
  • If you want to disable the use of an extension (TrustZone being the one mentioned in this issue), you have to find the correct string name in the core list.

    • If that combination doesn't exist, we need to add all of them!

    • For non-trustzone configuration, we would have to double all M23 and M33 entries (8 more core names).

The idea is to replace the need for this custom string concatenation and move to a flags-based approach:

targets.json

{
    "MY_M33_TZ_TARGET": {
        "core": {
            "name": "Coretex-M33",
            "tz": true,
            "fpu": "single_precision"
        }
    }
}

This would represent a Cortex-M33 target with an FPU and TrustZone enabled. If you wanted to disable the TrustZone extensions (because the silicon doesn't have the extensions at all) you could set the tz attribute to false in targets.json to disable it for all builds . If the silicon has the extensions but you don't want to use them, you can disable them in your mbed_app.json like so:

mbed_app.json

{
    "target_overrides": {
         "MY_M33_TZ_TARGET": {
             "target.core.tz": false
         }
    }
}

Now, a few gotchas here:

  • We currently can't set config to JSON objects like I did above in targets.json. Target data is treated a little differently then normal library config, so we may be able to get away with this one. We could alternatively flatten the dictionary as well ("core": "Cortex-M33", "core_tz": true, "core_fpu": "single_precision"). Not my favorite in-terms of organization but it'd be manageable.
  • If we went with specifying the JSON object in the targets.json, the syntax I used in mbed_app.json (target.core.tz - nested accessors (.)) also won't work as of now. It would require some updates to the config system.

Here's my working branch, feel free to poke around there and give feedback: https://github.com/bridadan/mbed-os/tree/core_refactor

@bridadan is your working branch ready to be tested ?

Hi @jeromecoutant, no it is not a complete solution yet. I posted it here to get general thoughts and opinions on the direction.

About

{
    "MY_M33_TZ_TARGET": {
        "core": {
            "name": "Coretex-M33",
            "tz": true,
            "fpu": "single_precision"
        }
    }
}

Domain is missing ?

{
    "MY_M33_TZ_TARGET": {
        "core": {
            "name": "Coretex-M33",
            "tz": true,
            "domain": "S",
            "fpu": "single_precision"
        }
    }
}

Python build script could become:

````
if target.core.tz == True:
if target.core.name == "Coretex-M33":
self.flags['cxx'].append("-mcmse")
self.flags['c'].append("-mcmse")

    if target.core.domain == "S":
        # set DOMAIN_NS to 0
    else
        # set DOMAIN_NS to 1

else
    # set DOMAIN_NS to 0

````

@jeromecoutant It's possible, I hadn't really gone into how applications would select non-secure vs secure domains for a build.

@bridadan
Regard "core_tz" default value as true by macros_add "core_tz=true" in target.json .
For non-Trustzone application, developer could set macros_add "core_tz=false" in mbe_app.json .
Is there any misunderstanding your scenario ?
Is there any plan or schedule to publish non-TrustZone support ?

Hi @cyliangtw I don't quite understand your question. However in my branch I am not using macros to modify the use of TrustZone, but configuration values.

There are currently no plans or schedule to publish non-TrustZone support that I am aware of.

@bridadan , if configuration value matter with python build tool not easy to support non-TrustZone, macro is the alternative choice to pass through to relative c/c++/h files.
Anyway, it depends on your opinion.
More, we really have v8M without TrustZone chips and eager to see Mbed support.

Thanks for the feedback @cyliangtw. I'm not aware of the priority of this particular feature but we will take note of your interest! FYI @bulislaw

Please check #10514
Thx

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MarceloSalazar picture MarceloSalazar  路  3Comments

sarahmarshy picture sarahmarshy  路  4Comments

toyowata picture toyowata  路  4Comments

chrissnow picture chrissnow  路  4Comments

DuyTrandeLion picture DuyTrandeLion  路  3Comments