embedded

35 posts tagged embedded, newest first.

Tagged embedded

35 posts
23 Sep 2026
9 min

dm-verity on a signed rootfs, and two console messages that were simply untrue

You cannot put a filesystem's hash inside that filesystem. Two U-Boot messages that were lies — “press any key to stop autoboot” when no key worked, and quotes vanishing from the kernel command line. Four attempts, three instructive failures, and a hardware SHA engine I did not know I was using.

dm-verityembeddedlinuxsecure-bootstm32mp1u-boot
23 Sep 2026
5 min

Breaking dm-verity on purpose: one bit in 52 MB, and the board refuses

The negative test that proves the chain is real: flip a single bit in a 52 MB root filesystem, get `data block 0 is corrupted`, and watch the board refuse. Why you cannot sabotage your own firmware the two obvious ways.

dm-verityembeddedlinuxsecure-bootstm32mp1testing
23 Sep 2026
6 min

Moving the kernel out of the rootfs, and feeding the bootloader garbage

The hash of a filesystem cannot live inside it, so the kernel had to move somewhere signed. Then the two-command test: hand the bootloader rubbish and watch the kernel ignore it entirely. What that cost, and where the chain now ends.

dm-verityembeddedlinuxsecure-bootstm32mp1u-boot
21 Sep 2026
11 min

Signing the kernel with a FIT image, and the escape hatch that makes it theatre

You cannot sign a zImage. Why the signature goes on the FIT configuration rather than the kernel, the escape hatch that turns the whole thing into theatre, why the negative test needed two tampered images and not one, and the three ways the test lied to me.

embeddedfitlinuxsecure-bootstm32mp1u-boot
18 Sep 2026
7 min

Signing BL2 and the FIP tamper test: one bit flipped, EAUTH, clean halt

TF-A verifying the next stage against a certificate chain inside the FIP — software, on blank fuses, refusing for real. Flipping one bit produced EAUTH on BL33 and a clean halt. Plus the honest limits of what that proves.

embeddedlinuxsecure-bootstm32mp1tf-a
17 Sep 2026
9 min

What secure boot actually is on an STM32MP1: the header, field by field

Signing is not encrypting — the thing burned into silicon is public and you could print it on a billboard. The chicken-and-egg the 32 bytes solve, the STM32 header field by field, four locks wearing one name, and the two things I got wrong and had to correct.

cryptographyembeddedsecure-bootstm32mp1u-boot
16 Sep 2026
8 min

Why I am not burning the fuses on an STM32MP157F-DK2

Secure boot on this chip comes down to 32 bytes in one-time-programmable memory, and a bit you can never un-blow. I started the project with a rule forbidding its own last step — and three of the four links in the chain turn out to enforce for real on completely blank silicon.

embeddedlinuxsecure-bootstm32mp1tf-a
16 Sep 2026
6 min

Four different things people call “security” on an embedded device

Authenticity, integrity, confidentiality and identity are four separate problems with four separate answers. Three private keys that must never be mixed up, why the firmware trust anchor does not identify a device, and the one I had backwards.

cryptographyembeddedsecure-bootsecuritystm32mp1
11 Sep 2026
7 min

Scenic on Nerves: scenes, graphs, drivers, and four things that bit me

Scenes, graphs, components and drivers on an STM32MP157F-DK2 — then the four gotchas that compile cleanly and fail on the device: the required assets module, the child spec that is a plain list, the missing input: style that made every button inert, and text_align: :center not working.

displayelixirembeddednervesscenicstm32mp1
11 Sep 2026
7 min

nerves_system_br: what it actually is, and where your OTP version is decided

An afternoon spent finding where a Nerves target's Erlang version is really decided — and discovering it is encoded in the filename of a patch inside a dependency I had never opened. Plus the Kconfig default that will silently move you to OTP 29 the moment you bump.

buildrootelixirembeddednervesotp
10 Sep 2026
9 min

The STM32MP157F-DK2 display stack, and the Vivante GPU I did not need

Between an Elixir process and a lit pixel on the DK2 there is an LTDC, a MIPI DSI host, an OTM8009A panel and a Goodix touch controller. I spent a day preparing to enable the Vivante GC NanoUltra, then read scenic_driver_local's source and found it renders in software to /dev/fb0.

displayelixirembeddednervesscenicstm32mp1
24 Aug 2026
6 min

Provisioning the next board

The repeatable runbook, and the reason flashing a pre-made image left me with a 512 MB data partition instead of 28 gigabytes.

embeddedfwupimx8linuxnerves
17 Aug 2026
5 min

Ran out all six config attempts

The board flashed perfectly and never reached Linux. A Kconfig choice split upstream had silently retargeted my bootloader at the wrong DRAM.

embeddedimx8linuxnervesu-boot
10 Aug 2026
6 min

Flashing without the vendor's flashing tool

NXP's uuu dies at 8% on an Apple Silicon Mac. The board's own U-Boot has ums and fastboot, and those use bulk USB, which works fine.

embeddedimx8linuxnervesu-boot
03 Aug 2026
6 min

It compiles. It still won't package.

Four packaging bugs between a Nerves system that builds and a firmware that flashes — plus the kconfig hang that looks exactly like a working build.

buildrootelixirembeddednerves
27 Jul 2026
6 min

Authoring a Nerves system by hand

Why I wrote a custom Nerves base image file by file for a CompuLab IOT-DIN-IMX8PLUS instead of forking a sibling board's system.

buildrootelixirembeddedimx8nerves
20 Jul 2026
93 min

Building the Nerves system: the first attempt

Before I show you the first build attempt (and its failures), I need to clear up something that confused me at first.

elixirembeddednervesstm32mp1
13 Jul 2026
15 min

Device trees demystified: reading the hardware map

On a desktop PC, when you plug in a USB device or install a PCI graphics card, the operating system discovers it automatically. PCI has enumeration.

elixirembeddednervesstm32mp1
06 Jul 2026
14 min

The STM32MP1 boot chain, from power-on to Linux

I've been using Nerves for years, and for most of that time the boot process was a black box. Plug in power, wait a few seconds, get an IEx prompt. Magic.

elixirembeddednervesstm32mp1
29 Jun 2026
6 min

Why build a custom Nerves gateway from scratch

I've been using Nerves for a while now. Raspberry Pi, BeagleBone — the usual suspects. You pull in the official system, write your Elixir code, burn firmware,…

elixirembeddednervesstm32mp1
15 Jun 2026
4 min

It boots signed — and the HAB gate in booti I did not know I had

The signed Nerves firmware boots. And a finding that deleted an open task: enabling CONFIG_IMX_HAB wires an automatic fail-closed authentication gate into booti itself, for every kernel boot, with no bootcmd changes at all. Plus a fleet gotcha about who can SSH in.

elixirembeddedhabimx8nervessecure-bootu-boot
08 Jun 2026
3 min

Making the Nerves build sign imx-boot and the kernel automatically

Wiring signing into the build, and a correction worth more than the wiring: I planned to point fwup.conf at signed artifacts, and that was the wrong layer entirely — the signed bootloader is not in the .fw file at all.

buildrootelixirembeddedfwupimx8nervessecure-boot
01 Jun 2026
3 min

Signing the Nerves kernel on i.MX8M Plus, clean on the first try

The same kernel-signing procedure as track A, on a different build — and it passed first time, because the two things that went wrong last time were checked rather than assumed. A 691,712-byte padding gap, and a signed range that goes through the IVT.

cstembeddedhabimx8nervessecure-boot
25 May 2026
4 min

Forking the Nerves system, and enabling HAB inside a Buildroot build

Three real bugs blocked the first three attempts: a nerves package version whose error message points nowhere near the cause, a missing .tool-versions, and the same SPL SRAM overflow track A hit. Plus the arm64 header field that is at offset 0x10, not 0x4.

buildrootelixirembeddedimx8nervessecure-boot
18 May 2026
3 min

From a lab unit to a production Nerves system on the IOT-DIN-IMX8PLUS

The first series proved HAB secure boot on a disposable lab unit running stock Linux. This one carries it into a real Nerves system — in a fork, so the build that runs in the field is never at risk. Same board, different starting point, and several things that do not transfer.

elixirembeddedimx8nervessecure-boot
04 May 2026
5 min

The SRK fuse and closing the device: what is left, and why I stopped

Two fuse writes stand between a signed board and a locked one: the SRK hash, and the bit that makes the chip refuse unsigned code. Both are permanent. Here is exactly what they are, how to read their current state, and why I have not burned either.

embeddedhabimx8secure-bootu-boot
27 Apr 2026
6 min

Signing the kernel, and a HAB failure the chip caught

Extending the chain from the bootloader to the kernel. The first signed Image failed with HAB_INV_ASSERTION — because I read NXP's own diagram literally and stopped the signed range one IVT short. How I decoded the event by hand and found the off-by-32-bytes.

cstembeddedhabimx8kernellinuxsecure-boot
20 Apr 2026
7 min

Signing imx-boot and turning on HAB on the i.MX8M Plus

Enabling CONFIG_IMX_HAB overflowed the SPL's SRAM budget by 10,440 bytes. Fixing that, computing the real CSF insertion offsets from the build's own binman node rather than NXP's generic one, signing with cst, and getting 'No HAB Events Found!' on hardware.

cstembeddedhabimx8secure-bootu-boot
13 Apr 2026
14 min

The board stopped booting: LPDDR4 training, and recovering an IOT-DIN-IMX8PLUS over USB

My imx-boot build failed LPDDR4 training and the gateway stopped booting before U-Boot. The cause was one Kconfig symbol. Recovering it took days, because uuu's SDP mode does not work on Apple Silicon and the board has two identical-looking micro-USB ports.

embeddedfastbootimx8linuxsecure-bootu-bootuuu
06 Apr 2026
4 min

Building an unsigned imx-boot for the IOT-DIN-IMX8PLUS

The first real build: a completely unsigned bootloader, on purpose, so that any problem is a build problem and not a signing problem. Two errors on the way, one of which is caused by a modern setuptools removing pkg_resources.

buildcompulabembeddedimx8secure-bootu-boot
30 Mar 2026
6 min

Pinning the U-Boot build environment for the IOT-DIN-IMX8PLUS

imx-boot is not one repository — it is U-Boot, ARM Trusted Firmware, NXP's imx-mkimage and the LPDDR4 training blobs, assembled together. Get one of them at the wrong version and it builds cleanly and fails to train memory. How I pinned all four using the board's own boot log.

atfbuildembeddedimx8secure-bootu-boot
23 Mar 2026
7 min

Backing up the eMMC: boot partitions, rootfs, and the force_ro trap

Before touching a bootloader, take a backup you can actually restore from. On an i.MX8M Plus that means four separate things, two of which a dd of the main device silently misses — and one that is not block data at all.

backupddembeddedemmcimx8linuxsecure-boot
16 Mar 2026
5 min

Generating HAB keys with NXP's Code Signing Tool (CST 4.0.1)

Getting CST, generating the thirteen-key HAB PKI tree with hab4_pki_tree.sh, and building the SRK table and its fuse hash with srktool. Including the thing that script does silently if you do not read it first: it invents a passphrase for you, and the passphrase is 'test'.

cryptographycstembeddedhabimx8secure-boot
09 Mar 2026
5 min

The HABv4 key hierarchy: SRK, CSF, IMG and the fuses

Why i.MX8M secure boot needs thirteen key pairs rather than one, what 'open' and 'closed' actually mean, and which single 256-bit value ends up permanently burned into the chip. The concepts, before any tool touches anything.

cryptographyembeddedhabimx8secure-boot
02 Mar 2026
7 min

The hardware: a CompuLab IOT-DIN-IMX8PLUS, and how to confirm what you actually have

What you need to follow this series: a CompuLab IOT-DIN-IMX8PLUS industrial gateway on an NXP i.MX8M Plus, a serial cable, and a spare unit you are willing to break. Plus the commands to confirm which variant you have, because it decides what you build.

compulabembeddedhardwareimx8linuxsecure-boot