9.2 Building a Secure image using the Armv8‑M Security Extensions

When building a Secure image you must also generate an import library that specifies the entry points to the Secure image. The import library is used when building a Non-secure image that needs to call the Secure image.

Prerequisites

The following procedure is not a complete example, and assumes that your code sets up the Security Attribution Unit (SAU) and calls the Non-secure startup code.

Procedure

  1. Create an interface header file, myinterface_v1.h, to specify the C linkage for use by Non-secure code:
    Example:
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    int entry1(int x);
    int entry2(int x);
    
    #ifdef __cplusplus
    }
    #endif
  2. In the C program for your Secure code, secure.c, include the following:
    Example:
    #include <arm_cmse.h>
    #include "myinterface_v1.h"
    
    int func1(int x) { return x; }
    int __attribute__((cmse_nonsecure_entry)) entry1(int x) { return func1(x);  }
    int __attribute__((cmse_nonsecure_entry)) entry2(int x) { return entry1(x); }
    					
    int main(void) { return 0; }
    In addition to the implementation of the two entry functions, the code defines the function func1() that is called only by Secure code.

    Note:

    If you are compiling the Secure code as C++, then you must add extern "C" to the functions declared as __attribute__((cmse_nonsecure_entry)).
  3. Create an object file using the armclang -mcmse command-line options:
    Example:
    $ armclang -c --target arm-arm-none-eabi -march=armv8-m.main -mcmse secure.c -o secure.o
  4. Enter the following command to see the disassembly of the machine code that armclang generates:
    Example:
    $ armclang -c --target arm-arm-none-eabi -march=armv8-m.main -mcmse -S secure.c
    The disassembly is stored in the file secure.s, for example:
        .text
        ...
        .code 16
        .thumb_func
        ...
    func1:
        .fnstart
        ...
        bx lr
        ...
    __acle_se_entry1:
    entry1:
        .fnstart
    @ BB#0:
        .save	{r7, lr}
        push	{r7, lr}
        ...
        bl func1
        ...
        pop.w {r7, lr}
        ...
        bxns lr
        ...
    __acle_se_entry2:
    entry2:
        .fnstart
    @ BB#0:
        .save	{r7, lr}
        push	{r7, lr}
        ...
        bl entry1
        ...
        pop.w {r7, lr}
        bxns lr
        ...
    main:
        .fnstart
    @ BB#0:
        ...
        movs r0, #0
        ...
        bx lr
        ...

    An entry function does not start with a Secure Gateway (SG) instruction. The two symbols __acle_se_entry_name and entry_name indicate the start of an entry function to the linker.

  5. Create a scatter file containing the Veneer$$CMSE selector to place the entry function veneers in a Non-Secure Callable (NSC) memory region.
    Example:
    LOAD_REGION 0x0 0x3000
    {
        EXEC_R 0x0
        {
            *(+RO,+RW,+ZI)
        }
        EXEC_NSCR 0x4000 0x1000
        {
            *(Veneer$$CMSE)
        }
        ARM_LIB_STACK 0x700000 EMPTY -0x10000
        {
        }
        ARM_LIB_HEAP  +0 EMPTY 0x10000
        {
        }
    }
    ...
  6. Link the object file using the armlink --import-cmse-lib-out command-line option and the scatter file to create the Secure image:
    Example:
    $ armlink secure.o -o secure.axf --cpu 8-M.Main --import-cmse-lib-out importlib_v1.o --scatter secure.scf

    In addition to the final image, the link in this example also produces the import library, importlib_v1.o, for use when building a Non-secure image. Assuming that the section with veneers is placed at address 0x4000, the import library consists of a relocatable file containing only a symbol table with the following entries:

    Symbol type Name Address
    STB_GLOBAL, SHN_ABS, STT_FUNC entry1 0x4001
    STB_GLOBAL, SHN_ABS, STT_FUNC entry2 0x4009

    When you link the relocatable file corresponding to this assembly code into an image, the linker creates veneers in a section containing only entry veneers.

    Note:

    If you have an import library from a previous build of the Secure image, you can ensure that the addresses in the output import library do not change when producing a new version of the Secure image. To ensure that the addresses do not change, specify the --import-cmse-lib-in command-line option together with the --import-cmse-lib-out option. However, make sure the input and output libraries have different names.
  7. Enter the following command to see the entry veneers that the linker generates:
    Example:
    $ fromelf --text -s -c secure.axf

    The following entry veneers are generated in the EXEC_NSCR execute-only (XO) region for this example:

    ...
    
    ** Section #3 'EXEC_NSCR' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR + SHF_ARM_NOREAD]
        Size   : 32 bytes (alignment 32)
        Address: 0x00004000
    
        $t
        entry1
            0x00004000:    e97fe97f    ....    SG        ; [0x3e08]
            0x00004004:    f7fcb85e    ..^.    B        __acle_se_entry1 ; 0xc4
        entry2
            0x00004008:    e97fe97f    ....    SG        ; [0x3e10]
            0x0000400c:    f7fcb86c    ..l.    B        __acle_se_entry2 ; 0xe8
    
    ...

    The section with the veneers is aligned on a 32-byte boundary and padded to a 32-byte boundary.

    If you do not use a scatter file, the entry veneers are placed in an ER_XO section as the first execution region, for example:

    ...
    
    ** Section #1 'ER_XO' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR + SHF_ARM_NOREAD]
        Size   : 32 bytes (alignment 32)
        Address: 0x00008000
    
        $t
        entry1
            0x00008000:    e97fe97f    ....    SG        ; [0x7e08]
            0x00008004:    f000b85a    ..Z.    B.W      __acle_se_entry1 ; 0x80bc
        entry2
            0x00008008:    e97fe97f    ....    SG        ; [0x7e10]
            0x0000800c:    f000b868    ..h.    B.W      __acle_se_entry2 ; 0x80e0
    
    ...

Next Steps

After you have built your Secure image:

  1. Pre-load the Secure image onto your device.
  2. Deliver your device with the pre-loaded image, together with the import library package, to a party who develops the Non-secure code for this device. The import library package contains:
    • The interface header file, myinterface_v1.h.
    • The import library, importlib_v1.o.
Non-ConfidentialPDF file icon PDF versionDUI0773J
Copyright © 2014–2017, 2019 Arm Limited or its affiliates. All rights reserved.