For reasons I won't bore anyone with I needed to build a 32-bit big-endian system with the Yocto Project to test a package, and I thought I'd write the steps down in case I ever need to do it again (or, even more unlikely, someone else needs to do it).
For unsurprising reasons I thought I'd do a big-endian Arm build. So we start by picking the
qemuarm machine, which is a Armv7-A processor (Cortex-A15, specifically) in little-endian mode by default.
MACHINE = "qemuarm"
tune-cortexa15.inc which then requires
arch-armv7ve.inc, and this file defines the base tunes. The default tune is
armv7ve, we can make it big-endian by simply adding a
DEFAULTTUNE:qemuarm = "armv7veb"
And now we just build an image:
$ MACHINE=qemuarm bitbake core-image-minimal ... Summary: 4 tasks failed: .../poky/meta/recipes-kernel/linux/linux-yocto_6.1.bb:do_package_qa .../poky/meta/recipes-graphics/xorg-proto/xorgproto_2022.2.bb:do_configure .../poky/meta/recipes-core/glib-2.0/glib-2.0_2.74.5.bb:do_configure .../poky/meta/recipes-graphics/wayland/wayland_1.21.0.bb:do_configure
There are two failure cases here. First, the kernel:
ERROR: linux-yocto-6.1.9+gitAUTOINC+d7393c5752_ccd3b20fb5-r0 do_package_qa: QA Issue: Endiannes did not match (1, expected 0) in /lib/modules/6.1.9-yocto-standard/kernel/net/ipv4/ah4.ko [arch]
It turns out the kernel needs to be configured specifically to be big or little endian, and the default configuration is, predictably, little endian. There is a bug open to make this automatic, but big-endian really is dead because it has been open since 2016. The solution is a quick kernel configuration fragment added to the kernel's
With this, the kernel builds as expected. The second set of failures are all from Meson, failing to execute a target binary:
../xorgproto-2022.2/meson.build:22:0: ERROR: Executables created by c compiler armeb-poky-linux-gnueabi-gcc [...] are not runnable.
Meson is trying to run the target binaries in a
qemu-user that we set up, but the problem here is to save build time we only build the qemu targets that are typically used. This doesn't include usermode big-endian 32-bit Arm, so this target needs enabling:
QEMU_TARGETS:append = " armeb"
Now the image builds successfully, and we discover that indeed gdbm refuses to open a database which was generated on a system with a different endian.