Commit f53d0fce authored by Andrew Thoelke's avatar Andrew Thoelke
Browse files

Merge pull request #101 from sandrine-bailleux:sb/tf-issue-81-v2

parents 8957fc76 638363eb
......@@ -41,7 +41,11 @@ MEMORY {
SECTIONS
{
ro : {
. = BL1_RO_BASE;
ASSERT(. == ALIGN(4096),
"BL1_RO_BASE address is not aligned on a page boundary.")
ro . : {
__RO_START__ = .;
*bl1_entrypoint.o(.text*)
*(.text*)
......@@ -52,16 +56,19 @@ SECTIONS
/*
* The .data section gets copied from ROM to RAM at runtime.
* Its LMA and VMA must be 16-byte aligned.
* Its LMA must be 16-byte aligned.
* Its VMA must be page-aligned as it marks the first read/write page.
*/
. = NEXT(16); /* Align LMA */
.data : ALIGN(16) { /* Align VMA */
. = BL1_RW_BASE;
ASSERT(. == ALIGN(4096),
"BL1_RW_BASE address is not aligned on a page boundary.")
.data . : ALIGN(16) {
__DATA_RAM_START__ = .;
*(.data*)
__DATA_RAM_END__ = .;
} >RAM AT>ROM
stacks (NOLOAD) : {
stacks . (NOLOAD) : {
__STACKS_START__ = .;
*(tzfw_normal_stacks)
__STACKS_END__ = .;
......@@ -111,11 +118,17 @@ SECTIONS
__DATA_ROM_START__ = LOADADDR(.data);
__DATA_SIZE__ = SIZEOF(.data);
/*
* The .data section is the last PROGBITS section so its end marks the end
* of the read-only part of BL1's binary.
*/
ASSERT(__DATA_ROM_START__ + __DATA_SIZE__ <= BL1_RO_LIMIT,
"BL1's RO section has exceeded its limit.")
__BSS_SIZE__ = SIZEOF(.bss);
__COHERENT_RAM_UNALIGNED_SIZE__ =
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
ASSERT(. <= BL31_BASE, "BL1 image overlaps BL31 image.")
ASSERT(. <= BL1_RW_LIMIT, "BL1's RW section has exceeded its limit.")
}
......@@ -117,4 +117,6 @@ SECTIONS
__BSS_SIZE__ = SIZEOF(.bss);
__COHERENT_RAM_UNALIGNED_SIZE__ =
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
}
......@@ -126,5 +126,5 @@ SECTIONS
__COHERENT_RAM_UNALIGNED_SIZE__ =
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
ASSERT(. <= BL2_BASE, "BL31 image overlaps BL2 image.")
ASSERT(. <= BL31_LIMIT, "BL3-1 image has exceeded its limit.")
}
......@@ -119,5 +119,5 @@ SECTIONS
__COHERENT_RAM_UNALIGNED_SIZE__ =
__COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
ASSERT(. <= BL32_LIMIT, "BL3-2 image does not fit.")
ASSERT(. <= BL32_LIMIT, "BL3-2 image has exceeded its limit.")
}
......@@ -669,10 +669,12 @@ before returning through EL3 and running the non-trusted firmware (BL3-3):
----------------------------------
On FVP platforms, we use the Trusted ROM and Trusted SRAM to store the trusted
firmware binaries. BL1 is originally sitting in the Trusted ROM. Its read-write
data are relocated at the base of the Trusted SRAM at runtime. BL1 loads BL2
image near the top of the the trusted SRAM. BL2 loads BL3-1 image between BL1
and BL2. This memory layout is illustrated by the following diagram.
firmware binaries. BL1 is originally sitting in the Trusted ROM at address
`0x0`. Its read-write data are relocated at the base of the Trusted SRAM at
runtime. BL1 loads BL2 image near the top of the trusted SRAM. BL2 loads BL3-1
image between BL1 and BL2. Optionally, BL2 then loads the TSP as the BL3-2
image. By default it is loaded in Trusted SRAM, in this case it sits between
BL3-1 and BL2. This memory layout is illustrated by the following diagram.
Trusted SRAM
+----------+ 0x04040000
......@@ -682,6 +684,10 @@ and BL2. This memory layout is illustrated by the following diagram.
|----------|
| |
|----------|
| BL32 | (optional)
|----------|
| |
|----------|
| BL31 |
|----------|
| |
......@@ -694,6 +700,14 @@ and BL2. This memory layout is illustrated by the following diagram.
| BL1 (ro) |
+----------+ 0x00000000
The TSP image may be loaded in Trusted DRAM instead. This doesn't change the
memory layout of the other boot loader images in Trusted SRAM.
Although the goal at long term is to give complete flexibility over the memory
layout, all platforms should conform to this layout at the moment. This is
because of some limitations in the implementation of the image loader in the
Trusted Firmware. Refer to the "Limitations of the image loader" section below.
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
correspond to particular addresses. The trusted firmware code can refer to these
......@@ -777,97 +791,51 @@ for this purpose:
* `__BL1_RAM_START__` This is the start address of BL1 RW data.
* `__BL1_RAM_END__` This is the end address of BL1 RW data.
### BL2's and BL3-1's linker symbols
### BL2's, BL3-1's and TSP's linker symbols
Both BL2 and BL3-1 need to know the extents of their read-only section to set
BL2, BL3-1 and TSP need to know the extents of their read-only section to set
the right memory attributes for this memory region in their MMU setup code. The
following linker symbols are defined for this purpose:
* `__RO_START__`
* `__RO_END__`
### How to choose the right base address for each bootloader stage image
The current implementation of the image loader has some limitations. It is
designed to load images dynamically, at a load address chosen to minimize memory
fragmentation. The chosen image location can be either at the top or the bottom
of free memory. However, until this feature is fully functional, the code also
contains support for loading images at a link-time fixed address.
BL1 is always loaded at address `0x0`. BL2 and BL3-1 are loaded at specified
locations in Trusted SRAM. The lack of dynamic image loader support means these
load addresses must currently be adjusted as the code grows. The individual
images must be linked against their ultimate runtime locations.
### How to choose the right base addresses for each bootloader stage image
BL2 is loaded near the top of the Trusted SRAM. BL3-1 is loaded between BL1
and BL2. All three images are resident concurrently in Trusted RAM during boot
so overlaps are not permitted.
There is currently no support for dynamic image loading in the Trusted Firmware.
This means that all bootloader images need to be linked against their ultimate
runtime locations and the base addresses of each image must be chosen carefully
such that images don't overlap each other in an undesired way. As the code
grows, the base addresses might need adjustments to cope with the new memory
layout.
The image end addresses can be determined from the link map files of the
different images. These are the `build/<platform>/<build-type>/bl<x>/bl<x>.map`
files, with `<x>` the stage bootloader.
The memory layout is completely specific to the platform and so there is no
general recipe for choosing the right base addresses for each bootloader image.
However, there are tools to aid in understanding the memory layout. These are
the link map files: `build/<platform>/<build-type>/bl<x>/bl<x>.map`, with `<x>`
being the stage bootloader. They provide a detailed view of the memory usage of
each image. Among other useful information, they provide the end address of
each image.
* `bl1.map` link map file provides `__BL1_RAM_END__` address.
* `bl2.map` link map file provides `__BL2_END__` address.
* `bl31.map` link map file provides `__BL31_END__` address.
* `bl32.map` link map file provides `__BL32_END__` address.
To prevent images from overlapping each other, the following constraints must be
enforced:
1. `__BL1_RAM_END__ <= BL31_BASE`
2. `__BL31_END__ <= BL2_BASE`
3. `__BL2_END__ <= (<Top of Trusted SRAM>)`
This is illustrated by the following memory layout diagram:
+----------+ 0x04040000
| |
|----------| __BL2_END__
| BL2 |
|----------| BL2_BASE
| |
|----------| __BL31_END__
| BL31 |
|----------| BL31_BASE
| |
|----------| __BL1_RAM_END__
| BL1 (rw) |
+----------+ 0x04000000
Overlaps are detected during image linking as follows.
Constraint 1 is enforced by BL1's linker script. If it is violated then the
linker will report an error while building BL1 to indicate that it doesn't
fit:
aarch64-none-elf-ld: BL31 image overlaps BL1 image.
This error means that the BL3-1 base address needs to be incremented. Ensure
that the new memory layout still obeys all constraints.
Constraint 2 is enforced by BL3-1's linker script. If it is violated then the
linker will report an error while building BL3-1 to indicate that it doesn't
fit:
aarch64-none-elf-ld: BL31 image overlaps BL2 image.
This error can either mean that the BL3-1 base address needs to be decremented
or that BL2 base address needs to be incremented. Ensure that the new memory
layout still obeys all constraints.
Constraint 3 is enforced by BL2's linker script. If it is violated then the
linker will report an error while building BL2 to indicate that it doesn't
fit. For example:
For each bootloader image, the platform code must provide its start address
as well as a limit address that it must not overstep. The latter is used in the
linker scripts to check that the image doesn't grow past that address. If that
happens, the linker will issue a message similar to the following:
aarch64-none-elf-ld: address 0x40400c8 of bl2.elf section `.bss' is not
within region `RAM'
aarch64-none-elf-ld: BLx has exceeded its limit.
This error means that the BL2 base address needs to be decremented. Ensure that
the new memory layout still obeys all constraints.
On FVP platforms, the base addresses have been chosen such that all images can
reside concurrently in Trusted RAM without overlapping each other. Note that
this is not a requirement, as not all images live in memory at the same time.
For example, when the BL3-1 image takes over execution, BL1 and BL2 images are
not needed anymore.
Since constraint checks are scattered across linker scripts, it is required to
`make clean` prior to building to ensure that all possible overlapping scenarios
are checked.
### Limitations of the image loader
The current implementation of the image loader can result in wasted space
because of the simplified data structure used to represent the extents of free
......
......@@ -180,16 +180,44 @@ constants defined. In the ARM FVP port, this file is found in
Defines the base address of the `CNTCTLBase` frame of the memory mapped
counter and timer in the system level implementation of the generic timer.
* **#define : BL1_RO_BASE**
Defines the base address in secure ROM where BL1 originally lives. Must be
aligned on a page-size boundary.
* **#define : BL1_RO_LIMIT**
Defines the maximum address in secure ROM that BL1's actual content (i.e.
excluding any data section allocated at runtime) can occupy.
* **#define : BL1_RW_BASE**
Defines the base address in secure RAM where BL1's read-write data will live
at runtime. Must be aligned on a page-size boundary.
* **#define : BL1_RW_LIMIT**
Defines the maximum address in secure RAM that BL1's read-write data can
occupy at runtime.
* **#define : BL2_BASE**
Defines the base address in secure RAM where BL1 loads the BL2 binary image.
Must be aligned on a page-size boundary.
* **#define : BL2_LIMIT**
Defines the maximum address in secure RAM that the BL2 image can occupy.
* **#define : BL31_BASE**
Defines the base address in secure RAM where BL2 loads the BL3-1 binary
image. Must be aligned on a page-size boundary.
* **#define : BL31_LIMIT**
Defines the maximum address in secure RAM that the BL3-1 image can occupy.
* **#define : NS_IMAGE_OFFSET**
Defines the base address in non-secure DRAM where BL2 loads the BL3-3 binary
......
......@@ -244,15 +244,31 @@
#define PLAT_AFF1_SUSPEND 0x2
#define PLAT_AFF1_ON 0x3
/*******************************************************************************
* BL1 specific defines.
* BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of
* addresses.
******************************************************************************/
#define BL1_RO_BASE TZROM_BASE
#define BL1_RO_LIMIT (TZROM_BASE + TZROM_SIZE)
#define BL1_RW_BASE TZRAM_BASE
#define BL1_RW_LIMIT BL31_BASE
/*******************************************************************************
* BL2 specific defines.
******************************************************************************/
#define BL2_BASE (TZRAM_BASE + TZRAM_SIZE - 0xc000)
#define BL2_LIMIT (TZRAM_BASE + TZRAM_SIZE)
/*******************************************************************************
* BL31 specific defines.
******************************************************************************/
#define BL31_BASE (TZRAM_BASE + 0x6000)
#if TSP_RAM_LOCATION_ID == TSP_IN_TZRAM
#define BL31_LIMIT BL32_BASE
#elif TSP_RAM_LOCATION_ID == TSP_IN_TZDRAM
#define BL31_LIMIT BL2_BASE
#endif
/*******************************************************************************
* BL32 specific defines.
......
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