Skip to content

Commit 72fee89

Browse files
authored
Rollup merge of #146453 - thejpster:arm-linux-docs, r=petrochenkov
Add general arm-linux.md platform doc. Adds a new page that covers all 32-bit Arm Linux systems. This means that we can reduce the amount of information required in the target specific pages to just the Tier level, the maintainer, and any specific details for that target. I have no changed those pages yet, though. Let's start with this.
2 parents 82e9e54 + 4d273c4 commit 72fee89

File tree

6 files changed

+234
-4
lines changed

6 files changed

+234
-4
lines changed

src/doc/rustc/src/SUMMARY.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
- [aarch64_be-unknown-none-softfloat](platform-support/aarch64_be-unknown-none-softfloat.md)
5353
- [aarch64_be-unknown-linux-musl](platform-support/aarch64_be-unknown-linux-musl.md)
5454
- [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md)
55-
- [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md)
5655
- [arm-none-eabi](platform-support/arm-none-eabi.md)
5756
- [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
5857
- [armv5te-none-eabi](platform-support/armv5te-none-eabi.md)
@@ -65,12 +64,14 @@
6564
- [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md)
6665
- [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md)
6766
- [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md)
68-
- [armv5te-unknown-linux-gnueabi](platform-support/armv5te-unknown-linux-gnueabi.md)
67+
- [arm\*-unknown-linux-\*](./platform-support/arm-linux.md)
68+
- [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md)
69+
- [armv5te-unknown-linux-gnueabi](platform-support/armv5te-unknown-linux-gnueabi.md)
70+
- [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
71+
- [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
6972
- [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
7073
- [armv7-rtems-eabihf](platform-support/armv7-rtems-eabihf.md)
7174
- [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
72-
- [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
73-
- [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
7475
- [armv7a-vex-v5](platform-support/armv7a-vex-v5.md)
7576
- [\*-android and \*-androideabi](platform-support/android.md)
7677
- [\*-linux-ohos](platform-support/openharmony.md)
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# Arm Linux support in Rust
2+
3+
The Arm Architecture has been around since the mid-1980s, going through nine
4+
major revisions, many minor revisions, and spanning both 32-bith and 64-bit
5+
architectures. This page covers 32-bit Arm platforms that run some form of
6+
Linux (but not Android). Those targets are:
7+
8+
* `arm-unknown-linux-gnueabi`
9+
* `arm-unknown-linux-gnueabihf`
10+
* `arm-unknown-linux-musleabi`
11+
* `arm-unknown-linux-musleabihf`
12+
* [`armeb-unknown-linux-gnueabi`](armeb-unknown-linux-gnueabi.md)
13+
* `armv4t-unknown-linux-gnueabi`
14+
* [`armv5te-unknown-linux-gnueabi`](armv5te-unknown-linux-gnueabi.md)
15+
* `armv5te-unknown-linux-musleabi`
16+
* `armv5te-unknown-linux-uclibceabi`
17+
* `armv7-unknown-linux-gnueabi`
18+
* `armv7-unknown-linux-gnueabihf`
19+
* `armv7-unknown-linux-musleabi`
20+
* `armv7-unknown-linux-musleabihf`
21+
* `armv7-unknown-linux-ohos`
22+
* [`armv7-unknown-linux-uclibceabi`](armv7-unknown-linux-uclibceabi.md)
23+
* [`armv7-unknown-linux-uclibceabihf`](armv7-unknown-linux-uclibceabihf.md)
24+
* `thumbv7neon-unknown-linux-gnueabihf`
25+
* `thumbv7neon-unknown-linux-musleabihf`
26+
27+
Some of these targets have dedicated pages and some do not. This is largely
28+
due to historical accident, or the enthusiasm of the maintainers. This
29+
document attempts to cover all the targets, but only in broad terms.
30+
31+
To make sense of this list, the architecture and ABI component of the
32+
`<architecture>-unknown-linux-<abi>` tuple will be discussed separately.
33+
34+
The second part of the tuple is `unknown` because these systems don't come
35+
from any one specific vendor (like `powerpc-ibm-aix` or
36+
`aarch64-apple-darwin`). The third part is `linux`, because this page only
37+
discusses Linux targets.
38+
39+
## Architecture Component
40+
41+
* `arm`
42+
* `armeb`
43+
* `armv4t`
44+
* `armv5te`
45+
* `armv7`
46+
* `thumbv7neon`
47+
48+
The architecture component simply called `arm` corresponds to the Armv6
49+
architecture - that is, version 6 of the Arm Architecture as defined in
50+
version 6 of the Arm Architecture Reference Manual (the Arm ARM). This was the
51+
last 'legacy' release of the Arm architecture, before they split into
52+
Application, Real-Time and Microcontroller profiles (leading to Armv7-A,
53+
Armv7-R and Armv7-M). Processors that implement the Armv6 architecture include
54+
the ARM1176JZF-S, as found in BCM2835 SoC that powers the Raspberry Pi Zero.
55+
Arm processors are generally fairly backwards compatible, especially for
56+
user-mode code, so code compiled for the `arm` architecture should also work
57+
on newer ARMv7-A systems, or even 64/32-bit Armv8-A systems.
58+
59+
The `armeb` architecture component specifies an Armv6 processor running in Big
60+
Endian mode (`eb` is for big-endian - the letters are backwards because
61+
engineers used to little-endian systems perceive big-endian numbers to be
62+
written into memory backwards, and they thought it was funnier like that).
63+
Most Arm processors can operate in either little-endian or big-endian mode and
64+
little-endian mode is by far the most common. However, if for whatever reason
65+
you wish to store your Most Significant Bytes first, these targets are
66+
available. They just aren't terribly well tested, or compatible with most
67+
existing pre-compiled Arm libraries.
68+
69+
Targets that start with `armv4t` are for processors implementing the Armv4T
70+
architecture from 1994. These include the ARM7TDMI, as found in the Nokia 6110
71+
brick-phone and the Game Boy Advance. The 'T' stands for *Thumb* and indicate
72+
that the processors can execute smaller 16-bit versions of some of the 32-bit
73+
Arm instructions. Because a Thumb is like a small version of an Arm.
74+
75+
Targets that start with `armv5te` are for processors implementing the Armv5TE
76+
architecture. These are mostly from the ARM9 family, like the ARM946E-S found
77+
in the Nintendo DS. If you are programming an Arm machine from the early
78+
2000s, this might be what you need.
79+
80+
The `armv7` is arguably a misnomer, and it should be `armv7a`. This is because
81+
it corresponds to the Application profile of Armv7 (i.e. Armv7-A), as opposed
82+
to the Real-Time or Microcontroller profile. Processors implementing this
83+
architecture include the Cortex-A7 and Cortex-A8.
84+
85+
The `thumbv7neon` component indicates support for a processor that implements
86+
ARMv7-A (the same as `armv7`), it generates Thumb instructions (technically
87+
Thumb-2, also known as the T32 ISA) as opposed to Arm instructions (also known
88+
as the A32 ISA). These instructions are smaller, giving more code per KB of
89+
RAM, but may have a performance penalty if they take two instructions to do
90+
something Arm instructions could do in one. It's a complex trade-off and you
91+
should be doing benchmarks to work out which is better for you, if you
92+
strongly care about code size and/or performance. This component also enables
93+
support for Arm's SIMD extensions, known as Neon. These extensions will
94+
improve performance for certain kinds of repetitive operations.
95+
96+
## ABI Component
97+
98+
* `gnueabi`
99+
* `gnueabihf`
100+
* `musleabi`
101+
* `musleabihf`
102+
* `ohos`
103+
* `uclibceabi`
104+
* `uclibceabihf`
105+
106+
You will need to select the appropriate ABI to match the system you want to be
107+
running this code on. For example, running `eabihf` code on an `eabi` system
108+
will not work correctly.
109+
110+
The `gnueabi` ABI component indicates support for using the GNU C Library
111+
(glibc), and the Arm Embedded ABI (EABI). The EABI is a replacement for the
112+
original ABI (now called the Old ABI or OABI), and it is the standard ABI for
113+
32-bit Arm systems. With this ABI, function parameters that are `f32` or `f64`
114+
are passed as if they were integers, instead of being passed via in FPU
115+
registers. Generally these targets also disable the use of the FPU entirely,
116+
although that isn't always true.
117+
118+
The `gnueabihf` ABI component is like `gnueabi`, except that it support the
119+
'hard-float' of the EABI. That is, function parameters that are `f32` or `f64`
120+
are passed in FPU registers. Naturally, this makes the FPU mandatory.
121+
122+
Most 'desktop' Linux distributions (Debian, Ubuntu, Fedora, etc) use the GNU C
123+
Library and so you should probably select either `gnueabi` or `gnueabihf`,
124+
depending on whether your distribution is using 'soft-float' (EABI) or
125+
'hard-float' (EABIHF). Debian happens to offer
126+
[both](https://wiki.debian.org/ArmEabiPort)
127+
[kinds](https://wiki.debian.org/ArmHardFloatPort).
128+
129+
The `musleabi` and `musleabihf` ABI components offer support for the [musl C
130+
library](https://musl.libc.org/). This C library can be used to create 'static
131+
binaries' that have no run-time library requirements (a feature that glibc
132+
does not support). There are soft-float (`eabi`) and hard-float (`eabihf`)
133+
variants, as per the `gnu*` targets above.
134+
135+
The `uclibceabi` and `uclibceabihf` ABI components are for the [uClibc-ng C
136+
library](https://uclibc-ng.org/). This is sometimes used in light-weight
137+
embedded Linux distributions, like those created with
138+
[buildroot](https://www.buildroot.org/).
139+
140+
## Cross Compilation
141+
142+
Unfortunately, 32-bit Arm machines are generally not the fastest around, and
143+
they don't have much RAM. This means you are likely to be cross-compiling.
144+
145+
To do this, you need to give Rust a suitable linker to use - one that knows
146+
the Arm architecture, and more importantly, knows where to find a suitable C
147+
Library to link against.
148+
149+
To do that, you can add the `linker` property to your `.cargo/config.toml`.
150+
Typically you would refer to a suitable copy of GCC that has built as a
151+
cross-compiler, alongside a C library.
152+
153+
```toml
154+
[target.arm-unknown-linux-gnueabi]
155+
linker = "arm-linux-gnueabi-gcc"
156+
```
157+
158+
On Debian Linux, you could install such a cross-compilation toolchain with
159+
`apt install gcc-arm-linux-gnueabi`. For more exotic combinations, you might
160+
need to build a bespoke version of GCC using [crosstool-ng].
161+
162+
[crosstool-ng]: https://github.com/crosstool-ng/crosstool-ng
163+
164+
Note that for GCC, all 32-bit Arm architectures are handled in the same build
165+
- there are no separate Armv4T or Armv6 builds of GCC. The architecture is
166+
selected with flags, like `-march=armv6`, but they aren't required for the
167+
linker.
168+
169+
Let's assume we are on some Debian machine, and we want to build a basic Arm
170+
Linux binary for a distribution using the GNU C Library, targeting Armv6 with
171+
a hard-float ABI. Such a binary should work on a Raspberry Pi, for example.
172+
The commands are:
173+
174+
```bash
175+
sudo apt install -y gcc-arm-linux-gnueabihf
176+
rustup target add arm-unknown-linux-gnueabihf
177+
cargo new --bin armdemo
178+
cd armdemo
179+
mkdir .cargo
180+
cat > .cargo/config.toml << EOF
181+
[target.arm-unknown-linux-gnueabihf]
182+
linker = "arm-linux-gnueabihf-gcc"
183+
EOF
184+
cargo build --target=arm-unknown-linux-gnueabihf
185+
```
186+
187+
This will give us our ARM Linux binary for the GNU C Library with a soft-float ABI:
188+
189+
```console
190+
$ file ./target/arm-unknown-linux-gnueabi/debug/armdemo
191+
./target/arm-unknown-linux-gnueabi/debug/armdemo: ELF 32-bit LSB pie
192+
executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter
193+
/lib/ld-linux.so.3, BuildID[sha1]=dd0b9aa5ae876330fd4e2fcf393850f083ec7fcd,
194+
for GNU/Linux 3.2.0, with debug_info, not stripped
195+
```
196+
197+
If you are building C code as part of your Rust project, you may want to
198+
direct `cc-rs` to use an appropriate cross-compiler with the `CROSS_COMPILE`
199+
environment variable. You may also want to set the CFLAGS environment variable
200+
for the target. For example:
201+
202+
```bash
203+
export CROSS_COMPILE=arm-linux-gnueabi
204+
export CFLAGS_arm_unknown_linux_gnueabi="-march=armv6"
205+
```
206+
207+
(Note that the dashes (`-`) turn to underscores (`_`) to form the name of the
208+
CFLAGS environment variable)
209+
210+
If you are building for a Tier 3 target using `-Zbuild-std` (on Nightly Rust),
211+
you need to set these variables as well:
212+
213+
```bash
214+
export CXX_arm_unknown_linux_gnueabi=arm-linux-gnueabi-g++
215+
export CC_arm_unknown_linux_gnueabi=arm-linux-gnueabi-gcc
216+
cargo +nightly build -Zbuild-std --target=arm-unknown-linux-gnueabi
217+
```

src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
Target for cross-compiling Linux user-mode applications targeting the Arm BE8 architecture.
55

6+
See [`arm-linux`](arm-linux.md) for information applicable to all Arm Linux
7+
targets.
8+
69
## Overview
710
BE8 architecture retains the same little-endian ordered code-stream used by conventional little endian Arm systems, however the data accesses are in big-endian. BE8 is used primarily in high-performance networking applications where the ability to read packets in their native "Network Byte Order" is important (many network protocols transmit data in big-endian byte order for their wire formats).
811

src/doc/rustc/src/platform-support/armv5te-unknown-linux-gnueabi.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
This target supports Linux programs with glibc on ARMv5TE CPUs without
66
floating-point units.
77

8+
See [`arm-linux`](arm-linux.md) for information applicable to all Arm Linux
9+
targets.
10+
811
## Target maintainers
912

1013
There are currently no formally documented target maintainers.

src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
This target supports Armv7-A softfloat CPUs and uses the uclibc-ng standard library. This is a common configuration on many consumer routers (e.g., Netgear R7000, Asus RT-AC68U).
66

7+
See [`arm-linux`](arm-linux.md) for information applicable to all Arm Linux
8+
targets.
9+
710
## Target maintainers
811

912
[@lancethepants](https://github.com/lancethepants)

src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
This tier supports the Armv7-A processor running a Linux kernel and uClibc-ng standard library. It provides full support for rust and the rust standard library.
66

7+
See [`arm-linux`](arm-linux.md) for information applicable to all Arm Linux
8+
targets.
9+
710
## Target Maintainers
811

912
[@skrap](https://github.com/skrap)

0 commit comments

Comments
 (0)