Problem: IOT2050 Example Image Refuses to Boot, STAT LED Red
A freshly compiled Siemens SIMATIC IOT2050 example image writes successfully to the SD card but the device will not bring up a login shell. The user-observable symptoms are:
- U-Boot loads the kernel and device tree, control passes from
bootcmdto the Linux kernel. - Boot progress halts very early — the console shows no
systemdbanner, nologin:prompt, no getty. - The front-panel STAT LED transitions from solid green to solid red within seconds of the first userspace activity.
- The same SD card flashed with the binary sample distributed under Siemens Support Entry 109780231 boots normally and exposes all network interfaces.
This pattern indicates the bootloader and storage are healthy — the failure is inside the userspace image itself (kernel/userspace ABI mismatch, missing firmware blobs, or incompatible extlinux.conf entry).
Affected Hardware and Firmware
| Item | Value |
|---|---|
| Device | SIMATIC IOT2050 (AR-Extension variant AR-3D / basic) |
| SoC | TI AM6528 (Arm Cortex-A53 dual core, 1.0 GHz) |
| Bootloader | Das U-Boot 2021.10 (vendor fork) or later vendor fork |
| Last working kernel | 4.19.y LTS |
| Userland in working image | Debian 10 (Buster) |
| Broken image | Any build against kernel > 4.19 using newer meta-iot2050 HEAD |
| Recommended replacement | meta-iot2050 release V01.01.01 |
Root Cause: Kernel/Firmware ABI Break
The Siemens meta-iot2050 Yocto layer tracks upstream linux-yocto and the AM65xx TI BSP. The vendor replaced the legacy 4.19 kernel branch in the layer with a newer mainline kernel branch (5.10+). The on-board firmware (CPSW Ethernet firmware, PRU firmware, System Controller binary) that is pre-flashed at the factory is only ABI-compatible with the 4.19 kernel drivers compiled against the matching firmware interface header. When a newer kernel is loaded:
- The CPSW
netcpdriver probes and fails to attach because the firmware interface version reported by the System Controller does not match the in-tree driver's expectation. - If a custom
systemdunit orudevrule requires the network stack to be online (e.g.Wants=network-online.target) before the watchdog daemon starts, the watchdog pet never happens and the BMC-equivalent watchdog on the IOT2050 asserts a hardware reset, which the firmware re-enters as a STAT = red state on the next U-Boot pass. - Even when the watchdog path is removed, newer kernels drop support for the on-board EEPROM layout that the vendor's MAC-address/persistent-storage reader expects, so the kernel may panic at boot on
of_get_mac_addresswith an-EINVALif the device tree is incompatible.
Siemens' official position (per the GitHub release notes on the V01.01.01 tag) is that the deployed firmware image on existing field devices requires the 4.19 kernel until a paired firmware + kernel update is released. The 4.19 branch was therefore the last supported configuration, and newer branches are pinned to require a firmware update that was scheduled for release "around October" (post-2021/09/10 cut-off for the source incident).
Solution: Pin to meta-iot2050 V01.01.01 (4.19 + Buster)
The supported, documented workaround is to clone or update the meta-iot2050 layer at the V01.01.01 release tag and rebuild the example image against it. This combination was the last release built on kernel 4.19 with Debian 10 (Buster) userland and is the safest option for existing devices that cannot take the new firmware yet.
Step 1 — Pin the layer
In your Yocto build directory's conf/sanity.conf or your top-level init script, change the SRCREV of the layer to the V01.01.01 commit hash:
# In your .conf or bblayers.conf-equivalent
SRCREV_meta-iot2050 = "<commit-hash-of-V01.01.01-tag>"
SRC_URI = "git://github.com/siemens/meta-iot2050.git;branch=master;protocol=https"
# Override to a specific tag by using a srcrev file or BB_GIT_LOCAL_MIRROR
The simpler approach is to use a git checkout in a local mirror before bitbake resolves the layer:
cd /path/to/sources/meta-iot2050
git fetch --tags
git checkout V01.01.01
git log -1 --oneline # confirm you are on the tagged commit
Step 2 — Verify kernel and distro pins
Confirm the build is producing the expected kernel and userland. In the V01.01.01 release the relevant variables are:
| Variable | Expected value on V01.01.01 |
|---|---|
| PREFERRED_PROVIDER_virtual/kernel | linux-yocto |
| LINUX_VERSION | 4.19.x (long-term) |
| DISTRO | poky (with Debian 10 userland packages) |
| DISTRO_FEATURES | includes systemd, wayland, x11 optional |
| MACHINE | iot2050 (or iot2050-basic) |
Inspect with bitbake -e virtual/kernel | grep ^LINUX_VERSION= after sourcing the build environment.
Step 3 — Build the example image
source oe-init-build-env
bitbake iot2050-example-image # or whatever the example IMAGE_INSTALL target is named in V01.01.01
The output .wic or rootfs tarball will land in tmp/deploy/images/iot2050/.
Step 4 — Flash the SD card
Use dd with a verified block size and confirm the write completed:
sudo umount /dev/sdX*
sudo dd if=tmp/deploy/images/iot2050/iot2050-example-image-iot2050.wic \
of=/dev/sdX bs=4M conv=fsync status=progress
sync
Remove the card, insert it into the IOT2050, and power-cycle.
Step 5 — Connect to the serial console
Use a 3.3 V TTL USB serial adapter on the IOT2050 debug header (115200 8N1):
minicom -D /dev/ttyUSB0 -b 115200
# or
screen /dev/ttyUSB0 115200
You should see the U-Boot banner, the kernel command line (typically console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait), and the login: prompt within 25-40 seconds of power-on.
Verification Checklist
- STAT LED behavior. After power-on, LED goes amber briefly during U-Boot, then green when systemd reaches the multi-user target. It must not turn red.
-
Console banner. Kernel prints
Linux version 4.19.xand finishes theFreeing unused kernel memoryline within 15 s. -
systemd default target reached.
systemctl is-system-runningreturnsrunning;multi-user.targetis active. -
Network interfaces up.
ip linkshowseth0and any bridge interfaces withLOWER_UP. On V01.01.01 the interface naming has been corrected (it matches the physical labels); older user builds sometimes named them in a way that clashed with udev rules. -
Watchdog daemon.
systemctl status systemd watchdog(or the equivalentwd_keepaliveunit in the example image) is active. If it is missing or failing, the watchdog will still fire on idle and you will see a red STAT LED after the configured timeout (default ~60 s). - Persistent state. Reboot twice. Some kernel/firmware mismatch symptoms only appear on the second boot when the RTC wakeup path is exercised.
STAT LED Diagnostic Matrix
| LED State During Boot | Interpretation | Likely Cause | Action |
|---|---|---|---|
| Off | No power or main PSU rail fault | PSU, fuse, base board | Check 24 V supply, base board LEDs |
| Amber solid | U-Boot executing, kernel not yet handed control | Normal early boot | Wait; verify console output |
| Green flashing | System alive but services still starting | Normal | Watch for login:
|
| Green solid | systemd reached multi-user.target | Healthy | None |
| Red solid | Hardware watchdog reset triggered | Kernel panic before watchdog pet OR userspace hung > 60 s | Capture console log; pin to V01.01.01 |
| Red flashing | Firmware error or recovery mode | U-Boot failed to load image from SD | Re-image SD; verify extlinux.conf |
Bootloader and Image Layout Reference
The IOT2050 SD card uses a two-stage layout managed by U-Boot. Understanding this layout is essential when a STAT-red boot leaves no useful log on the serial console.
| Partition | Filesystem | Contents |
|---|---|---|
| /dev/mmcblk0p1 | vfat (FAT32) | MLO, u-boot.img, uEnv.txt, extlinux/extlinux.conf, kernel Image, device tree *.dtb, System.map |
| /dev/mmcblk0p2 | ext4 | Rootfs (/bin, /sbin, /usr, /lib, /etc, /var, /home) |
If the SD card is unreadable at all, U-Boot's boot script (commonly finduuid then load mmc 0:1 ...) will fail and the device will drop to the U-Boot prompt. If the boot script succeeds but the kernel cannot mount /dev/mmcblk0p2 (e.g. ext4 module missing or root= argument wrong), the kernel panics with VFS: Cannot open root device "mmcblk0p2" — this also produces a red STAT LED via the watchdog, but the console will show the panic.
Card not detected or repeats the SD enumeration loop indefinitely, the storage card itself is suspect. Replace the SD card and re-image. This failure mode is generic across embedded Linux devices and is documented in vendor Windows CE 7 imaging guides (e.g. Eaton MN050004_EN).Workarounds Until the New Firmware Is Released
- Use V01.01.01 image only. Pin your build to this tag. Do not pull HEAD. This is the supported path until the matching firmware update ships.
- Use the Siemens-bundled binary sample. For training and demonstration purposes, the prebuilt sample linked from Siemens Support 109780231 is built against the same V01.01.01 base and will boot on factory firmware without modification.
-
Disable the hardware watchdog temporarily for debugging. In U-Boot, append
systemd.watchdog_device=to the kernel cmdline, or mask the watchdog service. This will keep the device alive long enough to capture a real panic log over the serial console, but it must not be left in production. -
Capture a full boot log from serial. Use a hardware serial logger (e.g. an OpenSDC, an FTDI friend with logging software, or a Linux host with
screen -L -Logfile boot.log) to record the entire boot. The kernel panic message will identify the exact failing subsystem (CPSW, PRU, EEPROM reader, etc.).
Post-Recovery: Planning the Firmware Update
When Siemens publishes the new IOT2050 firmware capsule (originally indicated for "around October" from the 2021/09 incident), the migration path is:
- Reflash the System Controller and CPSW firmware using the Siemens-provided capsule and the IOT2050 firmware update procedure (typically a signed U-Boot update from the FAT partition plus a power-cycle).
- Verify the new firmware version is reported on the serial console during U-Boot (look for
SCFW Build VersionandCPSWversion strings). - Rebuild the Yocto image against the newer meta-iot2050 release that matches the new firmware (kernel 5.10 or later).
- Validate the same boot checks (LED, systemd, network) on the new image.
Do not attempt to load a newer kernel image onto factory firmware. The kernel/firmware ABI mismatch is the exact failure mode that produces the red STAT LED in the original report.
Edge Cases and Field-Proven Caveats
- SD card quality. Industrial SD cards (e.g. Swissbit, ATP, Apacer) are strongly recommended. Consumer cards can produce intermittent read errors that masquerade as image corruption, with the same STAT-red symptom.
- Power supply ramp. The IOT2050 is sensitive to slow-rising 24 V. If the STAT LED never lights at all, measure the 5 V and 3.3 V rails on the base board test points before assuming an image problem.
-
U-Boot environment. If
uEnv.txtis corrupted (e.g. unterminated quote, missing newline at EOF), U-Boot silently falls back to default environment and may load the wrong device tree branch. Always edituEnv.txton a Linux host and verify withhexdump -C uEnv.txt | tail. -
Second boot only. If the first boot succeeds after a reflash and the second boot fails, the watchdog reset path is masking an in-service crash. Check
journalctl -b -1(previous boot) for the real panic message. -
MAC address stability. On IOT2050 the MAC addresses live in the on-board EEPROM. If you see
eth0: random ethernet addresson every boot, the EEPROM reader failed and the kernel assigned a random MAC — that is a strong indicator the wrong kernel branch is loaded.
Related Reading and Standards
- meta-iot2050 V01.01.01 release notes — Siemens GitHub
- Siemens Support Entry 109780231 — bundled IOT2050 example image binary
- U-Boot 2021.10 source tree — reference bootloader for embedded boards
FAQ
Why does the IOT2050 STAT LED turn red right after a fresh Yocto build?
The hardware watchdog on the IOT2050 asserts a red STAT LED when userspace fails to pet the watchdog within the timeout (default 60 s). A kernel that panics before reaching systemd, or that hangs on a CPSW/PRU firmware probe, will trigger this reset on the very first boot. The fix is to pin your build to meta-iot2050 V01.01.01 (kernel 4.19 + Debian 10 Buster) so the kernel matches the factory firmware ABI.
Can I use a newer Linux kernel on the existing IOT2050 firmware?
No. The factory firmware is only ABI-compatible with the 4.19 kernel branch. Newer kernels (5.10+) require a paired firmware update from Siemens. Mixing the two produces the red STAT LED / no login shell symptom documented in the original 2021/09 incident.
Where do I get a known-working IOT2050 example image?
Use the prebuilt sample linked from Siemens Support Entry 109780231 for quick validation, or build your own from the meta-iot2050 V01.01.01 tag. Both are built against kernel 4.19 and Debian 10.
How do I capture the actual panic message if the console is silent?
Connect a 3.3 V TTL serial adapter to the IOT2050 debug header at 115200 8N1 before power-on. Use a logging session (e.g. screen -L /dev/ttyUSB0 115200) so every byte is captured. If userspace never starts, also try masking the watchdog service to keep the device alive long enough to read the panic.
Will the red STAT LED clear after a reflash with the Siemens binary sample?
Yes. Flashing the binary sample from Siemens Support 109780231 onto the same SD card restores the green STAT LED and a working login: prompt, confirming that the SD card, U-Boot, and factory firmware are all healthy and the failure was entirely in the locally built image.