Commit 32412a8a authored by Antonio Nino Diaz's avatar Antonio Nino Diaz
Browse files

Replace bootwrapped kernel instructions from User Guide



The instructions to boot the bootwrapped kernel were outdated.

Also, the bootwrapped kernel boot flow isn't really useful. It was meant
to be a replacement for the Trusted Firmware-A, not to be used as the next
step during boot.

The instructions have been removed in favour of the new build option
ARM_LINUX_KERNEL_AS_BL33. This new system directly boots the Linux
kernel from BL31, and requires RESET_TO_BL31 to be 1. Also, the kernel
has to be preloaded in memory, so PRELOADED_BL33_BASE has to be set to its
address. This way, the runtime services of the Trusted Firmware-A are
available for the kernel in the least possible amount of time.

This new system requires the DTB to be patched so that the kernel knows
where the ramdisk is. A short script to add this information to the DTB
has been added to the User Guide. The information related to it can be
found in the following file in the Linux kernel tree:
``Documentation/devicetree/bindings/chosen.txt``

Change-Id: Ide135580959e09f6aa8e4425f37ea55d97439178
Signed-off-by: default avatarAntonio Nino Diaz <antonio.ninodiaz@arm.com>
parent b726c169
...@@ -1484,41 +1484,92 @@ without a BL33 and prepare to jump to a BL33 image loaded at address ...@@ -1484,41 +1484,92 @@ without a BL33 and prepare to jump to a BL33 image loaded at address
make PRELOADED_BL33_BASE=0x80000000 PLAT=fvp all fip make PRELOADED_BL33_BASE=0x80000000 PLAT=fvp all fip
Boot of a preloaded bootwrapped kernel image on Base FVP Boot of a preloaded kernel image on Base FVP
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following example uses the AArch64 boot wrapper. This simplifies normal The following example uses a simplified boot flow by directly jumping from the
world booting while also making use of TF-A features. It can be obtained from TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
its repository with: useful if both the kernel and the device tree blob (DTB) are already present in
memory (like in FVP).
:: For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
address ``0x82000000``, the firmware can be built like this:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git ::
After compiling it, an ELF file is generated. It can be loaded with the CROSS_COMPILE=aarch64-linux-gnu- \
following command: make PLAT=fvp DEBUG=1 \
RESET_TO_BL31=1 \
ARM_LINUX_KERNEL_AS_BL33=1 \
PRELOADED_BL33_BASE=0x80080000 \
ARM_PRELOADED_DTB_BASE=0x82000000 \
all fip
Now, it is needed to modify the DTB so that the kernel knows the address of the
ramdisk. The following script generates a patched DTB from the provided one,
assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
script assumes that the user is using a ramdisk image prepared for U-Boot, like
the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
offset in ``INITRD_START`` has to be removed.
.. code:: bash
#!/bin/bash
# Path to the input DTB
KERNEL_DTB=<path-to>/<fdt>
# Path to the output DTB
PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
# Base address of the ramdisk
INITRD_BASE=0x84000000
# Path to the ramdisk
INITRD=<path-to>/<ramdisk.img>
# Skip uboot header (64 bytes)
INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
INITRD_SIZE=$(stat -Lc %s ${INITRD})
INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
CHOSEN_NODE=$(echo \
"/ { \
chosen { \
linux,initrd-start = <${INITRD_START}>; \
linux,initrd-end = <${INITRD_END}>; \
}; \
};")
echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} | \
dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
And the FVP binary can be run with the following command:
:: ::
<path-to>/FVP_Base_AEMv8A-AEMv8A \ <path-to>/FVP_Base_AEMv8A-AEMv8A \
-C bp.secureflashloader.fname=bl1.bin \ -C pctl.startup=0.0.0.0 \
-C bp.flashloader0.fname=fip.bin \ -C bp.secure_memory=1 \
-a cluster0.cpu0=<bootwrapped-kernel.elf> \ -C cluster0.NUM_CORES=4 \
--start cluster0.cpu0=0x0 -C cluster1.NUM_CORES=4 \
-C cache_state_modelled=1 \
The ``-a cluster0.cpu0=<bootwrapped-kernel.elf>`` option loads the ELF file. It -C cluster0.cpu0.RVBAR=0x04020000 \
also sets the PC register to the ELF entry point address, which is not the -C cluster0.cpu1.RVBAR=0x04020000 \
desired behaviour, so the ``--start cluster0.cpu0=0x0`` option forces the PC back -C cluster0.cpu2.RVBAR=0x04020000 \
to 0x0 (the BL1 entry point address) on CPU #0. The ``PRELOADED_BL33_BASE`` define -C cluster0.cpu3.RVBAR=0x04020000 \
used when compiling the FIP must match the ELF entry point. -C cluster1.cpu0.RVBAR=0x04020000 \
-C cluster1.cpu1.RVBAR=0x04020000 \
Boot of a preloaded bootwrapped kernel image on Juno -C cluster1.cpu2.RVBAR=0x04020000 \
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -C cluster1.cpu3.RVBAR=0x04020000 \
--data cluster0.cpu0="<path-to>/bl31.bin"@0x04020000 \
The procedure to obtain and compile the boot wrapper is very similar to the case --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000 \
of the FVP. The execution must be stopped at the end of bl2\_main(), and the --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
loading method explained above in the EL3 payload boot flow section may be used --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
to load the ELF file over JTAG on Juno.
Boot of a preloaded kernel image on Juno
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Trusted Firmware must be compiled in a similar way as for FVP explained
above. The process to load binaries to memory is the one explained in
`Booting an EL3 payload on Juno`_.
Running the software on FVP Running the software on FVP
--------------------------- ---------------------------
......
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