Skip to content

Instantly share code, notes, and snippets.

@frosit
Last active November 21, 2024 19:01
Show Gist options
  • Save frosit/281c8dff9714667dd2b0e051c0e73f9d to your computer and use it in GitHub Desktop.
Save frosit/281c8dff9714667dd2b0e051c0e73f9d to your computer and use it in GitHub Desktop.

About CPU Architectures

Due to the wide variety of CPU architectures available, it's essential to understand the different identifiers and aliases used to represent these architectures in various environments. This guide provides an overview of common CPU architectures, their identifiers, and how they are represented in Docker, uname -m, and other contexts. This woulld be like a guide to multi-platform builds in Docker.

In a nutshell

There's a wide variety of architectures and identifiers/aliases, when we look at the most common ones, we have to take note of the following:

  • aarch64 - linux/arm64

  • armv7l - linux/arm/v7 (armhf, armv7, arm32 )

  • armhf - linux/arm/v7

  • amd64 - linux/amd64

  • i386 - linux/386

    • x86_64: AMD64 (64-bit)
    • i686 or i386: x86 (32-bit)
    • aarch64: ARM64 (64-bit)
    • armv7l: ARMv7 (32-bit)
    • armv6l: ARMv6 (32-bit)

These are the most common to build for.

What will the guide cover?

The next part answers the following questions:

  • What are the different CPU architectures and their identifiers/aliases?
  • How do these architectures differ in terms of bitness (32-bit vs. 64-bit) and use cases?
  • How are these architectures represented in various environments like Docker, uname -m, and others?
  • What are some common devices and their corresponding architectures?
  • How can you identify the architecture of a system programmatically?
  • How will we handle the different architectures in our Docker Buildx environment?

Table of Contents

Overview of CPU Architectures and Identifiers

1. x86 Architectures

Architecture Name uname -m Output Docker Platform Bits Aliases Notes
x86 (32-bit) i386, i686 linux/386 32-bit x86, i686, i386 Common in older PCs and some embedded systems.
x86_64 (64-bit) x86_64 linux/amd64 64-bit amd64, x86_64, x64 Standard 64-bit architecture for desktops, laptops, and servers.

2. ARM Architectures

Architecture Name uname -m Output Docker Platform Bits Aliases ARM Version Notes
ARMv6 (32-bit) armv6l linux/arm/v6 32-bit armel ARMv6 Used in early Raspberry Pi models (e.g., Raspberry Pi 1 and Zero).
ARMv7 (32-bit) armv7l linux/arm/v7 32-bit armhf, armv7, arm32 ARMv7 Common in Raspberry Pi 2, 3 (32-bit mode), and many embedded devices.
ARMv8-A (64-bit) aarch64 linux/arm64 64-bit arm64, aarch64 ARMv8 Used in Raspberry Pi 3 (64-bit mode), Pi 4, modern smartphones, and servers.
ARMv8-A (32-bit mode) armv8l linux/arm/v8 32-bit armv8l ARMv8 ARMv8 processors running in 32-bit mode (less common).
ARMv5 (32-bit) armv5tel linux/arm/v5 32-bit armv5 ARMv5 Older ARM architecture, less common today.

3. Other Architectures

Architecture Name uname -m Output Docker Platform Bits Aliases Notes
PowerPC 64-bit ppc64 linux/ppc64 64-bit ppc64 Used in some IBM systems and older Apple hardware.
PowerPC 64-bit LE ppc64le linux/ppc64le 64-bit ppc64le Little-endian variant of PowerPC 64-bit; used in modern IBM systems.
s390x s390x linux/s390x 64-bit s390x Used in IBM mainframe systems.
ARM 32-bit Hard Float N/A linux/armhf 32-bit armhf Hard float ABI; often overlaps with armv7 (armv7l).
RISC-V 64-bit riscv64 linux/riscv64 64-bit riscv64 Emerging open-source architecture; increasingly supported in Docker and other platforms.

Detailed Explanation of ARM Architectures

ARM architectures are particularly confusing due to various versions, modes, and naming conventions. Here's a breakdown:

ARM Versions and Variants

  • ARMv5 (ARM5):

    • uname -m: armv5tel
    • Docker Platform: linux/arm/v5
    • Notes: Very old; rarely used today.
  • ARMv6 (ARM6):

    • uname -m: armv6l
    • Docker Platform: linux/arm/v6
    • Notes: Used in Raspberry Pi 1 and Pi Zero.
  • ARMv7 (ARM7):

    • uname -m: armv7l
    • Docker Platform: linux/arm/v7
    • Aliases: armhf (ARM hard float)
    • Notes: Supports hardware floating-point operations; common in many 32-bit ARM devices.
  • ARMv8 (ARM8) in 64-bit Mode:

    • uname -m: aarch64
    • Docker Platform: linux/arm64
    • Aliases: arm64, aarch64
    • Notes: Fully 64-bit; used in modern ARM-based systems like Raspberry Pi 3 and 4 when running 64-bit OS.
  • ARMv8 (ARM8) in 32-bit Mode:

    • uname -m: armv8l
    • Docker Platform: linux/arm/v8 (less common)
    • Notes: ARMv8 processors can run in a 32-bit mode for compatibility.

Understanding ARM Identifiers

  • uname -m Outputs:

    • armv6l: ARMv6 Little-endian.
    • armv7l: ARMv7 Little-endian.
    • aarch64: ARMv8 in 64-bit mode.
    • armv8l: ARMv8 in 32-bit mode (less common).
  • Docker Platforms:

    • linux/arm/v6: Targets ARMv6 devices.
    • linux/arm/v7: Targets ARMv7 devices.
    • linux/arm64: Targets ARMv8 64-bit devices.
  • Notes on Variants:

    • armhf: Refers to ARM hard-float ABI, typically associated with ARMv7.
    • armel: Refers to ARM soft-float ABI, associated with older ARM architectures like ARMv5 and ARMv6.
    • aarch64: Standard identifier for 64-bit ARM architecture.

Examples of Common Devices and Their Architectures

Device Architecture uname -m Output Docker Platform Notes
Raspberry Pi Zero ARMv6 armv6l linux/arm/v6 Uses ARMv6 CPU.
Raspberry Pi 2 ARMv7 armv7l linux/arm/v7 32-bit ARMv7 CPU.
Raspberry Pi 3 (32-bit OS) ARMv7 armv7l linux/arm/v7 Running 32-bit OS on ARMv8 hardware.
Raspberry Pi 3 (64-bit OS) ARMv8 aarch64 linux/arm64 Running 64-bit OS to leverage ARMv8 capabilities.
Raspberry Pi 4 ARMv8 aarch64 linux/arm64 Supports both 32-bit and 64-bit OS; 64-bit recommended.
Modern Smartphones (Android) ARMv8 aarch64 linux/arm64 Most use 64-bit ARM processors.
Desktop PCs and Laptops x86_64 x86_64 linux/amd64 Standard 64-bit architecture.

Summary of Architectures and Compatibility

Bitness

  • 32-bit Architectures:

    • ARMv5, ARMv6, ARMv7, x86
    • Limitation: Can address up to 4 GB of RAM.
  • 64-bit Architectures:

    • ARMv8 (in 64-bit mode), x86_64
    • Advantage: Can address more than 4 GB of RAM; improved performance.

ARM Version Compatibility

  • ARMv7 is backward compatible with ARMv6 and ARMv5, but binaries compiled for ARMv7 may not run on ARMv6 devices due to instruction differences.

  • ARMv8 can run in 32-bit mode, supporting ARMv7 binaries, but to leverage 64-bit capabilities, software must be compiled for ARM64 (aarch64).


Practical Implications for Docker and Buildx

  • Building Images for Specific Platforms:

    • Use the appropriate Docker platform identifier to target the desired architecture.

    • Example Build Commands:

      • Build for ARMv7 (32-bit):

        docker buildx build --platform linux/arm/v7 -t yourimage:armv7 .
      • Build for ARM64 (ARMv8 64-bit):

        docker buildx build --platform linux/arm64 -t yourimage:arm64 .
      • Build for x86_64:

        docker buildx build --platform linux/amd64 -t yourimage:amd64 .
  • Determining Node Capabilities:

    • Nodes can build images for their native architecture without emulation.

    • Nodes with uname -m output of aarch64 can build for linux/arm64.

    • Nodes with uname -m output of armv7l can build for linux/arm/v7.

    • Nodes with uname -m output of x86_64 can build for linux/amd64.

  • Avoiding QEMU Emulation:

    • Exclude platforms that are not natively supported by your nodes to prevent Buildx from attempting to use QEMU.

    • Example: If a node is armv7l, avoid assigning it to build linux/amd64 images.


How to Identify Architectures Programmatically

You can use the following commands on each node to determine their architecture:

1. Using uname

uname -m
  • Outputs:

    • x86_64: AMD64 (64-bit)
    • i686 or i386: x86 (32-bit)
    • aarch64: ARM64 (64-bit)
    • armv7l: ARMv7 (32-bit)
    • armv6l: ARMv6 (32-bit)

2. Using dpkg (on Debian-based systems)

dpkg --print-architecture
  • Outputs:

    • amd64: AMD64
    • armhf: ARM hard float (usually ARMv7)
    • arm64: ARM64

3. Using lscpu

lscpu | grep 'Architecture\|Byte Order\|CPU(s)'
  • Provides detailed CPU information.

Cross-Referencing Architectures

uname -m Architecture Docker Platform Bits Use Cases
x86_64 x86_64 linux/amd64 64-bit Desktop PCs, servers, cloud instances.
i686/i386 x86 (32-bit) linux/386 32-bit Older PCs, some embedded systems.
armv6l ARMv6 linux/arm/v6 32-bit Raspberry Pi Zero, early ARM devices.
armv7l ARMv7 linux/arm/v7 32-bit Raspberry Pi 2, some smartphones, tablets.
aarch64 ARMv8 (64-bit) linux/arm64 64-bit Raspberry Pi 3 & 4 (64-bit OS), servers.
ppc64le PowerPC 64 LE linux/ppc64le 64-bit IBM Power Systems, some high-performance.
s390x IBM Z (s390x) linux/s390x 64-bit IBM mainframe systems.

Conclusion

Understanding the different CPU architectures and their identifiers is crucial for correctly configuring your Docker Buildx environment and ensuring that your builds are executed on the appropriate nodes without relying on QEMU emulation. Here's what you need to remember:

  • Match Node Architecture to Target Platform: Ensure each Buildx node builds images for the platforms it natively supports.

  • Use Consistent Identifiers: Refer to architectures using standard identifiers in your configurations and scripts.

  • Test and Verify: Always test your builds to confirm that the images work correctly on the target devices.


If you have any more questions or need further clarification on any of these architectures, feel free to ask!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment