Merge pull request #561 from antonio-nino-diaz-arm/an/bootwrapper
Enable preloaded BL33 alternative boot flow
diff --git a/Makefile b/Makefile
index 81991b8..6d17cfd 100644
--- a/Makefile
+++ b/Makefile
@@ -313,6 +313,29 @@
################################################################################
+# Check incompatible options
+################################################################################
+
+ifdef EL3_PAYLOAD_BASE
+ ifdef BL33_BASE
+ $(warning "BL33_BASE and EL3_PAYLOAD_BASE are incompatible \
+ build options. EL3_PAYLOAD_BASE has priority.")
+ endif
+endif
+
+ifeq (${NEED_BL33},yes)
+ ifdef EL3_PAYLOAD_BASE
+ $(warning "BL33 image is not needed when option \
+ BL33_PAYLOAD_BASE is used and won't be added to the FIP file.")
+ endif
+ ifdef BL33_BASE
+ $(warning "BL33 image is not needed when option BL33_BASE is \
+ used and won't be added to the FIP file.")
+ endif
+endif
+
+
+################################################################################
# Process platform overrideable behaviour
################################################################################
@@ -325,12 +348,19 @@
# supplied for the FIP and Certificate generation tools. This flag can be
# overridden by the platform.
ifdef BL2_SOURCES
-ifndef EL3_PAYLOAD_BASE
-NEED_BL33 ?= yes
-else
-# The BL33 image is not needed when booting an EL3 payload.
-NEED_BL33 := no
-endif
+ ifdef EL3_PAYLOAD_BASE
+ # If booting an EL3 payload there is no need for a BL33 image
+ # in the FIP file.
+ NEED_BL33 := no
+ else
+ ifdef BL33_BASE
+ # If booting a BL33 preloaded image there is no need of
+ # another one in the FIP file.
+ NEED_BL33 := no
+ else
+ NEED_BL33 ?= yes
+ endif
+ endif
endif
# Process TBB related flags
@@ -410,11 +440,17 @@
$(eval $(call add_define,ERROR_DEPRECATED))
$(eval $(call add_define,ENABLE_PLAT_COMPAT))
$(eval $(call add_define,SPIN_ON_BL1_EXIT))
+$(eval $(call add_define,PL011_GENERIC_UART))
# Define the EL3_PAYLOAD_BASE flag only if it is provided.
ifdef EL3_PAYLOAD_BASE
-$(eval $(call add_define,EL3_PAYLOAD_BASE))
+ $(eval $(call add_define,EL3_PAYLOAD_BASE))
+else
+ # Define the BL33_BASE flag only if it is provided and EL3_PAYLOAD_BASE
+ # is not defined, as it has priority.
+ ifdef BL33_BASE
+ $(eval $(call add_define,BL33_BASE))
+ endif
endif
-$(eval $(call add_define,PL011_GENERIC_UART))
################################################################################
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index 9ff75d2..73781dd 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -169,6 +169,7 @@
return e;
}
+#ifndef BL33_BASE
/*******************************************************************************
* Load the BL33 image.
* The bl2_to_bl31_params param will be updated with the relevant BL33
@@ -199,6 +200,8 @@
return e;
}
+#endif /* BL33_BASE */
+
#endif /* EL3_PAYLOAD_BASE */
/*******************************************************************************
@@ -253,7 +256,7 @@
* bl31_params_t structure makes sense in the context of EL3 payloads.
* This will be refined in the future.
*/
- VERBOSE("BL2: Populating the entrypoint info for the EL3 payload\n");
+ INFO("BL2: Populating the entrypoint info for the EL3 payload\n");
bl31_ep_info->pc = EL3_PAYLOAD_BASE;
bl31_ep_info->args.arg0 = (unsigned long) bl2_to_bl31_params;
bl2_plat_set_bl31_ep_info(NULL, bl31_ep_info);
@@ -274,11 +277,22 @@
}
}
+#ifdef BL33_BASE
+ /*
+ * In this case, don't load the BL33 image as it's already loaded in
+ * memory. Update BL33 entrypoint information.
+ */
+ INFO("BL2: Populating the entrypoint info for the preloaded BL33\n");
+ bl2_to_bl31_params->bl33_ep_info->pc = BL33_BASE;
+ bl2_plat_set_bl33_ep_info(NULL, bl2_to_bl31_params->bl33_ep_info);
+#else
e = load_bl33(bl2_to_bl31_params);
if (e) {
ERROR("Failed to load BL33 (%i)\n", e);
plat_error_handler(e);
}
+#endif /* BL33_BASE */
+
#endif /* EL3_PAYLOAD_BASE */
/* Flush the params to be passed to memory */
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 26c89bd..f0adf57 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -230,11 +230,6 @@
Defines the maximum address in secure RAM that the BL31 image can occupy.
-* **#define : NS_IMAGE_OFFSET**
-
- Defines the base address in non-secure DRAM where BL2 loads the BL33 binary
- image. Must be aligned on a page-size boundary.
-
For every image, the platform must define individual identifiers that will be
used by BL1 or BL2 to load the corresponding image into memory from non-volatile
storage. For the sake of performance, integer numbers will be used as
@@ -1047,10 +1042,10 @@
structure in memory provided by the platform with information about how
BL31 should pass control to the BL32 image.
-5. Loading the normal world BL33 binary image into non-secure DRAM from
- platform storage and arranging for BL31 to pass control to this image. This
- address is determined using the `plat_get_ns_image_entrypoint()` function
- described below.
+5. (Optional) Loading the normal world BL33 binary image (if not loaded by
+ other means) into non-secure DRAM from platform storage and arranging for
+ BL31 to pass control to this image. This address is determined using the
+ `plat_get_ns_image_entrypoint()` function described below.
6. BL2 populates an `entry_point_info` structure in memory provided by the
platform with information about how BL31 should pass control to the
@@ -1222,6 +1217,10 @@
overwrite the entry point set by loader and also set the security state
and SPSR which represents the entry point system state for BL33.
+In the preloaded BL33 alternative boot flow, this function is called after
+populating its entry point address. It is passed a null pointer as its first
+argument in this case.
+
### Function : bl2_plat_get_bl32_meminfo() [mandatory]
@@ -1243,6 +1242,9 @@
validate whether the BL33 image can be loaded with in the given
memory from the given base.
+This function isn't needed if either `BL33_BASE` or `EL3_PAYLOAD_BASE` build
+options are used.
+
### Function : bl2_plat_flush_bl31_params() [mandatory]
Argument : void
@@ -1265,6 +1267,9 @@
BL2 is responsible for loading the normal world BL33 image (e.g. UEFI).
+This function isn't needed if either `BL33_BASE` or `EL3_PAYLOAD_BASE` build
+options are used.
+
3.3 FWU Boot Loader Stage 2 (BL2U)
----------------------------------
@@ -1966,9 +1971,10 @@
* **NEED_BL33**
By default, this flag is defined `yes` by the build system and `BL33`
- build option should be supplied as a build option. The platform has the option
- of excluding the BL33 image in the `fip` image by defining this flag to
- `no`.
+ build option should be supplied as a build option. The platform has the
+ option of excluding the BL33 image in the `fip` image by defining this flag
+ to `no`. If any of the options `EL3_PAYLOAD_BASE` or `BL33_BASE` are used,
+ this flag will be set to `no` automatically.
5. C Library
-------------
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 9c17e35..ea10a81 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -10,10 +10,11 @@
5. [Building the Trusted Firmware](#5--building-the-trusted-firmware)
6. [Building the rest of the software stack](#6--building-the-rest-of-the-software-stack)
7. [EL3 payloads alternative boot flow](#7--el3-payloads-alternative-boot-flow)
-8. [Preparing the images to run on FVP](#8--preparing-the-images-to-run-on-fvp)
-9. [Running the software on FVP](#9--running-the-software-on-fvp)
-10. [Running the software on Juno](#10--running-the-software-on-juno)
-11. [Changes required for booting Linux on FVP in GICv3 mode](#11--changes-required-for-booting-linux-on-fvp-in-gicv3-mode)
+8. [Preloaded BL33 alternative boot flow](#8--preloaded-bl33-alternative-boot-flow)
+9. [Preparing the images to run on FVP](#9--preparing-the-images-to-run-on-fvp)
+10. [Running the software on FVP](#10--running-the-software-on-fvp)
+11. [Running the software on Juno](#11--running-the-software-on-juno)
+12. [Changes required for booting Linux on FVP in GICv3 mode](#12--changes-required-for-booting-linux-on-fvp-in-gicv3-mode)
1. Introduction
@@ -407,6 +408,12 @@
payload. Please refer to the "Booting an EL3 payload" section for more
details.
+* `BL33_BASE`: This option enables booting a preloaded BL33 image instead of
+ the normal boot flow. When defined, it must specify the entry point address
+ for the preloaded BL33 image. This option is incompatible with
+ `EL3_PAYLOAD_BASE`. If both are defined, `EL3_PAYLOAD_BASE` has priority
+ over `BL33_BASE`.
+
* `PL011_GENERIC_UART`: Boolean option to indicate the PL011 driver that
the underlying hardware is not a full PL011 UART but a minimally compliant
generic UART, which is a subset of the PL011. The driver will not access
@@ -972,8 +979,56 @@
Alternatively, the same DS-5 command mentioned in the FVP section above can
be used to load the EL3 payload's ELF file over JTAG on Juno.
+
+8. Preloaded BL33 alternative boot flow
+----------------------------------------
+
+Some platforms have the ability to preload BL33 into memory instead of relying
+on Trusted Firmware to load it. This may simplify packaging of the normal world
+code and improve performance in a development environment. When secure world
+cold boot is complete, Trusted Firmware simply jumps to a BL33 base address
+provided at build time.
+
+For this option to be used, the `BL33_BASE` build option has to be used when
+compiling the Trusted Firmware. For example, the following command will create
+a FIP without a BL33 and prepare to jump to a BL33 image loaded at address
+0x80000000:
+
+ CROSS_COMPILE=<path-to>/bin/aarch64-linux-gnu- \
+ make BL33_BASE=0x80000000 PLAT=fvp all fip
+
+#### Boot of a preloaded bootwrapped kernel image on Base FVP
+
+The following example uses the AArch64 boot wrapper. This simplifies normal
+world booting while also making use of TF features. It can be obtained from its
+repository with:
+
+ git clone git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git
-8. Preparing the images to run on FVP
+After compiling it, an ELF file is generated. It can be loaded with the
+following command:
+
+ <path-to>/FVP_Base_AEMv8A-AEMv8A \
+ -C bp.secureflashloader.fname=bl1.bin \
+ -C bp.flashloader0.fname=fip.bin \
+ -a cluster0.cpu0=<bootwrapped-kernel.elf> \
+ --start cluster0.cpu0=0x0
+
+The `-a cluster0.cpu0=<bootwrapped-kernel.elf>` option loads the ELF file. It
+also sets the PC register to the ELF entry point address, which is not the
+desired behaviour, so the `--start cluster0.cpu0=0x0` option forces the PC back
+to 0x0 (the BL1 entry point address) on CPU #0. The `BL33_BASE` define used when
+compiling the FIP must match the ELF entry point.
+
+#### Boot of a preloaded bootwrapped kernel image on Juno
+
+The procedure to obtain and compile the boot wrapper is very similar to the case
+of the FVP. Once compiled, the `SPIN_ON_BL1_EXIT=1` loading method explained
+above in the EL3 payload boot flow section may be used to load the ELF file over
+JTAG on Juno.
+
+
+9. Preparing the images to run on FVP
--------------------------------------
Note: This section can be ignored when booting an EL3 payload, as no Flattened
@@ -1026,8 +1081,8 @@
which the FVP is launched. Alternatively a symbolic link may be used.
-9. Running the software on FVP
--------------------------------
+10. Running the software on FVP
+--------------------------------
This version of the ARM Trusted Firmware has been tested on the following ARM
FVPs (64-bit versions only).
@@ -1326,7 +1381,7 @@
detect the legacy VE memory map while configuring the GIC.
-10. Running the software on Juno
+11. Running the software on Juno
---------------------------------
This version of the ARM Trusted Firmware has been tested on Juno r0 and Juno r1.
@@ -1408,7 +1463,7 @@
wakeup interrupt from RTC.
-11. Changes required for booting Linux on FVP in GICv3 mode
+12. Changes required for booting Linux on FVP in GICv3 mode
------------------------------------------------------------
In case the TF FVP port is built with the build option