Commit d265bd7c authored by Harry Liebel's avatar Harry Liebel Committed by Dan Handley
Browse files

Add Firmware Image Package (FIP) documentation

This fixes ARM-software/tf-issues#9

Change-Id: Id57037115b8762efc9eaf5ff41887b71d6494c5d
parent 561cd33e
...@@ -13,7 +13,8 @@ Contents ...@@ -13,7 +13,8 @@ Contents
* Boot Loader stage 2 (BL2) * Boot Loader stage 2 (BL2)
* Boot Loader stage 3-1 (BL3-1) * Boot Loader stage 3-1 (BL3-1)
* PSCI implementation (in BL3-1) * PSCI implementation (in BL3-1)
4. C Library 4. C Library
5. Storage abstraction layer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
...@@ -105,7 +106,17 @@ constants defined. In the ARM FVP port, this file is found in ...@@ -105,7 +106,17 @@ constants defined. In the ARM FVP port, this file is found in
* **#define : BL2_IMAGE_NAME** * **#define : BL2_IMAGE_NAME**
Name of the BL2 binary image on the host file-system. This name is used by Name of the BL2 binary image on the host file-system. This name is used by
BL1 to load BL2 into secure memory using semi-hosting. BL1 to load BL2 into secure memory from non-volatile storage.
* **#define : BL31_IMAGE_NAME**
Name of the BL3-1 binary image on the host file-system. This name is used by
BL2 to load BL3-1 into secure memory from platform storage.
* **#define : BL33_IMAGE_NAME**
Name of the BL3-3 binary image on the host file-system. This name is used by
BL2 to load BL3-3 into non-secure memory from platform storage.
* **#define : PLATFORM_CACHE_LINE_SIZE** * **#define : PLATFORM_CACHE_LINE_SIZE**
...@@ -172,6 +183,10 @@ constants defined. In the ARM FVP port, this file is found in ...@@ -172,6 +183,10 @@ constants defined. In the ARM FVP port, this file is found in
Defines the base address in secure RAM where BL2 loads the BL3-1 binary Defines the base address in secure RAM where BL2 loads the BL3-1 binary
image. Must be aligned on a page-size boundary. image. Must be aligned on a page-size boundary.
* **#define : NS_IMAGE_OFFSET**
Defines the base address in non-secure DRAM where BL2 loads the BL3-3 binary
image. Must be aligned on a page-size boundary.
### Other mandatory modifications ### Other mandatory modifications
...@@ -325,7 +340,7 @@ warm boot. For each CPU, BL1 is responsible for the following tasks: ...@@ -325,7 +340,7 @@ warm boot. For each CPU, BL1 is responsible for the following tasks:
specific address in the BL3-1 image in the same processor mode as it was specific address in the BL3-1 image in the same processor mode as it was
when released from reset. when released from reset.
5. Loading the BL2 image in secure memory using semi-hosting at the 5. Loading the BL2 image from non-volatile storage into secure memory at the
address specified by the platform defined constant `BL2_BASE`. address specified by the platform defined constant `BL2_BASE`.
6. Populating a `meminfo` structure with the following information in memory, 6. Populating a `meminfo` structure with the following information in memory,
...@@ -434,6 +449,9 @@ MMU and data cache have been enabled. ...@@ -434,6 +449,9 @@ MMU and data cache have been enabled.
In the ARM FVP port, it zeros out the ZI section, enables the system level In the ARM FVP port, it zeros out the ZI section, enables the system level
implementation of the generic timer counter and initializes the console. implementation of the generic timer counter and initializes the console.
This function is also responsible for initializing the storage abstraction layer
which is used to load further bootloader images.
This function helps fulfill requirement 5 above. This function helps fulfill requirement 5 above.
...@@ -485,16 +503,17 @@ The BL2 stage is executed only by the primary CPU, which is determined in BL1 ...@@ -485,16 +503,17 @@ The BL2 stage is executed only by the primary CPU, which is determined in BL1
using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at
`BL2_BASE`. BL2 executes in Secure EL1 and is responsible for: `BL2_BASE`. BL2 executes in Secure EL1 and is responsible for:
1. Loading the BL3-1 binary image in secure RAM using semi-hosting. To load the 1. Loading the BL3-1 binary image into secure RAM from non-volatile storage. To
BL3-1 image, BL2 makes use of the `meminfo` structure passed to it by BL1. load the BL3-1 image, BL2 makes use of the `meminfo` structure passed to it
This structure allows BL2 to calculate how much secure RAM is available for by BL1. This structure allows BL2 to calculate how much secure RAM is
its use. The platform also defines the address in secure RAM where BL3-1 is available for its use. The platform also defines the address in secure RAM
loaded through the constant `BL31_BASE`. BL2 uses this information to where BL3-1 is loaded through the constant `BL31_BASE`. BL2 uses this
determine if there is enough memory to load the BL3-1 image. information to determine if there is enough memory to load the BL3-1 image.
2. Arranging to pass control to a normal world BL image that has been 2. Loading the normal world BL3-3 binary image into non-secure DRAM from
pre-loaded at a platform-specific address. This address is determined using platform storage and arranging for BL3-1 to pass control to this image. This
the `plat_get_ns_image_entrypoint()` function described below. address is determined using the `plat_get_ns_image_entrypoint()` function
described below.
BL2 populates an `el_change_info` structure in memory provided by the BL2 populates an `el_change_info` structure in memory provided by the
platform with information about how BL3-1 should pass control to the normal platform with information about how BL3-1 should pass control to the normal
...@@ -535,7 +554,9 @@ by the primary CPU. The arguments to this function are: ...@@ -535,7 +554,9 @@ by the primary CPU. The arguments to this function are:
The platform must copy the contents of the `meminfo` structure into a private The platform must copy the contents of the `meminfo` structure into a private
variable as the original memory may be subsequently overwritten by BL2. The variable as the original memory may be subsequently overwritten by BL2. The
copied structure is made available to all BL2 code through the copied structure is made available to all BL2 code through the
`bl2_plat_sec_mem_layout()` function. `bl2_plat_sec_mem_layout()` function. The non-secure memory extents used for
loading BL3-3 is also initialized in this function. Access to this information
is provided by the `bl2_get_ns_mem_layout()` function.
### Function : bl2_plat_arch_setup() [mandatory] ### Function : bl2_plat_arch_setup() [mandatory]
...@@ -570,6 +591,9 @@ accesses it in `bl2_main()`. ...@@ -570,6 +591,9 @@ accesses it in `bl2_main()`.
The ARM FVP port initializes this pointer to the base address of Secure DRAM The ARM FVP port initializes this pointer to the base address of Secure DRAM
(`0x06000000`). (`0x06000000`).
This function is also responsible for initializing the storage abstraction layer
which is used to load further bootloader images.
### Variable : unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE] [mandatory] ### Variable : unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE] [mandatory]
...@@ -592,6 +616,20 @@ populated with the extents of secure RAM available for BL2 to use. See ...@@ -592,6 +616,20 @@ populated with the extents of secure RAM available for BL2 to use. See
`bl2_early_platform_setup()` above. `bl2_early_platform_setup()` above.
### Function : bl2_get_ns_mem_layout() [mandatory]
Argument : void
Return : meminfo *
This function should only be called on the cold boot path. It may execute with
the MMU and data caches enabled if the platform port does the necessary
initialization in `bl2_plat_arch_setup()`. It is only called by the primary CPU.
The purpose of this function is to return a pointer to a `meminfo` structure
populated with the extents of non-secure DRAM available for BL2 to use. See
`bl2_early_platform_setup()` above.
### Function : init_bl31_mem_layout() [optional] ### Function : init_bl31_mem_layout() [optional]
Argument : meminfo *, meminfo *, unsigned int Argument : meminfo *, meminfo *, unsigned int
...@@ -620,8 +658,7 @@ As previously described, BL2 is responsible for arranging for control to be ...@@ -620,8 +658,7 @@ As previously described, BL2 is responsible for arranging for control to be
passed to a normal world BL image through BL3-1. This function returns the passed to a normal world BL image through BL3-1. This function returns the
entrypoint of that image, which BL3-1 uses to jump to it. entrypoint of that image, which BL3-1 uses to jump to it.
The ARM FVP port assumes that flash memory has been pre-loaded with the UEFI BL2 is responsible for loading the normal world BL3-3 image (e.g. UEFI).
image, and so returns the base address of flash memory.
3.2 Boot Loader Stage 3-1 (BL3-1) 3.2 Boot Loader Stage 3-1 (BL3-1)
...@@ -981,6 +1018,55 @@ A copy of the [FreeBSD] sources can be downloaded with `git`. ...@@ -981,6 +1018,55 @@ A copy of the [FreeBSD] sources can be downloaded with `git`.
git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0 git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0
5. Storage abstraction layer
-----------------------------
In order to improve platform independence and portability an storage abstraction
layer is used to load data from non-volatile platform storage.
Each platform should register devices and their drivers via the Storage layer.
These drivers then need to be initialized by bootloader phases as
required in their respective `blx_platform_setup()` functions. Currently
storage access is only required by BL1 and BL2 phases. The `load_image()`
function uses the storage layer to access non-volatile platform storage.
It is mandatory to implement at least one storage driver. For the FVP the
Firmware Image Package(FIP) driver is provided as the default means to load data
from storage (see the "Firmware Image Package" section in the [User Guide]).
The storage layer is described in the header file `include/io_storage.h`. The
implementation of the common library is in `lib/io_storage.c` and the driver
files are located in `drivers/io/`.
Each IO driver must provide `io_dev_*` structures, as described in
`drivers/io/io_driver.h`. These are returned via a mandatory registration
function that is called on platform initialization. The semi-hosting driver
implementation in `io_semihosting.c` can be used as an example.
The Storage layer provides mechanisms to initialize storage devices before
IO operations are called. The basic operations supported by the layer
include `open()`, `close()`, `read()`, `write()`, `size()` and `seek()`.
Drivers do not have to implement all operations, but each platform must
provide at least one driver for a device capable of supporting generic
operations such as loading a bootloader image.
The current implementation only allows for known images to be loaded by the
firmware. These images are specified by using their names, as defined in the
`platform.h` file. The platform layer (`plat_get_image_source()`) then returns
a reference to a device and a driver-specific `spec` which will be understood
by the driver to allow access to the image data.
The layer is designed in such a way that is it possible to chain drivers with
other drivers. For example, file-system drivers may be implemented on top of
physical block devices, both represented by IO devices with corresponding
drivers. In such a case, the file-system "binding" with the block device may
be deferred until the file-system device is initialised.
The abstraction currently depends on structures being statically allocated
by the drivers and callers, as the system does not yet provide a means of
dynamically allocating memory. This may also have the affect of limiting the
amount of open resources per driver.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ _Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
......
...@@ -50,7 +50,8 @@ The following tools are required to use the ARM Trusted Firmware: ...@@ -50,7 +50,8 @@ The following tools are required to use the ARM Trusted Firmware:
* `ia32-libs` package * `ia32-libs` package
* `build-essential` and `uuid-dev` packages for building UEFI * `build-essential` and `uuid-dev` packages for building UEFI and the Firmware
Image Package(FIP) tool
* `bc` and `ncurses-dev` packages for building Linux * `bc` and `ncurses-dev` packages for building Linux
...@@ -80,12 +81,14 @@ To build the software for the FVPs, follow these steps: ...@@ -80,12 +81,14 @@ To build the software for the FVPs, follow these steps:
cd arm-trusted-firmware cd arm-trusted-firmware
3. Set the compiler path and build: 3. Set the compiler path, specify a Normal World (BL3-3) image and build:
CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- make PLAT=fvp CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- BL33=<path-to-bl33> make PLAT=fvp
By default this produces a release version of the build. To produce a debug By default this produces a release version of the build. To produce a debug
version instead, refer to the "Debugging options" section below. version instead, refer to the "Debugging options" section below. UEFI can be
used as the BL3-3 image, refer to the "Obtaining the normal world software"
section below.
The build process creates products in a `build` directory tree, building The build process creates products in a `build` directory tree, building
the objects and binaries for each boot loader stage in separate the objects and binaries for each boot loader stage in separate
...@@ -97,10 +100,17 @@ To build the software for the FVPs, follow these steps: ...@@ -97,10 +100,17 @@ To build the software for the FVPs, follow these steps:
* `build/<platform>/<build-type>/bl31.bin` * `build/<platform>/<build-type>/bl31.bin`
... where `<platform>` currently defaults to `fvp` and `<build-type>` is ... where `<platform>` currently defaults to `fvp` and `<build-type>` is
either `debug` or `release`. either `debug` or `release`. A Firmare Image Package(FIP) will be created as
part of the build. It contains all boot loader images except for `bl1.bin`.
4. Copy the three boot loader binary files to the directory from which the FVP * `build/<platform>/<build-type>/fip.bin`
will be launched. Symbolic links of the same names may be created instead.
For more information on the `fip.bin` image see the "Firmware Image Package"
section below
4. Copy the `bl1.bin` and `fip.bin` binary files to the directory from which
the FVP will be launched. Symbolic links of the same names may be created
instead.
5. (Optional) Build products for a specific build variant can be removed using: 5. (Optional) Build products for a specific build variant can be removed using:
...@@ -168,6 +178,8 @@ is set to 'origin/master'. ...@@ -168,6 +178,8 @@ is set to 'origin/master'.
#### Obtaining UEFI #### Obtaining UEFI
TODO: Update UEFI GitHub hash.
Clone the [EDK2 (EFI Development Kit 2) source code][EDK2] from Github. This Clone the [EDK2 (EFI Development Kit 2) source code][EDK2] from Github. This
version supports the Base and Foundation FVPs. EDK2 is an open source version supports the Base and Foundation FVPs. EDK2 is an open source
implementation of the UEFI specification: implementation of the UEFI specification:
...@@ -186,20 +198,19 @@ these steps: ...@@ -186,20 +198,19 @@ these steps:
2. Copy build config templates to local workspace 2. Copy build config templates to local workspace
export EDK_TOOLS_PATH=$(pwd)/BaseTools . edksetup.sh
. edksetup.sh $(pwd)/BaseTools/
3. Rebuild EDK2 host tools 3. Rebuild EDK2 host tools
make -C "$EDK_TOOLS_PATH" clean make -C BaseTools clean
make -C "$EDK_TOOLS_PATH" make -C BaseTools
4. Build the software 4. Build the software
CROSS_COMPILE=<absolute-path-to-aarch64-gcc>/bin/aarch64-none-elf- \ CROSS_COMPILE=<absolute-path-to-aarch64-gcc>/bin/aarch64-none-elf- \
build -v -d3 -a AARCH64 -t ARMGCC \ make -f ArmPlatformPkg/Scripts/Makefile EDK2_ARCH=AARCH64 \
-p ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \ EDK2_DSC=ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \
-D ARM_FOUNDATION_FVP=1 EDK2_TOOLCHAIN=ARMGCC EDK2_MACROS="-n 6 -D ARM_FOUNDATION_FVP=1"
The EDK2 binary for use with the ARM Trusted Firmware can then be found The EDK2 binary for use with the ARM Trusted Firmware can then be found
here: here:
...@@ -219,10 +230,14 @@ location. To do this, build the software as described above with the ...@@ -219,10 +230,14 @@ location. To do this, build the software as described above with the
-D ARM_FVP_LEGACY_GICV2_LOCATION=1 -D ARM_FVP_LEGACY_GICV2_LOCATION=1
Then `make clean` before rebuilding EDK2. Then clean the source tree before rebuilding EDK2:
make -f ArmPlatformPkg/Scripts/Makefile EDK2_ARCH=AARCH64 \
EDK2_DSC=ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc \
EDK2_TOOLCHAIN=ARMGCC clean
The EDK2 binary `FVP_AARCH64_EFI.fd` should be loaded into FVP FLASH0 via model The EDK2 binary `FVP_AARCH64_EFI.fd` should be specified as `BL33` to the
parameters as described in the "Running the Software" section below. Trusted Firmware Makefile. See the "Building the Trusted Firmware" section.
#### Obtaining a Linux kernel #### Obtaining a Linux kernel
...@@ -421,13 +436,17 @@ The following `Foundation_v8` parameters should be used to boot Linux with ...@@ -421,13 +436,17 @@ The following `Foundation_v8` parameters should be used to boot Linux with
NOTE: Using the `--block-device` parameter is not necessary if a Linux RAM-disk NOTE: Using the `--block-device` parameter is not necessary if a Linux RAM-disk
file-system is used (see the "Obtaining a File-system" section above). file-system is used (see the "Obtaining a File-system" section above).
NOTE: The `--data="<path to FIP binary>"@0x8000000` parameter is used to load a
Firmware Image Package at the start of NOR FLASH0 (see the "Building the
Trusted Firmware" section above).
<path-to>/Foundation_v8 \ <path-to>/Foundation_v8 \
--cores=4 \ --cores=4 \
--no-secure-memory \ --no-secure-memory \
--visualization \ --visualization \
--gicv3 \ --gicv3 \
--data="<path to bl1.bin>"@0x0 \ --data="<path to bl1.bin>"@0x0 \
--data="<path to UEFI binary>"@0x8000000 \ --data="<path to FIP binary>"@0x8000000 \
--block-device="<path-to>/vexpress64-openembedded_lamp-armv8_20130927-7.img" --block-device="<path-to>/vexpress64-openembedded_lamp-armv8_20130927-7.img"
The default use-case for the Foundation FVP is to enable the GICv3 device in The default use-case for the Foundation FVP is to enable the GICv3 device in
...@@ -448,6 +467,10 @@ cache maintenance defects in the software. ...@@ -448,6 +467,10 @@ cache maintenance defects in the software.
NOTE: Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary NOTE: Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary
if a Linux RAM-disk file-system is used (see the "Obtaining a root file-system" if a Linux RAM-disk file-system is used (see the "Obtaining a root file-system"
section above).
NOTE: The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
section above). section above).
<path-to>/FVP_Base_AEMv8A-AEMv8A \ <path-to>/FVP_Base_AEMv8A-AEMv8A \
...@@ -458,7 +481,7 @@ section above). ...@@ -458,7 +481,7 @@ section above).
-C cache_state_modelled=1 \ -C cache_state_modelled=1 \
-C bp.pl011_uart0.untimed_fifos=1 \ -C bp.pl011_uart0.untimed_fifos=1 \
-C bp.secureflashloader.fname=<path to bl1.bin> \ -C bp.secureflashloader.fname=<path to bl1.bin> \
-C bp.flashloader0.fname=<path to UEFI binary> \ -C bp.flashloader0.fname=<path to FIP binary> \
-C bp.virtioblockdevice.image_path="<path-to>/vexpress64-openembedded_lamp-armv8_20130927-7.img" -C bp.virtioblockdevice.image_path="<path-to>/vexpress64-openembedded_lamp-armv8_20130927-7.img"
#### Running on the Cortex-A57-A53 Base FVP #### Running on the Cortex-A57-A53 Base FVP
...@@ -472,6 +495,10 @@ cache maintenance defects in the software. ...@@ -472,6 +495,10 @@ cache maintenance defects in the software.
NOTE: Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary NOTE: Using the `-C bp.virtioblockdevice.image_path` parameter is not necessary
if a Linux RAM-disk file-system is used (see the "Obtaining a root file-system" if a Linux RAM-disk file-system is used (see the "Obtaining a root file-system"
section above).
NOTE: The `-C bp.flashloader0.fname` parameter is used to load a Firmware Image
Package at the start of NOR FLASH0 (see the "Building the Trusted Firmware"
section above). section above).
<path-to>/FVP_Base_Cortex-A57x4-A53x4 \ <path-to>/FVP_Base_Cortex-A57x4-A53x4 \
...@@ -480,7 +507,7 @@ section above). ...@@ -480,7 +507,7 @@ section above).
-C cache_state_modelled=1 \ -C cache_state_modelled=1 \
-C bp.pl011_uart0.untimed_fifos=1 \ -C bp.pl011_uart0.untimed_fifos=1 \
-C bp.secureflashloader.fname=<path to bl1.bin> \ -C bp.secureflashloader.fname=<path to bl1.bin> \
-C bp.flashloader0.fname=<path to UEFI binary> \ -C bp.flashloader0.fname=<path to FIP binary> \
-C bp.virtioblockdevice.image_path="<path-to>/vexpress64-openembedded_lamp-armv8_20130927-7.img" -C bp.virtioblockdevice.image_path="<path-to>/vexpress64-openembedded_lamp-armv8_20130927-7.img"
### Configuring the GICv2 memory map ### Configuring the GICv2 memory map
...@@ -533,7 +560,7 @@ legacy VE memory map: ...@@ -533,7 +560,7 @@ legacy VE memory map:
--visualization \ --visualization \
--no-gicv3 \ --no-gicv3 \
--data="<path to bl1.bin>"@0x0 \ --data="<path to bl1.bin>"@0x0 \
--data="<path to UEFI binary>"@0x8000000 \ --data="<path to FIP binary>"@0x8000000 \
--block-device="<path-to>/vexpress64-openembedded_lamp-armv8_20130927-7.img" --block-device="<path-to>/vexpress64-openembedded_lamp-armv8_20130927-7.img"
Explicit configuration of the `SYS_ID` register is not required. Explicit configuration of the `SYS_ID` register is not required.
...@@ -723,11 +750,10 @@ BL1 execution continues as follows: ...@@ -723,11 +750,10 @@ BL1 execution continues as follows:
1. BL1 determines the amount of free trusted SRAM memory available by 1. BL1 determines the amount of free trusted SRAM memory available by
calculating the extent of its own data section, which also resides in calculating the extent of its own data section, which also resides in
trusted SRAM. BL1 loads a BL2 raw binary image through semi-hosting, at a trusted SRAM. BL1 loads a BL2 raw binary image from platform storage, at a
platform-specific base address. The filename of the BL2 raw binary image on platform-specific base address. The filename of the BL2 raw binary image
the host file system must be `bl2.bin`. If the BL2 image file is not present must be `bl2.bin`. If the BL2 image file is not present or if there is not
or if there is not enough free trusted SRAM the following error message enough free trusted SRAM the following error message is printed:
is printed:
"Failed to load boot loader stage 2 (BL2) firmware." "Failed to load boot loader stage 2 (BL2) firmware."
...@@ -777,31 +803,32 @@ the BL3-1 image. ...@@ -777,31 +803,32 @@ the BL3-1 image.
#### Normal world image load #### Normal world image load
BL2 loads a rich boot firmware image (UEFI). The image executes in the normal BL2 loads the normal world firmware image (e.g. UEFI). BL2 relies on BL3-1 to
world. BL2 relies on BL3-1 to pass control to the normal world software image it pass control to the normal world software image it loads. Hence, BL2 populates
loads. Hence, BL2 populates a platform-specific area of memory with the a platform-specific area of memory with the entrypoint and Current Program
entrypoint and Current Program Status Register (`CPSR`) of the normal world Status Register (`CPSR`) of the normal world software image. The entrypoint is
software image. The entrypoint is the load address of the normal world software the load address of the normal world software image. The `CPSR` is determined as
image. The `CPSR` is determined as specified in Section 5.13 of the [PSCI PDD] specified in Section 5.13 of the [PSCI PDD] [PSCI]. This information is passed
[PSCI]. This information is passed to BL3-1. to BL3-1.
##### UEFI firmware load ##### UEFI firmware load
By default, BL2 assumes the UEFI image is present at the base of NOR flash0 BL2 loads the BL3-3 (UEFI) image into non-secure memory as defined by the
(`0x08000000`), and arranges for BL3-1 to pass control to that location. As platform (`0x88000000` for FVPs), and arranges for BL3-1 to pass control to that
mentioned earlier, BL2 populates platform-specific memory with the entrypoint location. As mentioned earlier, BL2 populates platform-specific memory with the
and `CPSR` of the UEFI image. entrypoint and `CPSR` of the BL3-3 image.
#### BL3-1 image load and execution #### BL3-1 image load and execution
BL2 execution continues as follows: BL2 execution continues as follows:
1. BL2 loads the BL3-1 image into a platform-specific address in trusted SRAM. 1. BL2 loads the BL3-1 image into a platform-specific address in trusted SRAM
This is done using semi-hosting. The image is identified by the file and the BL3-3 image into a platform specific address in non-secure DRAM.
`bl31.bin` on the host file-system. If there is not enough memory to load The images are identified by the files `bl31.bin` and `bl33.bin` in
the image or the image is missing it leads to an assertion failure. If the platform storage. If there is not enough memory to load the images or the
BL3-1 image loads successfully, BL1 updates the amount of trusted SRAM used images are missing it leads to an assertion failure. If the BL3-1 image
and available for use by BL3-1. This information is populated at a loads successfully, BL1 updates the amount of trusted SRAM used and
available for use by BL3-1. This information is populated at a
platform-specific memory address. platform-specific memory address.
2. BL2 passes control back to BL1 by raising an SMC, providing BL1 with the 2. BL2 passes control back to BL1 by raising an SMC, providing BL1 with the
...@@ -920,7 +947,7 @@ memory address populated by BL2. ...@@ -920,7 +947,7 @@ memory address populated by BL2.
### Normal world software execution ### Normal world software execution
BL3-1 uses the entrypoint information provided by BL2 to jump to the normal BL3-1 uses the entrypoint information provided by BL2 to jump to the normal
world software image at the highest available Exception Level (EL2 if world software image (BL3-3) at the highest available Exception Level (EL2 if
available, otherwise EL1). available, otherwise EL1).
...@@ -954,7 +981,7 @@ and BL2. This memory layout is illustrated by the following diagram. ...@@ -954,7 +981,7 @@ and BL2. This memory layout is illustrated by the following diagram.
Each bootloader stage image layout is described by its own linker script. The Each bootloader stage image layout is described by its own linker script. The
linker scripts export some symbols into the program symbol table. Their values linker scripts export some symbols into the program symbol table. Their values
correspond to particular addresses. The trusted firwmare code can refer to these correspond to particular addresses. The trusted firmware code can refer to these
symbols to figure out the image memory layout. symbols to figure out the image memory layout.
Linker symbols follow the following naming convention in the trusted firmware. Linker symbols follow the following naming convention in the trusted firmware.
...@@ -998,7 +1025,7 @@ must be provided for each bootloader stage and some are specific to a given ...@@ -998,7 +1025,7 @@ must be provided for each bootloader stage and some are specific to a given
bootloader stage. bootloader stage.
The linker scripts define some extra, optional symbols. They are not actually The linker scripts define some extra, optional symbols. They are not actually
used by any code but they help in undertanding the bootloader images' memory used by any code but they help in understanding the bootloader images' memory
layout as they are easy to spot in the link map files. layout as they are easy to spot in the link map files.
#### Common linker symbols #### Common linker symbols
...@@ -1196,6 +1223,135 @@ following view: ...@@ -1196,6 +1223,135 @@ following view:
------------ 0x04000000 ------------ 0x04000000
### Firmware Image Package (FIP)
Using a Firmware Image Package (FIP) allows for packing bootloader images (and
potentially other payloads) into a single archive that can be loaded by the ARM
Trusted Firmware from non-volatile platform storage. A driver to load images
from a FIP has been added to the storage layer and allows a package to be read
from supported platform storage. A tool to create Firmware Image Packages is
also provided and described below.
#### Firmware Image Package layout
The FIP layout consists of a table of contents (ToC) followed by payload data.
The ToC itself has a header followed by one or more table entries. The ToC is
terminated by an end marker entry. All ToC entries describe some payload data
that has been appended to the end of the binary package. With the information
provided in the ToC entry the corresponding payload data can be retrieved.
------------------
| ToC Header |
|----------------|
| ToC Entry 0 |
|----------------|
| ToC Entry 1 |
|----------------|
| ToC End Marker |
|----------------|
| |
| Data 0 |
| |
|----------------|
| |
| Data 1 |
| |
------------------
The ToC header and entry formats are described in the header file
`include/firmware_image_package.h`. This file is used by both the tool and the
ARM Trusted firmware.
The ToC header has the following fields:
`name`: The name of the ToC. This is currently used to validate the header.
`serial_number`: A non-zero number provided by the creation tool
`flags`: Flags associated with this data. None are yet defined.
A ToC entry has the following fields:
`uuid`: All files are referred to by a pre-defined Universally Unique
IDentifier [UUID] . The UUIDs are defined in
`include/firmware_image_package`. The platform translates the requested
image name into the corresponding UUID when accessing the package.
`offset_address`: The offset address at which the corresponding payload data
can be found. The offset is calculated from the ToC base address.
`size`: The size of the corresponding payload data in bytes.
`flags`: Flags associated with this entry. Non are yet defined.
#### Creating a Firmware Image Package
The FIP creation tool can be used to pack specified images into a binary package
that can be loaded by the ARM Trusted Firmware from platform storage. The tool
currently only supports packing bootloader images. Additional image definitions
can be added to the tool as required.
The tool can be found in `tools/fip_create`. Instructions on how to build and
use the tool follow.
Build the tool:
make -C tools/fip_create
It is recommended to remove the build artifacts before rebuilding:
make -C tools/fip_create clean
Create a Firmware package that contains existing FVP BL2 and BL3-1 images:
# fip_create --help to print usage information
# fip_create <fip_name> <images to add> [--dump to show result]
./tools/fip_create/fip_create fip.bin --dump \
--bl2 build/fvp/debug/bl2.bin --bl31 build/fvp/debug/bl31.bin
Firmware Image Package ToC:
---------------------------
- Trusted Boot Firmware BL2: offset=0x88, size=0x81E8
file: 'build/fvp/debug/bl2.bin'
- EL3 Runtime Firmware BL3-1: offset=0x8270, size=0xC218
file: 'build/fvp/debug/bl31.bin'
---------------------------
Creating "fip.bin"
View the contents of an existing Firmware package:
./tools/fip_create/fip_create fip.bin --dump
Firmware Image Package ToC:
---------------------------
- Trusted Boot Firmware BL2: offset=0x88, size=0x81E8
- EL3 Runtime Firmware BL3-1: offset=0x8270, size=0xC218
---------------------------
Existing package entries can be individially updated:
# Change the BL2 from Debug to Release version
./tools/fip_create/fip_create fip.bin --dump \
--bl2 build/fvp/release/bl2.bin
Firmware Image Package ToC:
---------------------------
- Trusted Boot Firmware BL2: offset=0x88, size=0x7240
file: 'build/fvp/release/bl2.bin'
- EL3 Runtime Firmware BL3-1: offset=0x72C8, size=0xC218
---------------------------
Updating "fip.bin"
#### Loading from a Firmware Image Package (FIP)
The Firmware Image Package (FIP) driver can load images from a binary package on
non-volatile platform storage. For the FVPs this currently NOR FLASH. For
information on how to load a FIP into FVP NOR FLASH see the "Running the
software" section.
Bootloader images are loaded according to the platform policy as specified in
`plat/<platform>/plat_io_storage.c`. For the FVPs this means the platform will
attempt to load images from a Firmware Image Package located at the start of NOR
FLASH0.
Currently the FVPs policy only allows for loading of known images. The platform
policy can be modified to add additional images.
### Code Structure ### Code Structure
Trusted Firmware code is logically divided between the three boot loader Trusted Firmware code is logically divided between the three boot loader
...@@ -1256,3 +1412,4 @@ _Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._ ...@@ -1256,3 +1412,4 @@ _Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved._
[DS-5]: http://www.arm.com/products/tools/software-tools/ds-5/index.php [DS-5]: http://www.arm.com/products/tools/software-tools/ds-5/index.php
[PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022b/index.html "Power State Coordination Interface PDD (ARM DEN 0022B.b)" [PSCI]: http://infocenter.arm.com/help/topic/com.arm.doc.den0022b/index.html "Power State Coordination Interface PDD (ARM DEN 0022B.b)"
[SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)" [SMCCC]: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html "SMC Calling Convention PDD (ARM DEN 0028A)"
[UUID]: https://tools.ietf.org/rfc/rfc4122.txt "A Universally Unique IDentifier (UUID) URN Namespace"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment