1 .. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
10 Texas Instrument's K3 family of SoCs utilize a heterogeneous multicore
11 and highly integrated device architecture targeted to maximize
12 performance and power efficiency for a wide range of industrial,
13 automotive and other broad market segments.
15 Typically the processing cores and the peripherals for these devices are
16 partitioned into three functional domains to provide ultra-low power
17 modes as well as accommodating application and industrial safety systems
18 on the same SoC. These functional domains are typically called the:
20 * Wakeup (WKUP) domain
21 * Micro-controller (MCU) domain
24 For a more detailed view of what peripherals are attached to each
25 domain, consult the device specific documentation.
34 ../toradex/verdin-am62
42 For all K3 SoCs the first core started will be inside the Security
43 Management Subsystem (SMS) which will secure the device and start a core
44 in the wakeup domain to run the ROM code. ROM will then initialize the
45 boot media needed to load the binaries packaged inside `tiboot3.bin`,
46 including a 32bit U-Boot SPL, (called the wakup SPL) that ROM will jump
47 to after it has finished loading everything into internal SRAM.
49 .. image:: img/boot_flow_01.svg
51 The wakeup SPL, running on a wakeup domain core, will initialize DDR and
52 any peripherals needed load the larger binaries inside the `tispl.bin`
53 into DDR. Once loaded the wakeup SPL will start one of the 'big'
54 application cores inside the main domain to initialize the main domain,
55 starting with Trusted Firmware-A (TF-A), before moving on to start
56 OP-TEE and the main domain's U-Boot SPL.
58 .. image:: img/boot_flow_02.svg
60 The main domain's SPL, running on a 64bit application core, has
61 virtually unlimited space (billions of bytes now that DDR is working) to
62 initialize even more peripherals needed to load in the `u-boot.img`
63 which loads more firmware into the micro-controller & wakeup domains and
64 finally prepare the main domain to run Linux.
66 .. image:: img/boot_flow_03.svg
68 This is the typical boot flow for all K3 based SoCs, however this flow
69 offers quite a lot in the terms of flexibility, especially on High
75 All K3 SoCs will generally use the above boot flow with two main
76 differences depending on the capabilities of the boot ROM and the number
77 of cores inside the device. These differences split the bootflow into
78 essentially 4 unique but very similar flows:
80 * Split binary with a combined firmware: (eg: AM65)
81 * Combined binary with a combined firmware: (eg: AM64)
82 * Split binary with a split firmware: (eg: J721E)
83 * Combined binary with a split firmware: (eg: AM62)
85 For devices that utilize the split binary approach, ROM is not capable
86 of loading the firmware into the SoC requiring the wakeup domain's
87 U-Boot SPL to load the firmware.
89 Devices with a split firmware will have two firmwares loaded into the
90 device at different times during the bootup process. TI's Foundational
91 Security (TIFS), needed to operate the Security Management Subsystem,
92 will either be loaded by ROM or the WKUP U-Boot SPL, then once the
93 wakeup U-Boot SPL has completed, the second Device Management (DM)
94 firmware can be loaded on the now free core in the wakeup domain.
96 For more information on the bootup process of your SoC, consult the
97 device specific boot flow documentation.
102 All scripts and code needed to build the `tiboot3.bin`, `tispl.bin` and
103 `u-boot.img` for all K3 SoCs can be located at the following places
106 .. k3_rst_include_start_boot_sources
110 | **source:** https://source.denx.de/u-boot/u-boot.git
113 * **Trusted Firmware-A (TF-A)**
115 | **source:** https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/
118 * **Open Portable Trusted Execution Environment (OP-TEE)**
120 | **source:** https://github.com/OP-TEE/optee_os.git
123 * **TI Firmware (TIFS, DM, DSMC)**
125 | **source:** https://git.ti.com/git/processor-firmware/ti-linux-firmware.git
126 | **branch:** ti-linux-firmware
128 .. k3_rst_include_end_boot_sources
133 Depending on the specifics of your device, you will need three or more
134 binaries to boot your SoC.
136 * `tiboot3.bin` (bootloader for the wakeup domain)
137 * `tispl.bin` (bootloader for the main domain)
140 During the bootup process, both the 32bit wakeup domain and the 64bit
141 main domains will be involved. This means everything inside the
142 `tiboot3.bin` running in the wakeup domain will need to be compiled for
143 32bit cores and most binaries in the `tispl.bin` will need to be
144 compiled for 64bit main domain CPU cores.
146 All of that to say you will need both a 32bit and 64bit cross compiler
147 (assuming you're using an x86 desktop)
149 .. k3_rst_include_start_common_env_vars_desc
150 .. list-table:: Generic environment variables
159 - Cross compiler for ARMv7 (ARM 32bit), typically arm-linux-gnueabihf-
162 - Cross compiler for ARMv8 (ARM 64bit), typically aarch64-linux-gnu-
165 - Path to TI Linux firmware repository
168 - Path to source of Trusted Firmware-A
171 - Path to source of OP-TEE
172 .. k3_rst_include_end_common_env_vars_desc
174 .. k3_rst_include_start_common_env_vars_defn
177 $ export CC32=arm-linux-gnueabihf-
178 $ export CC64=aarch64-linux-gnu-
179 $ export LNX_FW_PATH=path/to/ti-linux-firmware
180 $ export TFA_PATH=path/to/trusted-firmware-a
181 $ export OPTEE_PATH=path/to/optee_os
182 .. k3_rst_include_end_common_env_vars_defn
184 We will also need some common environment variables set up for the various
185 other build sources. we shall use the following, in the build descriptions below:
187 .. k3_rst_include_start_board_env_vars_desc
188 .. list-table:: Board specific environment variables
197 - Defconfig for Cortex-R (Boot processor).
200 - Defconfig for Cortex-A (MPU processor).
201 * - Trusted Firmware-A
203 - Platform name used for building TF-A for Cortex-A Processor.
204 * - Trusted Firmware-A
206 - Any extra arguments used for building TF-A.
209 - Platform name used for building OP-TEE for Cortex-A Processor.
212 - Any extra arguments used for building OP-TEE.
213 .. k3_rst_include_end_board_env_vars_desc
216 ^^^^^^^^^^^^^^^^^^^^^
218 1. To generate the U-Boot SPL for the wakeup domain, use the following
219 commands, substituting :code:`{SOC}` for the name of your device (eg:
220 am62x) to package the various firmware and the wakeup UBoot SPL into
221 the final `tiboot3.bin` binary. (or the `sysfw.itb` if your device
222 uses the split binary flow)
224 .. k3_rst_include_start_build_steps_spl_r5
227 $ # inside u-boot source
228 $ make $UBOOT_CFG_CORTEXR
229 $ make CROSS_COMPILE=$CC32 BINMAN_INDIRS=$LNX_FW_PATH
230 .. k3_rst_include_end_build_steps_spl_r5
232 At this point you should have all the needed binaries to boot the wakeup
233 domain of your K3 SoC.
235 **Combined Binary Boot Flow** (eg: am62x, am64x, ... )
237 `tiboot3-{SOC}-{gp/hs-fs/hs}.bin`
239 **Split Binary Boot Flow** (eg: j721e, am65x)
241 | `tiboot3-{SOC}-{gp/hs-fs/hs}.bin`
242 | `sysfw-{SOC}-{gp/hs-fs/hs}-evm.itb`
246 It's important to rename the generated `tiboot3.bin` and `sysfw.itb`
247 to match exactly `tiboot3.bin` and `sysfw.itb` as ROM and the wakeup
248 UBoot SPL will only look for and load the files with these names.
253 The `tispl.bin` is a standard fitImage combining the firmware need for
254 the main domain to function properly as well as Device Management (DM)
255 firmware if your device using a split firmware.
257 2. We will first need TF-A, as it's the first thing to run on the 'big'
258 application cores on the main domain.
260 .. k3_rst_include_start_build_steps_tfa
263 $ # inside trusted-firmware-a source
264 $ make CROSS_COMPILE=$CC64 ARCH=aarch64 PLAT=k3 SPD=opteed $TFA_EXTRA_ARGS \
265 TARGET_BOARD=$TFA_BOARD
266 .. k3_rst_include_end_build_steps_tfa
268 Typically all `j7*` devices will use `TARGET_BOARD=generic` or `TARGET_BOARD
269 =j784s4` (if it is a J784S4 device), while typical Sitara (`am6*`) devices
270 use the `lite` option.
272 3. The Open Portable Trusted Execution Environment (OP-TEE) is designed
273 to run as a companion to a non-secure Linux kernel for Cortex-A cores
274 using the TrustZone technology built into the core.
276 .. k3_rst_include_start_build_steps_optee
279 $ # inside optee_os source
280 $ make CROSS_COMPILE=$CC32 CROSS_COMPILE64=$CC64 CFG_ARM64_core=y $OPTEE_EXTRA_ARGS \
281 PLATFORM=$OPTEE_PLATFORM
282 .. k3_rst_include_end_build_steps_optee
284 4. Finally, after TF-A has initialized the main domain and OP-TEE has
285 finished, we can jump back into U-Boot again, this time running on a
286 64bit core in the main domain.
288 .. k3_rst_include_start_build_steps_uboot
291 $ # inside u-boot source
292 $ make $UBOOT_CFG_CORTEXA
293 $ make CROSS_COMPILE=$CC64 BINMAN_INDIRS=$LNX_FW_PATH \
294 BL31=$TFA_PATH/build/k3/$TFA_BOARD/release/bl31.bin \
295 TEE=$OPTEE_PATH/out/arm-plat-k3/core/tee-raw.bin
296 .. k3_rst_include_end_build_steps_uboot
298 At this point you should have every binary needed initialize both the
299 wakeup and main domain and to boot to the U-Boot prompt
301 **Main Domain Bootloader**
303 | `tispl.bin` for HS devices or `tispl.bin_unsigned` for GP devices
304 | `u-boot.img` for HS devices or `u-boot.img_unsigned` for GP devices
306 Fit Signature Signing
307 ---------------------
309 K3 Platforms have fit signature signing enabled by default on their primary
310 platforms. Here we'll take an example for creating fit image for J721e platform
311 and the same can be extended to other platforms
313 1. Describing FIT source
320 description = "Kernel fitImage for j721e-hs-evm";
321 #address-cells = <1>;
325 description = "Linux kernel";
326 data = /incbin/("Image");
330 compression = "none";
332 entry = <0x80080000>;
338 fdt-ti_k3-j721e-common-proc-board.dtb {
339 description = "Flattened Device Tree blob";
340 data = /incbin/("k3-j721e-common-proc-board.dtb");
343 compression = "none";
353 default = "conf-ti_k3-j721e-common-proc-board.dtb";
354 conf-ti_k3-j721e-common-proc-board.dtb {
355 description = "Linux kernel, FDT blob";
356 fdt = "fdt-ti_k3-j721e-common-proc-board.dtb";
359 algo = "sha512,rsa4096";
360 key-name-hint = "custMpk";
361 sign-images = "kernel", "fdt";
367 You would require to change the '/incbin/' lines to point to the respective
368 files in your local machine and the key-name-hint also needs to be changed
369 if you are using some other key other than the TI dummy key that we are
370 using for this example.
372 2. Compile U-boot for the respective board
375 :start-after: .. k3_rst_include_start_build_steps_uboot
376 :end-before: .. k3_rst_include_end_build_steps_uboot
380 The changes only affect a72 binaries so the example just builds that
382 3. Sign the fit image and embed the dtb in uboot
384 Now once the build is done, you'll have a dtb for your board that you'll
385 be passing to mkimage for signing the fitImage and embedding the key in
390 mkimage -r -f fitImage.its -k $UBOOT_PATH/board/ti/keys -K
391 $UBOOT_PATH/build/a72/dts/dt.dtb
393 For signing a secondary platform, pass the -K parameter to that DTB
397 mkimage -f fitImage.its -k $UBOOT_PATH/board/ti/keys -K
398 $UBOOT_PATH/build/a72/arch/arm/dts/k3-j721e-sk.dtb
402 If changing `CONFIG_DEFAULT_DEVICE_TREE` to the secondary platform,
403 binman changes would also be required so that correct dtb gets packaged.
407 diff --git a/arch/arm/dts/k3-j721e-binman.dtsi b/arch/arm/dts/k3-j721e-binman.dtsi
408 index 673be646b1e3..752fa805fe8d 100644
409 --- a/arch/arm/dts/k3-j721e-binman.dtsi
410 +++ b/arch/arm/dts/k3-j721e-binman.dtsi
412 #define SPL_J721E_SK_DTB "spl/dts/k3-j721e-sk.dtb"
414 #define UBOOT_NODTB "u-boot-nodtb.bin"
415 -#define J721E_EVM_DTB "u-boot.dtb"
416 -#define J721E_SK_DTB "arch/arm/dts/k3-j721e-sk.dtb"
417 +#define J721E_EVM_DTB "arch/arm/dts/k3-j721e-common-proc-board.dtb"
418 +#define J721E_SK_DTB "u-boot.dtb"
422 This is required so that the modified dtb gets updated in u-boot.img
425 :start-after: .. k3_rst_include_start_build_steps_uboot
426 :end-before: .. k3_rst_include_end_build_steps_uboot
428 6. (Optional) Enabled FIT_SIGNATURE_ENFORCED
430 By default u-boot will boot up the fit image without any authentication as
431 such if the public key is not embedded properly, to check if the public key
432 nodes are proper you can enable FIT_SIGNATURE_ENFORCED that would not rely
433 on the dtb for anything else then the signature node for checking the fit
434 image, rest other things will be enforced such as the property of
435 required-keys. This is not an extensive check so do manual checks also
437 This is by default enabled for devices with TI_SECURE_DEVICE enabled.
441 The devices now also have distroboot enabled so if the fit image doesn't
442 work then the fallback to normal distroboot will be there on hs devices,
443 this will need to be explicitly disabled by changing the boot_targets.
448 SAVEENV is disabled by default and for the new flow uses Uenv.txt as the default
449 way for saving the environments. This has been done as Uenv.txt is more granular
450 then the saveenv command and can be used across various bootmodes too.
452 **Writing to MMC/EMMC**
456 => env export -t $loadaddr <list of variables>
457 => fatwrite mmc ${mmcdev} ${loadaddr} ${bootenvfile} ${filesize}
459 **Reading from MMC/EMMC**
461 By default run envboot will read it from the MMC/EMMC partition ( based on
462 mmcdev) and set the environments.
464 If manually needs to be done then the environment can be read from the
465 filesystem and then imported
469 => fatload mmc ${mmcdev} ${loadaddr} ${bootenvfile}
470 => env import -t ${loadaddr} ${filesize}