Testing on lots of architecture targets with mkroot.

Rob Landley <[email protected]> Tue, 26 May 2026 13:51:32 -0500
Newsgroups org.kernel.vger.linux-embedded
Message-ID <[email protected]>
I promised Tim I'd explain to him how I regression test on s390x and sh4 
and mips and powerpc and so on in parallel, and he was in the audience 
for my wednesday talk at ELC, but I'm not sure that gave him everything 
he needed to do proper automated regression testing under qemu on lots 
of architectures in parallel.

The source repo I used was: https://codeberg.org/landley/toybox

Prebuilt binaries of all the outputs are at https://landley.net/bin/ 
with several releases worth of history. (Although it'll probably go down 
at the end of the year to avoid Gavin Newsom's $7500/download fines.)

There's a README in the toybox/mkroot directory, but also instructions 
at https://landley.net/toybox/faq.html#mkroot and 
https://landley.net/talks/mkroot-2023.txt (which was the previous time I 
gave a mkroot talk).

You'll need cross compilers: my musl+gcc cross (and native) compilers 
are built with Rich Felker's 
https://github.com/richfelker/musl-cross-make using a wrapper script in 
scripts/mcm-buildall.sh in the toybox source. The binary tarballs are in 
https://landley.net/bin/toolchains but you'll probably want to build 
them from source.

If you run that mcm-buildall.sh script in a fresh musl-cross-make 
checkout directory with no arguments it builds toolchains for all the 
targets I've managed to get working so far.

If you want to rebuild just one, you can feed it any of the strings from 
https://codeberg.org/landley/toybox/src/branch/master/scripts/mcm-buildall.sh#L18 
as an argument, ala:

$ ~/toybox/mcm-buildall.sh m68k::

Note that these toolchains are statically linked with a host compiler to 
be portable, so the script will first build a musl host compiler (see 
line 38 in the buildall script) because glibc is incompetent at static 
linking.

In theory this means you can just grab a tarball and extract it 
somewhere and add it to your $PATH and it should just work. There's also 
a https://landley.net/bin/toolchains/25-03-2024/musl-cross-make.tar.xz 
with everything (all the source and all the targets it built) to shut 
Bradley Stallman up.

The test harness script is mkroot/testroot.sh again in the toybox 
source. Run it from the top level (toybox source) directory and it'll 
iterate through all the images under root/ and try to run them under 
qemu (you need qemu-system-* and mksquashfs in your $PATH, it'll 
complain if either is missing). It provides a squashfs filesystem with 
controls scripts and test data, so instead of booting to a shell prompt 
the qemu instance runs a test script and then exits on its own. It 
prints out various "=== thingy" lines for successful tests, and the 
pass/fail thing at the end says whether it got enough === lines of 
output. If not, look at root/build/log/*-test.txt to see what output it 
DID get.

I did the start of a busybox-based version at 
https://codeberg.org/landley/toybox/src/branch/master/mkroot/packages/busybox 
a while back but unfortunately building busybox defconfig is INSANE 
these days. You'll notice rather extensive patching with sed to remove 
build dependencies toybox doesn't have, and even then it was mad about 
something (I forget what).

That said, you can also just do:

mkroot/mkroot.sh NOAIRLOCK=1 LINUX=~/linux CROSS=allnonstop mybusybox

To skip the airlock step and run your own much simpler busybox build 
script (just stick it in mkroot/packages), and as long as your script 
sets NOTOYBOX=1 before it exits you should get the directory layout, the 
init script, the kernel build and packaging, and the run-qemu.sh for the 
target, with whatever additional files YOU installed (under $ROOT/). So 
a busybox based filesystem instead of toybox shouldn't be a big lift, 
just wasn't a priority for me.

But since you're not testing _toybox_, and toybox isn't 1.0 yet, that 
would probably give you an environment much closer to what you want. :)

Note that mkroot.sh is almost entirely self-contained, merging it into 
toybox and having LINUX= be specified on the command line was just so I 
didn't have to download any packages in the default build. (There's 
download plumbing in scripts/plumbing, I think I went over that in the 
talk. The "dropbear" package is another one to read to see how that 
stuff works.)

Rob