This shows you the differences between two versions of the page.
ass:labs-2025:01:tasks:02 [2025/08/04 11:32] florin.stancu |
ass:labs-2025:01:tasks:02 [2025/08/04 19:51] (current) florin.stancu |
||
---|---|---|---|
Line 1: | Line 1: | ||
==== 02. Creating the Firmware Image Package ==== | ==== 02. Creating the Firmware Image Package ==== | ||
- | This package will contain **BL2** (U-Boot SPL), **BL31** (ATF-A) and **BL33** (fully-featured U-Boot) and some proprietary firmware (//yikes!//). The Secure OS (**BL32**) is outside the scope of this lab; even if we did bother to include it, it would just //be there//, doing nothing. | + | This package will contain **BL2** (U-Boot SPL), **BL31** (ARM Trusted Firmware) and **BL33** (normal/full U-Boot) and some proprietary firmware (//yikes!//). The Secure OS (**BL32**) is outside the scope of this lab; even if we did bother to include it, it would just //be there//, doing nothing. |
Following this exercise, we should be able to reach the first step of the booting sequence that //can// be interactive; meaning that we'll be able to interact with a shell implemented in U-Boot! | Following this exercise, we should be able to reach the first step of the booting sequence that //can// be interactive; meaning that we'll be able to interact with a shell implemented in U-Boot! | ||
Line 24: | Line 24: | ||
== Step 2.1. Build ARM Trusted Firmware-A (ATF / TF-A) == | == Step 2.1. Build ARM Trusted Firmware-A (ATF / TF-A) == | ||
- | |||
- | Following a successful build process, you should obtain a **bl31.bin** file (take note if its location, for you will need it later). | ||
<note tip> | <note tip> | ||
Line 38: | Line 36: | ||
If you're still having problems, you can also read the [[https://docs.u-boot.org/en/latest/board/nxp/imx93_frdm.html|u-boot mainline steps for FRDM iMX93]]. | If you're still having problems, you can also read the [[https://docs.u-boot.org/en/latest/board/nxp/imx93_frdm.html|u-boot mainline steps for FRDM iMX93]]. | ||
+ | |||
+ | Following a successful build process, you should obtain a **bl31.bin** file (take note if its location (use ''find'' to find it if lost) and copy it to your ''artifacts/'' dir, for you will need it later). | ||
=== The iMX proprietary firmware === | === The iMX proprietary firmware === | ||
Line 62: | Line 62: | ||
<code bash> | <code bash> | ||
- | # from the firmware-imx: | + | # from the firmware-imx (8 files!): |
- | lpddr4_imem_1d_v202201.bin lpddr4_dmem_1d_v202201.bin | + | lpddr4_imem_1d_v202201.bin lpddr4_dmem_1d_v202201.bin |
- | lpddr4_imem_2d_v202201.bin lpddr4_dmem_2d_v202201.bin | + | lpddr4_imem_2d_v202201.bin lpddr4_dmem_2d_v202201.bin |
- | lpddr4_pmu_train_1d_dmem.binlpddr4_pmu_train_1d_imem.bin | + | lpddr4_pmu_train_1d_dmem.bin lpddr4_pmu_train_1d_imem.bin |
- | lpddr4_pmu_train_2d_dmem.bin lpddr4_pmu_train_2d_imem.bin | + | lpddr4_pmu_train_2d_dmem.bin lpddr4_pmu_train_2d_imem.bin |
- | # and this is from firmware-sentinel: | + | # and this is from firmware-sentinel (just 1 req., fortunately): |
mx93a1-ahab-container.img | mx93a1-ahab-container.img | ||
</code> | </code> | ||
Line 164: | Line 164: | ||
</note> | </note> | ||
- | === Step 2.4. Generate the firmware package === | + | === The Firmware Image Package === |
Now that we have all necessary binaries either downloaded or compiled ourselves, all that is left is to combine them in a manner that can be understood by the processor's first boot stage (**BL1** -- inside ROM memory). | Now that we have all necessary binaries either downloaded or compiled ourselves, all that is left is to combine them in a manner that can be understood by the processor's first boot stage (**BL1** -- inside ROM memory). | ||
+ | |||
+ | The format is specific to each model and is usually described inside the chip's [[https://www.nxp.com/webapp/Download?colCode=IMX93RM|Technical Reference Manual]] (note: requires sign in!). | ||
+ | |||
+ | {{ :ass:labs-2025:01:imx93_firm_image_format.png?600 |}} | ||
+ | |||
+ | |||
+ | In order to generate a binary image file in this format, we must use a specific tool ofc. | ||
Since 2022, U-Boot's tool of choice for this task is [[https://u-boot.readthedocs.io/en/latest/develop/package/binman.html|binman]]. This tool uses a platform-specific config file that specifies what components should be included and where they should be placed in memory. For our platform (i.e.: i.MX93) this file would be ''arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi''. | Since 2022, U-Boot's tool of choice for this task is [[https://u-boot.readthedocs.io/en/latest/develop/package/binman.html|binman]]. This tool uses a platform-specific config file that specifies what components should be included and where they should be placed in memory. For our platform (i.e.: i.MX93) this file would be ''arch/arm/dts/imx93-11x11-frdm-u-boot.dtsi''. | ||
Line 172: | Line 179: | ||
**However**, since the U-Boot version that we are using is older and the board manufacturer did not add proper support for binman, **we are going to use the older method**, based on [[https://linux.die.net/man/1/mkimage|mkimage]] (part of the U-Boot repo or as a package on most distros). In order to spare ourselves some pain, we are going to use NXP's [[https://github.com/nxp-imx/imx-mkimage/|imx-mkimage]] implementation which knows the proper offsets where the images should be loaded... but beware: it's not very pretty to use! | **However**, since the U-Boot version that we are using is older and the board manufacturer did not add proper support for binman, **we are going to use the older method**, based on [[https://linux.die.net/man/1/mkimage|mkimage]] (part of the U-Boot repo or as a package on most distros). In order to spare ourselves some pain, we are going to use NXP's [[https://github.com/nxp-imx/imx-mkimage/|imx-mkimage]] implementation which knows the proper offsets where the images should be loaded... but beware: it's not very pretty to use! | ||
- | So clone the ''imx-mkimage'' folder and navigate to it! | + | === Step 2.6. Generate flash.bin (the FIP) === |
- | In their source tree you will find a number of subdirectories corresponding to different versions of the i.MX platform. Select the one which corresponds to our board. | + | |
- | When you get there (that is, inside the ''iMX93'' subdirectory), you will have to copy all the ''artifacts'' you compiled so far + the ones downloaded/extracted from proprietary firmware archive (trust us here: **make a script to do all this automatically**! you'll need to do it tens -- probably hundreds -- of times!). | + | Clone the ''imx-mkimage'' project from git and ''cd'' to it! |
+ | In their source tree you will find a number of subdirectories corresponding to different versions of the i.MX platform. Select the one which corresponds to our board: | ||
+ | |||
+ | <code> | ||
+ | imx-mkimage | ||
+ | ├── iMX8DXL | ||
+ | ├── iMX8M | ||
+ | ├── iMX8QM | ||
+ | ├── iMX8QX | ||
+ | ├── iMX8ULP | ||
+ | ├── iMX91 | ||
+ | ├── iMX93 | ||
+ | ├── iMX94 | ||
+ | ├── iMX95 | ||
+ | ├── scripts | ||
+ | └── src | ||
+ | </code> | ||
+ | |||
+ | When you get there (that is, inside the ''iMX93'' subdirectory), you will have to copy all the ''artifacts'' (remember we had you manage them all inside a new folder?) you compiled so far + the ones downloaded/extracted from proprietary firmware archive (trust us here: **make a script/Makefile goal to do all this automatically**! you'll need to do it tens -- probably hundreds -- of times!). | ||
In addition to these, you will have to copy the base **mkimage** tool generated in the U-Boot directory, see if you can ''find'' it '';)'' you must rename it as **mkimage_uboot** inside the ''iMX93'' subdirectory. | In addition to these, you will have to copy the base **mkimage** tool generated in the U-Boot directory, see if you can ''find'' it '';)'' you must rename it as **mkimage_uboot** inside the ''iMX93'' subdirectory. | ||
- | Once you have all these (see below), run make **in the parent directory** (check and see where it has that Makefile!) with the ''flash_singleboot'' target, while specifying the platform in the ''SOC=iMX93'' argument (note that cASE!), and the name of the DTB copied over from U-Boot in the ''dtbs='' argument. The output firmware image should be called **flash.bin**. Here's the final contents of the directory: | + | Once you have all these (see below), run ''make'' **in the parent directory of imx-mkimage** (check and see where it has that Makefile!) with the ''flash_singleboot'' target, while specifying the platform in the ''SOC=iMX93'' argument (note that cASE!), and the name of the DTB copied over from U-Boot in the ''dtbs='' argument. The output firmware image should be called **flash.bin**. Here's the final contents of the directory: |
<code> | <code> | ||
imx-mkimage/iMX93 | imx-mkimage/iMX93 | ||
- | ├── bl31.bin # generated, we don't care | + | ├── bl31.bin # ARM Trusted Firmware |
├── boot-spl-container.img # also generated | ├── boot-spl-container.img # also generated | ||
├── flash.bin # generated by `make SOC=... dtbs=...` | ├── flash.bin # generated by `make SOC=... dtbs=...` | ||
Line 221: | Line 245: | ||
The last two sub-tasks demonstrate that the DTB format is very versatile. On one hand, it is used to describe the available hardware to the Linux kernel. On the other hand, image packaging tools rely on them to determine the layout of different binaries in memory. | The last two sub-tasks demonstrate that the DTB format is very versatile. On one hand, it is used to describe the available hardware to the Linux kernel. On the other hand, image packaging tools rely on them to determine the layout of different binaries in memory. | ||
</note> | </note> | ||
+ | |||