Building a big-endian Arm system in Yocto

Posted by Ross Burton on March 6, 2023

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"

qemumarm.conf requires 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 b:

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

Or not.

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 SRC_URI:

CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_LITTLE_ENDIAN=n

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.

tags: tech, yocto