This shows you the differences between two versions of the page.
ass:labs-2025:01:tasks:02 [2025/08/03 16:59] florin.stancu created |
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 59: | Line 59: | ||
(oh, and since we're on Linux, don't forget to apply to executable bit -- ''chmod +x <filename>''). | (oh, and since we're on Linux, don't forget to apply to executable bit -- ''chmod +x <filename>''). | ||
- | What we're actually interested in are the following files (find them and put them inside your own ''firmware-files''' directory, we'll make use of them later): | + | What we're actually interested in are the following files (find them and put them inside your own ''artifacts'' directory, we'll make use of them later): |
<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 147: | Line 147: | ||
* ''arch/arm/dts/imx93-11x11-frdm.dtb'': a Device Tree Blob (DTB) which we'll also require -- see below. | * ''arch/arm/dts/imx93-11x11-frdm.dtb'': a Device Tree Blob (DTB) which we'll also require -- see below. | ||
- | Copy them all inside your //special// ''firmware-files'' directory (which you created earlier, right?). | + | Copy them all inside your //special// ''artifacts'' directory (which you created earlier, right?). |
<note> | <note> | ||
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. | + | |
+ | 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 ''firmware-files'' 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!). | + | 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=...` |