mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 17:44:19 +00:00
Merge pull request #101 from sandrine-bailleux:sb/tf-issue-81-v2
This commit is contained in:
commit
f53d0fce3f
7 changed files with 113 additions and 86 deletions
25
bl1/bl1.ld.S
25
bl1/bl1.ld.S
|
@ -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
|
||||
### How to choose the right base addresses 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.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
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:
|
||||
|
||||
1. `__BL1_RAM_END__ <= BL31_BASE`
|
||||
2. `__BL31_END__ <= BL2_BASE`
|
||||
3. `__BL2_END__ <= (<Top of Trusted SRAM>)`
|
||||
aarch64-none-elf-ld: BLx has exceeded its limit.
|
||||
|
||||
This is illustrated by the following memory layout diagram:
|
||||
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.
|
||||
|
||||
+----------+ 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:
|
||||
|
||||
aarch64-none-elf-ld: address 0x40400c8 of bl2.elf section `.bss' is not
|
||||
within region `RAM'
|
||||
|
||||
This error means that the BL2 base address needs to be decremented. Ensure that
|
||||
the new memory layout still obeys all constraints.
|
||||
|
||||
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.
|
||||
|
|
Loading…
Add table
Reference in a new issue