You copied the Doc URL to your clipboard.

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:
    #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:
    #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:
    $ 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:
    $ 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.
    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:
    $ 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:
    $ 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
    
    ...

Postrequisites

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.
Was this page helpful? Yes No