Chipbox Reborn & Chipbox Next

October 12, 2026    chipbox set-top-box dvb-s2 embedded-linux u-boot linux-kernel llm

TL;DR:

In 2009 I designed one of the world’s first Linux-based HD satellite receivers, the Chipbox. It is one of the main projects on this website: DVB-S2 ARM-Linux Set-Top-Box.

17 years later, with today’s AI / LLM tools, I started to reproduce the whole project from source with its original SDK/BSP stack (U-Boot from 2007, Linux 2.6.12.5, the MiniGUI-based mvapp). I used Cursor for that phase: we got quite far, nailed down JTAG flashing and built a repo-based CBS (Chipbox Build System). That is chipbox-reborn (firmware version v41).

Then we ported the box to a modern stack: U-Boot 2026.07, Linux 7.2, an EABI userspace, the original application re-built for it, a graphical updater and over-the-air updates for boxes in the field. That is chipbox-next (firmware version v42), mostly done with Claude Code in October 2026.

Both are fully reproducible with four commands:

repo init -u https://gitlab.com/chipbox/chipbox-reborn/manifest.git -b main   # or chipbox-next
repo sync -j8
./indockerbuild.sh 28        # 28 = CPU cores to use; -q for one line per step
./push-to-ota.sh             # publish the result to the OTA server (--dry: just build packages)

Everything lives on GitLab: https://gitlab.com/chipbox

What is Chipbox?

HIREMCO Chipbox is a DVB-S/S2 HD set-top box built around the CelestialSemi Orion CSM1203 SoC (ARM926EJ-S @ 180 MHz), 32 MiB NOR flash, a CAT6611 HDMI transmitter, an AVL2108 demodulator + IX2564 tuner front end, an Atmel MCU on the front panel (keys + IR receiver), smartcard reader and a CI slot. The original post with photos is here.

Chipbox Reborn: reproducing the 2009 stack (v41)

The goal of the first phase was simple to state: build the exact 2009 firmware again, from source, in Docker, on a 2026 PC, without relying on any binary dump of the original box.

Things we had to solve on the way:

  • JTAG: a full 32 MiB read/write/verify of the NOR with a SEGGER J-Link (JFlash and OpenOCD), including a “halt in U-Boot, then write” recovery path. Without this, every bricked box would have been a dead box.
  • CBS (Chipbox Build System): a repo manifest with all the sources (U-Boot 1.2.0, kernel 2.6.12.5, rootfs, mvapp, toolchain, dropbear, thttpd, curl, oscam, plugins …), built in the original gcc 3.4.6 / glibc 2.3.6 toolchain inside a Docker image (stulluk/chipbox-docker-builder).
  • A safe field updater: the original DumpWrite32M wrote JFFS2 partitions while they were mounted (Node CRC errors). The v41 writer copies itself to a tmpfs, pivot_roots, lazily unmounts and only then flashes.

Build it yourself:

mkdir chipbox-reborn && cd chipbox-reborn
repo init -u https://gitlab.com/chipbox/chipbox-reborn/manifest.git -b main
repo sync -j8
./indockerbuild.sh 28

The quiet mode (-q) of the build, from a run on my PC:

[indockerbuild] workspace /media/WORK/chipbox-full-verify-20261009_133729, jobs 28 (logs: out/logs)
[indockerbuild] DOCKER IMAGE               ... OK (0 s)
[indockerbuild] ROOTFS/FS TREE SYNC (HOST) ... OK (1 s)
[indockerbuild] FULL BUILD (IN DOCKER)     ... OK (39 s)
[indockerbuild] POST-BUILD VERIFICATION    ... OK (0 s)
[indockerbuild]   jffs2 content=3452832 headroom=2445408 (mtd2=5898240)
[indockerbuild]   work1 jffs2 content=4017068 headroom=3978324 (mtd9=7995392)
[indockerbuild]   VERIFY PASSED
[indockerbuild] DONE — AllFlash_32M.tar ready (29112320 bytes)

The result, out/artifacts/AllFlash_32M.tar, is exactly what the old web upgrade page of a v39 box accepts. ./push-to-ota.sh turns it into a plugin-menu package, so a v39 box in the field can go to v41 from Menu → Plug-in (U-Boot and the channel list are left alone).

What we learned about the hardware

The 32 MiB NOR flash is split into ten MTD partitions. Interesting details: there are four copies of the U-Boot slot (mtd0, mtd3, mtd6, mtd8), the first 5 KB of each slot is a product loader that starts U-Boot (at 0x1400), and the channel list lives in its own partition (mtd5), so a firmware update never has to touch it.

Chipbox NOR flash layout

Boot chain on v39/v41: loader → U-Boot 1.2.0 (bootm 0x380A0000, the NOR is mapped at 0x38000000) → Linux 2.6.12.5 with a JFFS2 root on mtd2 → init scripts → mvapp from work0.

The CBS kernel carries a lot of Celestial-specific drivers that never existed in mainline Linux:

  • Display Feeder (DF): the compositor (video planes, OSD planes, background, clipping) and two output interfaces (HD for HDMI, SD for the TV encoder)
  • TV encoders, the 2D graphics engine (scaler, compositor, ROP)
  • Video decoder: a MIPS co-processor running MPEG-2 / H.264 firmware
  • Audio DSP with its own firmware per codec
  • xport: the transport stream demultiplexer (again with firmware)
  • Orion I2C / GPIO, the cn100 Ethernet MAC, the front-panel UART protocol, smartcard and CI

The biggest surprise: HDMI is driven by the application, not by the kernel. mvapp has a task that talks to the CAT6611 over I2C every 100 ms (HDMITX_DevLoopProc()). If mvapp stops, the HDMI signal is gone within about two seconds. That matters a lot later, when you want to show an “updating, do not unplug” screen while mvapp is killed.

Chipbox Next: U-Boot 2026.07 + Linux 7.2 (v42)

Once the old stack was reproducible, the next goal was a modern one. In July we brought up U-Boot 2026.07 and a mainline Linux 7.2 kernel (first from RAM via JTAG, then from NOR). In October we turned that into a product:

Chipbox software stacks

What had to be written or ported:

  • U-Boot 2026.07: CFI NOR behind the original loader (with a patched NOR read), cn100 Ethernet, USB (MUSB), the MAC address from the I2C EEPROM, HDMI boot logo.
  • Linux 7.2: board + device tree, cn100 (plus three RX fixes found under load), Orion I2C, the I2C EEPROM, front panel / IR as an input device, Display Feeder and frame buffers, the 2D engine, the video decoder and audio DSP firmware loaders, xport with section filters, CAT6611 HDMI inside the kernel, a watchdog-based restart.
  • Userspace: the original application is an ARM OABI binary linked against closed libraries. Instead of keeping the kernel’s OABI compatibility forever, we went EABI: libcs* (the Celestial API) from source, MiniGUI and its image/font libraries rebuilt, and the closed Merih tuner and SI (service information) libraries re-written in C — live TV, channel scan and EPG work with them.
  • Picture quality = v39: the first v42 picture had crushed blacks and ran at 720p. Register dumps of v39 vs v42 showed a missing studio-range clip (16–235) in the compositor (26 % of the pixels below 16 vs 1 %), and that v39 scales its 1280x720 menu to 1080i with the 2D engine. Porting that engine fixed both.

Chipbox HDMI path

Over-the-air: v39 → v42 in the field

A box in someone’s living room has no JTAG. So v42 had to arrive through the old v39 firmware itself: its plugin menu downloads a tar from a web server and runs install.sh as root. The package carries a small static LVGL updater (one build for v39 with its own CAT6611 loop, one for v42) that kills everything, keeps HDMI alive, shows the progress screen, pivot_roots into RAM and writes the flash block by block (erase, write, read back, retry), with the U-Boot slot last.

Chipbox v42 update screen

A real v39 → v42 migration from the plugin menu (lab test harness, serial console + HDMI capture card):

09:20:02 plugin flow over telnet
09:20:56 waiting for the writer on serial
09:21:12 update screen during rootfs write: OK (4613 px)
09:25:03 writer finished, fail=0 (301 s)
09:25:23 boot: uboot=True kernel=True root=True init=True
09:26:56 mtd0 boot-slot window (erase+write+verify): 3.6 s
09:26:56 ip=192.168.1.239 web=True audio mean_volume: -40.5 dB (OK) total 414 s
09:26:56 RESULT PASS

The only really dangerous moment, rewriting the boot slot, takes about 3.6 seconds; 27 migration runs in the lab had zero verify failures. Later v42 → v42 updates skip everything that is already identical, so U-Boot is not touched again (0.2 s in the same log line). There is also a way back: a v39 rollback package (old U-Boot first, the box’s own MAC address patched into the old environment).

Build v42 yourself:

mkdir chipbox-next && cd chipbox-next
repo init -u https://gitlab.com/chipbox/chipbox-next/manifest.git -b main
repo sync -j8
./indockerbuild.sh 28
[indockerbuild] image     ... OK (0 s)
[indockerbuild] u-boot    ... OK (2 s)
[indockerbuild] kernel    ... OK (5 s)
[indockerbuild] mvapp     ... OK (34 s)
[indockerbuild] busybox   ... OK (9 s)
[indockerbuild] ssh       ... OK (12 s)
[indockerbuild] updater   ... OK (2 s)
[indockerbuild] images    ... OK (2 s)
[indockerbuild] packages  ... OK (3 s)
[indockerbuild]   rootfs: content 5260072 of 5898240 bytes, headroom 638168
[indockerbuild]   Work0: content 5203080 of 7995392 bytes, headroom 2792312
[indockerbuild]   slot: released field U-Boot (692501e4ccb31476439acc3fc0b92077)
[indockerbuild] DONE 42-2026.10.11.2301: out/ota

(That is -q; the default is verbose.) out/ota then holds the v39 → v42 migration package, the v42 update for the web interface, the v39 rollback and an AllFlash_32M.tar for the old web upgrade page. ./push-to-ota.sh publishes them; on a v39/v41 box the site chipbox-ota.kernelmax.com in the plugin menu shows them.

Not there yet

  • Smartcard and CI (CAM): no drivers yet on v42, so no decryption (scrambled channels stay black, as on a v41 box without a CAM).
  • Teletext and subtitles: they lived in closed libraries; on v42 they are stubbed out for now.
  • DRM/KMS: video output is still classic fbdev + a CBS-compatible ioctl interface for the application.
  • The kernel still carries OABI compatibility, although the v42 userspace no longer needs it.

What’s next: mvapp on LVGL

The application UI is still MiniGUI 1.3.3 from the 2000s. The updater already shows that LVGL runs nicely on this 180 MHz ARM926 (fbdev, Turkish fonts, the 2D engine for scaling). The next big step is to re-write the mvapp UI on LVGL screen by screen — infobar, channel list, menus, EPG, installation — while keeping the middleware (Celestial API + the re-written Merih tuner/SI code).

Links



comments powered by Disqus