Honeycomb-lx2k - Replacing the bootloader
Tags: aarch64, gentoo, linux
Published: 2020-07-09 11:42:24

I saw some interesting changes for u-boot landing in the [image-builder](https://github.com/SolidRun/lx2160a_build) [SolidRun](https://github.com/SolidRun) provides and almost coincidentally their customer service replied to my initial inquiry about the booting process.

That lead to some more tries and testing, I had yet to see if there is a linux kernel update that makes rebooting work as should, but at least now I know that the problem is just software.

Since I do not want to wipe the eMMC image all the time I asked them directions on how to just update the bootloader and they provided me with enough directions.

Since it isn't yet trivial to get the sources in the right shape here a short blogpost about it.

## Getting the sources
Our point of truth is again the [image-builder](https://github.com/SolidRun/lx2160a_build) since it contains the patches and how to apply them.
I'm using Gentoo so I just read the `runme.sh` and adapt it.
I want to use `u-boot`, the boot image is of the `Trusted Firmware-A` kind, so I need to fetch `aft` to assemble the whole thing and `rcw` to build the Pre-Boot Loader initialization code.

``` sh
cd /usr/src
# Get the build script and the patchsets
git clone https://github.com/SolidRun/lx2160a_build
# u-boot as the main bootloader
git clone https://source.codeaurora.org/external/qoriq/qoriq-components/u-boot
# trusted firmware builder
git clone https://source.codeaurora.org/external/qoriq/qoriq-components/atf
# pre-boot initialization compiler
git clone https://source.codeaurora.org/external/qoriq/qoriq-components/rcw
```
### Patches
There are plenty and they apply on specific tags, I'm using `LSDK-20.04` as base.
The patches could live in `patches/<tool name>` or `patches/<tool-name>-<tag>`.

``` sh
for a in rcw u-boot; do
    pushd $a
    git checkout -b LSDK-20.04 refs/tags/LSDK-20.04
    git am ../lx2160a_build/patches/$a-LSDK-20.04/*
    popd
done
pushd aft
git checkout -b LSDK-20.04 refs/tags/LSDK-20.04
git am ../lx2160a_build/patches/aft/*
popd
```
### Binary blobs
The script fetches and uses some binary blobs 
```
cd aft/tools/fiptool/
git clone https://github.com/NXP/ddr-phy-binary.git
make
./fiptool create --ddr-immem-udimm-1d ddr-phy-binary/lx2160a/ddr4_pmu_train_imem.bin --ddr-immem-udimm-2d ddr-phy-binary/lx2160a/ddr4_2d_pmu_train_imem.bin --ddr-dmmem-udimm-1d ddr-phy-binary/lx2160a/ddr4_pmu_train_dmem.bin --ddr-dmmem-udimm-2d ddr-phy-binary/lx2160a/ddr4_2d_pmu_train_dmem.bin --ddr-immem-rdimm-1d ddr-phy-binary/lx2160a/ddr4_rdimm_pmu_train_imem.bin --ddr-immem-rdimm-2d ddr-phy-binary/lx2160a/ddr4_rdimm2d_pmu_train_imem.bin --ddr-dmmem-rdimm-1d ddr-phy-binary/lx2160a/ddr4_rdimm_pmu_train_dmem.bin --ddr-dmmem-rdimm-2d ddr-phy-binary/lx2160a/ddr4_rdimm2d_pmu_train_dmem.bin fip_ddr_all.bin
```

## Building
We need to build `u-boot` and the `rcw` images first and then put everything together with atf.

### u-boot
``` sh
pushd u-boot
make lx2160acex7_tfa_defconfig
make -j16
export BL33=$PWD/u-boot.bin
popd
```

> **Note**: if you are using gcc-10, you should apply a patch on top of the set
``` diff
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index fd825ebba6..24af549977 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -38,7 +38,6 @@ LINECOMMENT   "//".*\n
 #include "srcpos.h"
 #include "dtc-parser.tab.h"

-YYLTYPE yylloc;
 extern bool treesource_error;

 /* CAUTION: this will stop working if we ever use yyless() or yyunput() */
```




### rcw
``` sh
# Set the configuration for your memory timings and the SERDES configuration for your networking
# Options at hand
# DDR_SPEED=2400,2600,2900,3200
export DDR_SPEED=${DDR_SPEED:-3200}
# SERDES=8_5_2, 13_5_2, 20_5_2
export SERDES=${SERDES:-8_5_2}

export SPEED=2000_700_${DDR_SPEED}
pushd rcw/lx2160acex7
mkdir -p RCW
echo "#include <configs/lx2160a_defaults.rcwi>" > RCW/template.rcw
echo "#include <configs/lx2160a_${SPEED}.rcwi>" >> RCW/template.rcw
echo "#include <configs/lx2160a_${SERDES}.rcwi>" >> RCW/template.rcw
make clean
make -j 16
popd
```

Once those two componets are built we assemble everything in our image
``` sh
pushd atf
make PLAT=lx2160acex7 clean
make -j16 PLAT=lx2160acex7 all fip pbl RCW=../rcw/lx2160acex7/RCW/template.bin TRUSTED_BOARD_BOOT=0 GENERATE_COT=0 BOOT_MODE=auto SECURE_BOOT=false
```

In `build/lx2160acex7/release/fip.bin` we have our final product if everything went well.

## Flashing
The process itself is quite simple, you copy with dd the image to an offset of your boot device (either the eMMC `/dev/mmcblk1` or the SD `/dev/mmcblk0`).

> **Note**: just in case you might back up the firmware
``` sh
dd if=/dev/mmcblk0 of=backup-fip.bin  bs=512 seek=2048 conv=notrunc
```

And then overwrite it
``` sh
dd if=build/lx2160acex7/release/fip.bin of=/dev/mmcblk0 bs=512 seek=2048 conv=notrunc
```

Once you reboot you should look for something like:
```
U-Boot 2019.10-00019-g16209d0bf6 (Jul 08 2020 - 15:14:33 +0300)
```
In the early boot messages.

## Word of warning
The current `u-boot` code available as today is fairly new and has two interesting features:
- u-boot is able to `poweroff` (linux is not, yet, sadly)
- u-boot would stop setting the fan at full blast

> Make sure your kernel is able to drive the fans correctly otherwise the system will hit the shutdown temperature.

I'm looking forward the time this nice machine could power on and power off correctly.

## Coming next
Hopefully I'll complete and publish some more information about `rav1e`, both its API and its internals.