User:Adrian/aarch64 be
This page aims to cover all there is to know about big endian, 64-bit ARM (also known as aarch64_be).
What? I thought ARM was little endian!
You're right, but also not quite. Most ARM[1] CPUs run in little endian mode by default, but are technically capable of bi-endianess and can be changed to big endian mode.
Big endian ARM is extremely similar to little endian ARM, with basically only one difference: All memory load and store operations (i.e. instructions that copy data from a register to memory and vice-versa) use big-endian byte order instead of little endian byte order.
The instruction encoding is always little endian.
Why should I care?
You probably shouldn't. Big endian CPU architectures are becoming more and more rare. x86 is entirely little endian, ARM is predominantly used as little endian and so is RISC-V. POWER is bi-endian but heavily favors little endian for Linux and MIPS is already near dead.
A lot of software nowadays makes the assumption that it is running on a little endian system and does not even consider the possibility of a big endian host. Mesa is a prominent example of software that appears to have regressed on big endian systems in the past. Lack of access to big endian hardware for developers means that they cannot easily test or debug these problems.
Big endian ARM solves this! Most ARM CPUs appear to support running in big endian mode and, provided software support for it existed, it would allow developers to test their software's big endian compatibility by firing it up on e.g. their smartphones.
Caveats
Since only memory load/store operations are affected by the runtime endianess on ARM, any endianess-unaware MMIO will likely completely break on big-endian systems.
The Linux kernel makes it near impossible to use endianess-unaware MMIO and generally handles big endian ARM quite well, provided that the hardware implements it correctly[2].
Technical aspect
See the ARM documentation for SCTLR_EL2 for more information.
In order to switch the CPU to big endian mode, one must simply set the EE (endianess enable) bit of the SCTLR_EL2 (or the equivalent EL3 register) system control register to 1.
Assembly example:
mrs x13, SCTLR_EL2
orr x13, x13, #(1 << 25)
msr SCTLR_EL2, x13
isb
This sets EE (bit 25) to 1 and flushes the processor pipeline. Any instructions following are executed in big endian mode.
The Linux kernel's head.S will set the configured endianess early, even if it was booted in little endian mode.
Linux
Building a Linux kernel for big endian ARM is pretty easy. Just take your kernel configured for little endian ARM, open menuconfig and go to "Kernel Features" -> "Endianess" and select "Build big-endian kernel".
This may or may not disable a couple of config options (most notably, EFI will not work with big endian systems).
Alpine
An unofficial port of Alpine Linux is available at aarch64.be.
Field survey
This aims to be a list of all ARMv8-A SoCs and whether they support big endian mode or not. If you have a new finding, please edit the page and add it!
For testing, you can just build a standard kernel in big endian mode and optionally use Buildroot to generate a big-endian ARM initramfs for you. However, if you use a little endian initramfs and the kernel complains that the initramfs is in the wrong endianess, it means that your SoC supports big endian just fine! Another good sign is wrong colors on your framebuffer.
Qualcomm SoCs will need this patch unless the kernel version is recent enough to include it, otherwise the kernel will crash very early.
SoC | Supports big endian mode | Quirks | Notes |
---|---|---|---|
Qualcomm Snapdragon 730/730G/732G (SM7150) | Yes | None | Can be booted by the stock bootloader just fine |
Qualcomm Snapdragon 778G/778G+/782G (SM7325) | Yes | Unknown | Only tested in EFI so far, Linux hangs on QCS6490 |
Qualcomm Snapdragon 8 Gen 1/8+ Gen 1/7+ Gen 2 (SM8450/SM8475/SM7475) | Yes | GICv3 is also big-endian, contrary to spec | Can be booted by the stock bootloader just fine |
CIX CD8180 | Yes | Unknown | Only tested in EFI so far |
Amlogic S905 | Yes | None | putting a BE kernel into an Android bootimg works just fine |
Allwinner H313/H616 | Yes | None |