The ARM Application Binary Interface (ABI) and Embedded ABI (EABI) define standards for how executable code interacts with the ARM processor architecture and underlying system software. The ABI and EABI enable compatibility between various software components in an ARM system by standardizing areas like function calling conventions, register usage, stack layout, exception handling, and OS interactions.
Background on ARM Architectures
ARM processors power billions of devices from smartphones to appliances to industrial equipment. This wide deployment stems from ARM’s RISC architecture that emphasizes power efficiency, making ARM ideal for embedded systems. However, ARM’s flexibility allows vendors to customize implementations, optimizing for factors like performance, die area, and power draw.
This customization introduces challenges for software compatibility. An executable compiled for one ARM chip may not work on another due to differences in hardware features or software interfaces. Components like the operating system kernel, device drivers, and applications need standardized conventions to interact seamlessly.
The ARM ABI
The original ARM ABI aimed to promote interoperability by standardizing various low-level code interactions. It defined conventions like:
- Function calling syntax, including register usage for passing arguments and return values.
- Stack frame layout during function calls.
- Global variable access between separately compiled code.
- Use of coprocessor registers for floating point and other operations.
Following the ABI allows compilers to generate binary code that integrates with other ABI-compliant components. This enables easily combining software from multiple sources into a compatible system.
Limitations of the ARM ABI
While the original ABI improved compatibility, it had limitations that restricted more complex software development:
- Lacked specifications for sharing libraries or linking object code at runtime.
- Provided limited support for operating system portability.
- Did not standardize stack usage for exception handling and privilege levels.
- Had ambiguities around parameter passing and alignment.
These gaps meant the ABI on its own struggled to meet the needs of advanced embedded operating systems and applications.
The ARM EABI
To address these deficiencies, ARM introduced the Embedded ABI (EABI). The EABI supplements the original ABI with conventions and standards focused on embedded Linux and RTOS environments. Improvements include:
- Formal specifications for shared libraries and dynamic linking.
- Standards for passing arguments in registers or memory.
- Rules for stack usage across privilege levels.
- Explicit support for operating system portability.
- Well-defined handling of integers, floating point values, and stack frames.
Together, the ABI and EABI allow diverse components to combine into sophisticated embedded software stacks. The EABI built upon the fundamental ABI to enable more advanced OS capabilities.
The EABI brings multiple advantages for embedded software:
- Portability – OSes and applications meeting EABI standards can move between EABI-compliant ARM chips.
- Interoperability – C libraries, runtimes, kernels, drivers, and programs generated by different compilers can link together.
- Efficiency – Standardized conventions around registers and stacks result in smaller code size and faster execution.
- Support – EABI compliance means toolchain and OS vendors can officially support chips from multiple hardware partners.
Putting the ARM ABI and EABI Together
The ABI and EABI play complementary roles in enabling ARM ecosystem compatibility:
- The ABI standardizes low-level conventions for routine code execution, like functions calls or global data access.
- The EABI builds on this by addressing OS considerations like dynamic linking, privilege levels, and stack usage.
By separating these concerns, the ABI focuses on general code execution, while the EABI adds provisions needed specifically for OS support. Vendors can conform to the ABI for basic interoperability, then extend compliance to the EABI for more complex OS-based development.
Examples of ABI and EABI Interactions
Here are some examples of how the ABI and EABI work together in an embedded software stack:
- The ABI specifies how functions use registers to pass arguments, allowing functions from any compliant compiler to integrate cleanly.
- The EABI defines how to make C library calls across privilege boundaries, enabling user applications to leverage OS services.
- The ABI standardizes a stack frame structure for each function call. The EABI further defines the stack format at exception levels to support preemptive OS task switching.
- The ABI provides conventions for passing parameters in registers. The EABI adds rules for managing register spills to the stack during function calls.
In each case, the EABI builds on ABI conventions to extend support for OS capabilities.
Looking Forward for the ARM Ecosystem
ARM and its partners continue evolving the ABI and EABI to meet new requirements. For example, ARM recently introduced the ARM 64-bit Architecture (AArch64) ABI to support 64-bit ARMv8-A cores. Additional enhancements like better C++ support are underway. The needs of emerging ARM-based applications and markets will spur further ABI and EABI developments.
Together, the ARM ABI and EABI enable the ecosystem synergy that makes ARM the ubiquitous architecture powering today’s intelligent embedded world. Their careful standardization allows software innovations to thrive on a robust base of compatibility.