Lifecycle Management for white-label hardware
You might want to buy ready-to use hardware from an overseas manufacturer, but noticed that they only support old operating system versions or you are worried about software support from them in general. Updating software as fast as possible is important to keep devices secure and simplifies development a lot by being able to utilize the latest features.
The solution is to choose hardware which is based on a very common SoC where the SoC manufacturer itself actively maintains and updates the software. With that, all you have to do is to understand the differences between the manufacturer’s official development kit and your hardware. Then you take the device definitions from the development kit which are compatible with the latest version of the operating system and adjust the parts where your hardware differs. We did that to get Android 15 running on the Advantech TPC-107W which uses an NXP i.MX 8M Mini. We did this without access to any hardware documentation like schematics.
Understanding the board manufacturer’s changes
The Advantech TPC-107W comes with Android 10 support while the latest version is 15. The first important step is to figure out, which version of which software they based their work on, so you can see what exactly they changed. This process depends on the software, but in Android, a good indication is the file build/core/build_id.mk. Additionally, you can look at files which changed between git tags of the SoC manufacturers releases.
Once you know the base version, you look at the changes made by the board manufacturer to understand the hardware and what’s required to get it working. We also found it useful to compare everything against the official development kit from the SoC manufacturer. This way, you understand the hardware differences and will be able to quickly port any SDK version and migrate to new ones by looking at what was changed in the devkit related files.
The changes made by board manufacturers usually fall into these categories:
• Changes that you really need to support the hardware.
• Changes for hardware components, that you don’t need.
• Changes that were needed in the old version, but are not needed anymore thanks to advances in the upstream project.
• Changes that are unrelated to the hardware, e.g. additional features or demo code.
Luckily, we only need to care about the first category. Depending on the hardware and the scope of the SDK, these can be surprisingly little compared to the total amount of changes they made. In a multi-repository project like Android it’s also important to stay focused on the repositories that actually are relevant for the hardware. Usually, these are the firmware, the bootloader, the kernel and the Android board configs. For NXP, the Android HAL components should be board-independent and work as is.
Porting Android 15
For the TPC-107W, we started by creating a new device config based on the development kit. At this point it doesn’t have to be complete or correct, it just needs to compile and then you can adapt it more and more during the porting process.
As said before, for NXP, there aren’t any changes needed in Android itself outside of the device configs, so the focus is on:
• Bootloader (U-Boot)
• Kernel
The process for both of these is actually identical, because they both use device-trees for configuring the hardware. Bootloader support usually needs some additional C code to initialize board specific hardware without a driver. For Linux, that’s usually not needed, but you might need to add new drivers which are not mainline, yet. If the difference in bootloader/kernel versions isn’t too big and you’re lucky, you can actually just use the “old” device tree as is, with no or only minor modifications and it’ll work just fine. We tried that out and, lo and behold, we were greeted with the android boot screen.

We managed to get a fully functional port that way. Later we then decided to fully redo the device-tree based on the official development kit to understand all of the hardware differences and make it easier to adapt future changes in the dev kit device-tree to the Advantech device-tree.
For the Advantech board thes most importants differences were:
• Different PMIC
• Different LCD panel and backlight
• No USB-C
• Different pin numbers and regulator configuration
• Different I2C devices
• Special GPIO initialization in U-Boot.
• Read ethernet MAC address from SPI flash and write it to device tree.
• One of the ethernet ports uses a driver that’s not mainline.
And this is basically it. Of course, all of this took a couple of weeks, but it was very straight forward and mostly slowed down by compile-times. With this, we now have a very new and standard software stack which allows us to fully utilize the hardware. We even got secure boot working.






