ARM Embedded (Bare Metal)

From Crypto++ Wiki
Jump to: navigation, search

This page will provide instructions for cross-compiling Crypto++ with a third-party branch of GCC ARM Embedded Tools for bare metal. The tools are available as a PPA on Ubuntu and the source code is available from GNU Tools for ARM Embedded Processors. The branch is maintained by Bin Cheng, Hale Wang, Joey Ye, Terry Guo, Thomas Preud'homme, Tony Wang and Zhenqiang Chen.

There are four reasons to use the alternate toolchain. First, the branch is from ARM Inc and maintained by ARM employees. Second, the project works well (unlike some distro's embedded toolchains). Third, the project is well supported. Fourth, the project supports the latest Cortex-M and Cortex-R processors (Cortex-M0/M0+/M3/M4, Cortex-R4/R5/R7).

There are four steps to building Crypto++ for embedded targets, and the process will create an embedded ARM version of cryptest.exe, the dynamic library, and the static library. After building the library, you can push cryptest.exe and the test vectors to the device. Once on the device, you can then execute the tests using a remote shell. The example below builds for the Cortex-M3 processor.

Note: setenv-embedded.sh was added to the library sources in March 2016. It is available in Git and library ZIP files after 5.6.3. Also see Commit 22d6374ce7151ad0, Added Android and embedded environment and test script.

If you are build for Android or iOS, then there are separate pages for the platforms. The pages use the toolchains provided by AOSP and Apple. See Android (Command Line) and iOS (Command Line) for details. Also see ARM (Command Line), ARM Embedded (Command Line) and ARM Embedded (Bare Metal) if building with the arm-linux-gnueabi toolchain.

Install the PPA

There a four steps to install the PPA. If working on Ubuntu 14.04 or higher, you will also need to pin the PPA. If you don't pin the PPA, then upgrade and dist-upgrade will overwrite the PPA files with the distro's files.

Here are the steps to install the PPA. Refer to GNU ARM Embedded Toolchain Overview for details.

sudo apt-get remove binutils-arm-none-eabi gcc-arm-none-eabi
sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded
sudo apt-get update
sudo apt-get install gcc-arm-none-eabi=4-8-2014q2-0trusty10

For Ubuntu 14.04 and higher, pin the PPA by adding the following to /etc/apt/preferences. Refer to Permanently block distro package installation? on Super User for details.

Package: binutils-arm-none-eabi
Pin: origin ppa.launchpad.net
Pin-Priority: 900

Package: gcc-arm-none-eabi
Pin: origin ppa.launchpad.net
Pin-Priority: 900

Finally, verify the pin:

$ apt-cache policy gcc-arm-none-eabi
gcc-arm-none-eabi:
  Installed: 4-8-2014q2-0trusty10
  Candidate: 4-8-2014q2-0trusty10
  Package pin: 4-8-2014q2-0trusty10
  Version table:
     4.8.2-14ubuntu1+6 900
        500 http://us.archive.ubuntu.com/ubuntu/ trusty/universe amd64 Packages
 *** 4-8-2014q2-0trusty10 900
        500 http://ppa.launchpad.net/terry.guo/gcc-arm-embedded/ubuntu/ trusty/main amd64 Packages
        100 /var/lib/dpkg/status

Set the Environment

Cryptopp-android-100.png
Before you begin you must set the cross-compilation environment. Setting the environment will do two things. First, it will ensure the arm-none-eabi toolchain is on-path. Second, it will ensure some environmental variables are set so the makefile picks up specific device flags. For example, the script will set IS_ARM_EMBEDDED, ARM_EMBEDDED_FLAGS and ARM_EMBEDDED_SYSROOT.

Perform the following to run the script. The source command is required to make changes to the current shell.

$ source ./setenv-embedded.sh 
CPP: /usr/bin/arm-none-eabi-cpp
CXX: /usr/bin/arm-none-eabi-g++
AR: /usr/bin/arm-none-eabi-ar
LD: /usr/bin/arm-none-eabi-ld
RANLIB: /usr/bin/arm-none-eabi-gcc-ranlib-4.7
ARM_EMBEDDED_TOOLCHAIN: /usr/bin
ARM_EMBEDDED_CXX_HEADERS: /usr/arm-none-eabi/include/c++/4.7.3
ARM_EMBEDDED_FLAGS: -I/usr/arm-none-eabi/include/c++/4.7.3 -I/usr/arm-none-eabi/include/c++/4.7.3/arm-none-eabi
ARM_EMBEDDED_SYSROOT: /usr/arm-none-eabi

Build the Library

Cryptopp-embedded-bare-01.png
Building the library consists of running the following command after setting the environment:
$ make -f GNUmakefile-cross

If you plan on stripping the dead code, then you should issue make -f GNUmakefile-cross lean. The lean target builds libcryptopp.a, libcryptopp.so and cryptest.exe; and it adds -ffunction-sections -fdata-sections for you. When you link your shared object or application, you will still need to add -Wl,--gc-sections to perform the stripping of the dead code from the final executable.

$ make -f GNUmakefile-cross static dynamic cryptest.exe
/usr/bin/arm-none-eabi-g++ -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM
-mcpu=cortex-m3 -mthumb --specs=nosys.specs --sysroot=/usr/arm-none-eabi
-c 3way.cpp
/usr/bin/arm-none-eabi-g++ -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM 
-mcpu=cortex-m3 -mthumb --specs=nosys.specs --sysroot=/usr/arm-none-eabi
-c adler32.cpp
/usr/bin/arm-none-eabi-g++ -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM 
-mcpu=cortex-m3 -mthumb --specs=nosys.specs --sysroot=/usr/arm-none-eabi
-c algebra.cpp
...

/usr/bin/arm-none-eabi-g++ -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM
-mcpu=cortex-m3 -mthumb --specs=nosys.specs --sysroot=/usr/arm-none-eabi
-shared -o libcryptopp.so 3way.o adler32.o algebra.o algparam.o arc4.o asn.o
... wake.o whrlpool.o winpipes.o xtr.o xtrcrypt.o zdeflate.o zinflate.o zlib.o
...

/usr/bin/arm-none-eabi-g++ -o cryptest.exe -DNDEBUG -g2 -Os -pipe -fPIC
-DCRYPTOPP_DISABLE_ASM -mcpu=cortex-m3 -mthumb --specs=nosys.specs --sysroot=
/usr/arm-none-eabi bench.o bench2.o test.o validat1.o validat2.o validat3.o
adhoc.o datatest.o regtest.o fipsalgt.o dlltest.o ./libcryptopp.a

Execute the Program

To be determined.

Architecture Options

The following table provides the options to use for ARM_EMBEDDED_FLAGS in setenv-embedded-bare.sh. You should also adjust ARM_EMBEDDED_SYSROOT appropriately. The table below was shamelessly ripped from GNU Tools for ARM Embedded Processors README:

--------------------------------------------------------------------
| ARM Core | Command Line Options                       | multilib |
|----------|--------------------------------------------|----------|
|Cortex-M0+| -mthumb -mcpu=cortex-m0plus                | armv6-m  |
|Cortex-M0 | -mthumb -mcpu=cortex-m0                    |          |
|Cortex-M1 | -mthumb -mcpu=cortex-m1                    |          |
|          |--------------------------------------------|          |
|          | -mthumb -march=armv6-m                     |          |
|----------|--------------------------------------------|----------|
|Cortex-M3 | -mthumb -mcpu=cortex-m3                    | armv7-m  |
|          |--------------------------------------------|          |
|          | -mthumb -march=armv7-m                     |          |
|----------|--------------------------------------------|----------|
|Cortex-M4 | -mthumb -mcpu=cortex-m4                    | armv7e-m |
|(No FP)   |--------------------------------------------|          |
|          | -mthumb -march=armv7e-m                    |          |
|----------|--------------------------------------------|----------|
|Cortex-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp | armv7e-m |
|(Soft FP) | -mfpu=fpv4-sp-d16                          | /softfp  |
|          |--------------------------------------------|          |
|          | -mthumb -march=armv7e-m -mfloat-abi=softfp |          |
|          | -mfpu=fpv4-sp-d16                          |          |
|----------|--------------------------------------------|----------|
|Cortex-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=hard   | armv7e-m |
|(Hard FP) | -mfpu=fpv4-sp-d16                          | /fpu     |
|          |--------------------------------------------|          |
|          | -mthumb -march=armv7e-m -mfloat-abi=hard   |          |
|          | -mfpu=fpv4-sp-d16                          |          |
|----------|--------------------------------------------|----------|
|Cortex-R4 | [-mthumb] -march=armv7-r                   | armv7-ar |
|Cortex-R5 |                                            | /thumb   |
|Cortex-R7 |                                            | 	   |
|(No FP)   |                                            |          |
|----------|--------------------------------------------|----------|
|Cortex-R4 | [-mthumb] -march=armv7-r -mfloat-abi=softfp| armv7-ar |
|Cortex-R5 | -mfpu=vfpv3-d16                            | /thumb   |
|Cortex-R7 |                                            | /softfp  |
|(Soft FP) |                                            |          |
|----------|--------------------------------------------|----------|
|Cortex-R4 | [-mthumb] -march=armv7-r -mfloat-abi=hard  | armv7-ar |
|Cortex-R5 | -mfpu=vfpv3-d16                            | /thumb   |
|Cortex-R7 |                                            | /fpu     |
|(Hard FP) |                                            |          |
|----------|--------------------------------------------|----------|
|Cortex-A* | [-mthumb] -march=armv7-a                   | armv7-ar |
|(No FP)   |                                            | /thumb   |
|----------|--------------------------------------------|----------|
|Cortex-A* | [-mthumb] -march=armv7-a -mfloat-abi=softfp| armv7-ar |
|(Soft FP) | -mfpu=vfpv3-d16                            | /thumb   |
|          |                                            | /softfp  |
|----------|--------------------------------------------|----------|
|Cortex-A* | [-mthumb] -march=armv7-a -mfloat-abi=hard  | armv7-ar |
|(Hard FP) | -mfpu=vfpv3-d16                            | /thumb   |
|          |                                            | /fpu     |
--------------------------------------------------------------------

Downloads

setenv-embedded-bare.sh.zip - Script to set the environment for ARM embedded cross-compiles. Added to the library at Crypto++ 5.6.3.

GNUmakefile-cross.zip - Makefile for cross-compiling the library. Added to the library at Crypto++ 5.6.3.