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 [2026/07/13 13:52] (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 54: | Line 54: | ||
| == Step 2.2. Fetch the NXP IMX proprietary firmware == | == Step 2.2. Fetch the NXP IMX proprietary firmware == | ||
| - | You must download both [[https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.22.bin|firmware-imx-8.22.bin]] and [[https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-sentinel-0.11.bin|firmware-sentinel-0.11.bin]] (URLs are taken from Yocto recipes) and download the self-extracting archives. | + | NXP releases its proprietary IMX firmware on its [[https://www.nxp.com/design/design-center/software/embedded-software/i-mx-software/embedded-linux-for-i-mx-applications-processors:IMXLINUX|software design documentation website]] (download the latest release's '' i.MX Linux Release Notes'' PDF document; the actual firmware download URLs are provided in there). |
| + | |||
| + | Download both [[https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.32-1991416.bin|firmware-imx-8.32.bin]] and [[https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-sentinel-0.11.bin|firmware-sentinel-0.11.bin]] (URLs are taken from Yocto recipes) and download the self-extracting archives. | ||
| Run the binaries and accept the license agreement in order for it to extract its contents | Run the binaries and accept the license agreement in order for it to extract its contents | ||
| Line 62: | Line 64: | ||
| <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 85: | Line 87: | ||
| The more astute will notice that, **once again**, we're not using the [[https://github.com/u-boot/u-boot|official U-Boot]] project, but instead NXP (i.e. the board's manufacturer) fork. | The more astute will notice that, **once again**, we're not using the [[https://github.com/u-boot/u-boot|official U-Boot]] project, but instead NXP (i.e. the board's manufacturer) fork. | ||
| - | The FRDM-IMX93 board has been published in mainline, though. And it works! But we want //"advanced"// features (like USB mass storage support) which is yet to be supported. And we'll still need to patch the NXP fork... | + | Fhe FRDM-IMX93 board has been published in mainline and it works perfectly as of 2026 (including USB support!) |
| + | Feel free to try it out, though your current defconfig and DTB path might be wrong (due to differing official naming schemes)! | ||
| </note> | </note> | ||
| == Step 2.3. Downloading & patching U-Boot source code == | == Step 2.3. Downloading & patching U-Boot source code == | ||
| - | Clone this repo using git: [[https://github.com/nxp-imx/uboot-imx|The NXP iMX U-Boot fork]] (**obligatory: clone the ''lf_v2024.04'' branch!** you can use [[https://git-scm.com/docs/git-checkout|git checkout]] to change branch afterwards). | + | Clone this repo using git: [[https://github.com/nxp-imx/uboot-imx|The NXP iMX U-Boot fork]] (**obligatory: clone the ''lf_v2026.04'' branch!** you can use [[https://git-scm.com/docs/git-checkout|git checkout]] to change branch afterwards). |
| - | Unfortunately, especially when using NXP's official U-Boot, our FRDM board is **not supported**! We'll need to download yet another thing (a patch) from NXP's Yocto source code: [[https://github.com/nxp-imx-support/meta-imx-frdm/blob/lf-6.6.36-2.1.0/meta-imx-bsp/recipes-bsp/u-boot/u-boot-imx/0002-imx-imx93_frdm-Add-basic-board-support.patch]]. | + | Fortunately, ''v2026.04'' has recently added support for our FRDM-IMX93 board ([[https://github.com/nxp-imx/uboot-imx/commit/ab870ad9a92b4d367ae80489a4421b820ba9942b|check out the commit]]), so we won't need to patch anything ;) |
| - | + | ||
| - | Save the file to ''u-boot''`s source directory and apply it using: | + | |
| - | + | ||
| - | <code bash> | + | |
| - | # the -p1 argument is required to strip out the first path component | + | |
| - | # (which is a/b if you manually inspect the patch) | + | |
| - | patch -p1 < 0002-imx-imx93_frdm-Add-basic-board-support.patch | + | |
| - | </code> | + | |
| - | + | ||
| - | If the patch fails some hunks, it's your fault :P (you haven't checked out the correct git branch as mentioned above). | + | |
| == Step 2.4. Configure U-Boot == | == Step 2.4. Configure U-Boot == | ||
| Line 164: | Line 157: | ||
| </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 172: | ||
| **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 ''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!). | + | 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=...` | ||