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
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.
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:
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).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).
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.
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:
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.
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:
What had to be written or ported:
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.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.

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.
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).