1

I'm exploring the i.MX53 QSB and the TrustZone extensions. I run an OS in the secure world thanks to the U-Boot bootloader. Now I'm in the secure world. I have three questions :

  • The first question is when should I share the memory and the interrupts between the secure and normal world ?
  • The second one is how can I move to the normal world in order to run a Rich OS on it?
  • The third question concerns the monitor mode code, where should I write it ? Is it a kernel module in the secure world ?
artless noise
  • 21,212
  • 6
  • 68
  • 105
EngineerN
  • 133
  • 2
  • 11
  • See also: [TZ scheduler](http://stackoverflow.com/questions/22659472/arm-trustzone-behaviour-of-the-scheduler-in-secure-and-non-secure-os) question. – artless noise Apr 09 '15 at 16:50

2 Answers2

2

Think of the secure monitor code as a kind of hypervisor that mediates between the secure OS and the non-secure OS. Typically it would be some standalone bare-metal firmware which mostly just dispatches calls and interrupts to the secure OS - I suppose technically it could be made entirely integral to the secure OS, but that hurts reusability and opens up the potential for far more security holes, so would generally be strongly discouraged.

The monitor code is also what should be solely responsible for world-switching - once the secure OS is up and running it should call into the monitor, which sets SCR.NS and performs an exception return down to the non-secure world to kick off the non-secure bootloader.

As for sharing resources between secure and non-secure, that's entirely down to what you want to do - a relatively simple secure payload like a software TPM might need no shared resources at all; something like full-path content protection involves handing off buffers and entire devices between worlds and is far more complex.

Notlikethat
  • 20,095
  • 3
  • 40
  • 77
  • Thank you for your response. But in practice, let's suppose I have a secure OS and a Rich OS and U-Boot as bootloader. Is it U-Boot which boots the secure world, install the secure monitor software and calls the SMC intruction ? Or I have to do it manually after booting the secure OS ? And can you give more details if you have the answer please – EngineerN Apr 09 '15 at 11:40
  • I am not aware of code in 'u-boot' that does monitor mode; it may have stub code to handle some sort of 'hypervisor' boot on 64bit ARM CPUs. If there is no code in 'u-boot' (public source which you may look at for your particular version), then of course you must implement it yourself. – artless noise Apr 09 '15 at 14:31
  • @EngineerN IIRC (from the Exynos 5410 secure boot code), out of reset the U-Boot SPL does the basic board initialisation, relocates U-Boot itself to RAM, loads the firmware blob into secure SRAM and just jumps to it. The firmware then sets up its own monitor vectors and does the execption return to the non-secure RAM copy of the U-Boot entry point. That was a rather different system, though, so you'd best look at Freescale's U-Boot code - if they're not using the SPL and just running the whole thing through in the secure world, then you're on your own for getting the normal world started. – Notlikethat Apr 09 '15 at 16:11
1

.. when should I share the memory and the interrupts between the secure and normal world ?

Memory sharing depends on your system requirements/design. It is possible to use the smc to only use registers to share information. No one can give a generic answer on memory sharing.

It rarely makes sense to share interrupts. You would need a driver in both worlds. The whole point of trustzone is to partition hardware.

Some hardware is trustzone aware. Ie, it can change it's register set/view based on what world is executing. Generally, this hardware only has an interrupt for one world or a separate interrupt number. If you do not have a device that is trustzone aware, this is probably a foolish thing to try.

..how can I move to the normal world in order to run a Rich OS on it?

Well, this is fairly simple when you have a monitor mode. So, from the secure boot (maybe a secure OS task/thread),

  1. Load the normal world OS to memory.
  2. Setup monitor mode stack and other contexts; monitor mode will need a memory buffer to store world contexts.
  3. Switch to monitor mode.
  4. Setup memory partitioning (intially allow everything for the normal world).
  5. Change the NS bit to set normal world CP15.
  6. Configure CP15 registers as per boot default. Many OSs will expect that they are booting as per normal. Most trustzone CPUs do not setup the normal world CP15 registers by default.
  7. Mask interrupts, turn off cache, etc as required to boot normal OS.
  8. With NS bit still set, do a world switch.

The world switch is dependent on your system design. If the secure world OS only used registers R0-R12 the instructions might be like,

    # NS bit is set.
    msr     spsr_fsxc, lr    # mon_lr contains normal world mode, etc.
    ldm sp, {r0 - r12, pc}^  # monitor 'sp' is a context pointer.

The ldm rX, {xxx, pc}^ will do a mode switch. The monitor 'sp' could have 13 zeros (for r0-r12) and then a normal world entry point for the 'PC'. The monitor 'lr' would have the starting mode (interrupt masked, etc) for the normal world.

NOTE: This is a simple example and it not meant for your particular OS. It is only conceptual. Specifics depend on specific normal/secure world OS requirements. Typically, you need to do all the things a boot loader would do for that platform/OS without TrustZone. As well, you need to initialize all registers in all modes. You may not care about registers the secure world doesn't use (NEON/VFP) and leave them as per boot defaults; this is more true for actual 'world switch' code.

...concerning the monitor mode code, where should I write it? Is it a kernel module in the secure world?

Monitor mode will always USE the CP15 registers of the secure world. This implies monitor mode has the MMU view, cache, etc of the secure OS. When the 'NS' bit is set and monitor mode does a mcr or mrc, it is setting the normal world registers. Well, technically it could be 'separate' there will probably be a lot of interaction between the secure OS and the monitor. Again, it depends on specifics. There are many types of OSs (or world contexts),

  1. Polling mode
  2. Non-preemptive
  3. Pre-emptive

You have permutations of the above for both the secure and normal world and the world switch handling will depend on the requirement of both. For the most complex case (Pre-emptive secure/normal), you need integration of schedulers which is OS dependent.

Community
  • 1
  • 1
artless noise
  • 21,212
  • 6
  • 68
  • 105
  • Thank you for your answer!!! but I still have questions concerning the second point **how can I move to the normal world in order to run a Rich OS on it** If I understand, I have to run the secure OS thanks to u-boot for exemple. After that, in a thread in this secure OS I realize everything related with the initialisation of the monitor system, after that I call an SMC to move to the monitor mode...ect ? It's not u-boot as bootloader for the normal world who will do this I have to do it manually? The second question concerns a github repo that I found dealing with this – EngineerN Apr 10 '15 at 08:29
  • In this repo [link](https://github.com/finallyjustice/liboot-tz) the person used u-boot-2009 as a secure OS and a linux as a rich OS. Can you show me on which file, all are we talking about i.e **how can I move to the normal world in order to run a Rich OS on it** is ? – EngineerN Apr 10 '15 at 08:35
  • The switch is in my answer `ldm rX, {xxx, pc}^` several times. The `smc` is used to call from the **normal world** to the **monitor->secure world**. The 'libboot-tz' has a files **u-boot/arch/arm/lib/tz-secure*.S**; this is the code to examine. He uses `msr spsr_cxsf, #mode_SVC` and `movs pc,lr` to do the initial call. This is not as efficient as my suggestion. The monitor code could use the same context switch; but he custom codes both. Also, I think this setup is *polling mode secure world/pre-emptive OS normal*. This makes the monitor mode simple to implement. *u-boot* is not an OS. – artless noise Apr 10 '15 at 15:45