Use aarch64-unknown-none target in nightly 🎉

We have a generic target for writing bare-metal code
for 64-bit ARM architectures in upstream Rust now.

Use it to get rid of the fully custom target spec.

\o/
pull/9/head
Andre Richter 6 years ago
parent 5a71b00422
commit 0d75a8eaf3
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -22,6 +22,71 @@ However, since we want to use the toolchain that is delivered with `rustup` as
much as possible, we are already setting up a Rust crate. This allows us to use
`rustc` and LLVM's `lld.ld` linker to process our assembly file.
## Target
The Raspberry Pi 3 features a processor that uses ARM's `AArch64` architecture.
Conveniently, Rust already provides a generic target for bare-metal aarch64 code
that we can leverage. It is called [aarch64-unknown-none].
[aarch64-unknown-none]: https://github.com/andre-richter/rust/blob/master/src/librustc_target/spec/aarch64_unknown_none.rs
In the `Makefile`, we select this target in various places by passing it to
cargo using the `--target` cmdline argument.
Additionally, we provide a config file in `.cargo/config` were we make further
specializations:
```toml
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]
```
The first line tells rustc to use our custom `link.ld` linker script. The second
line instructs the compiler to not use floating point operations. This is a
common choice when writing an operating system kernel. If floating point is not
explicitly disabled, it is possible that the compiler uses auto-vectorization to
optimize, for example, operations on array data structures. This would
implicitly result in use of floating point registers and operations. However,
since it is very costly to save and restore floating point registers during
context-switches, use of fp is usually disabled from the get go to save the
cycles and optimize the kernel for fast context switching.
Finally, the third arguments specifies the exact CPU type that is used in
Raspberry Pi 3, so that the compiler can optimize for it.
Since the `aarch64-unknown-none` target is not shipped with an associated
precompiled standard library, and since we anyways modify the target via the
`.cargo/config` file, we are using [Xargo][xargo] to compile our own standard
library. This way, we can ensure that our bare-metal code is optimized
throughout.
[xargo]: https://github.com/japaric/xargo
## Linker script `link.ld`
We just set the base address where our kernel8.img will be loaded, and we put
the only section we have there, which is `.text.boot`. Important note, for
AArch64 the load address is **0x80_000**, and not **0x80_00** as with AArch32.
## Makefile
Our Makefile has a few useful targets:
- `kernel8` compiles the crate either in release or debug mode. For the latter,
add `DEBUG=1` before invoking make, e.g. `DEBUG=1 make`
- `kernel8.img` uses `cargo objcopy` to generate our kernel binary. Citing the [binutils documentation][butils]:
- "_When objcopy generates a raw binary file, it will essentially produce a
memory dump of the contents of the input object file. All symbols and
relocation information will be discarded. The memory dump will start at
the load address of the lowest section copied into the output file._"
- `qemu` loads our kernel into an emulated RPi3, and shows as output the
assembler blocks that are executed. This happens in a docker container.
[butils]: https://sourceware.org/binutils/docs/binutils/objcopy.html
## main.rs
We define the crate to not use the standard library (`#![no_std]`), indicate
@ -50,40 +115,3 @@ sleep until an asynchronous event occurs. If that happens, we jump right back to
Note that the CPU has 4 cores. All of them will execute the same infinite loop
for now.
## aarch64-raspi3-none-elf.json
This is our custom target definition of the RPi3 for [Xargo][xargo]. It also
includes a directive to use the `link.ld` linker script.
```json
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
```
[xargo]: https://github.com/japaric/xargo
## Makefile
Our Makefile has a few useful targets:
- `kernel8` compiles the crate either in release or debug mode. For the latter,
add `DEBUG=1` before invoking make, e.g. `DEBUG=1 make`
- `kernel8.img` uses our cross-toolchain's `objcopy` in the docker container to
generate our kernel binary. Citing the [binutils documentation][butils]:
- "_When objcopy generates a raw binary file, it will essentially produce a
memory dump of the contents of the input object file. All symbols and
relocation information will be discarded. The memory dump will start at
the load address of the lowest section copied into the output file._"
- `qemu` loads our kernel into an emulated RPi3, and shows as output the
assembler blocks that are executed. This happens in another docker container.
[butils]: https://sourceware.org/binutils/docs/binutils/objcopy.html
## Linker script `link.ld`
We just set the base address where our kernel8.img will be loaded, and we put
the only section we have there, which is `.text.boot`. Important note, for
AArch64 the load address is **0x80_000**, and not **0x80_00** as with AArch32.

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.

@ -0,0 +1,6 @@
[target.aarch64-unknown-none]
rustflags = [
"-C", "link-arg=-Tlink.ld",
"-C", "target-feature=-fp-armv8",
"-C", "target-cpu=cortex-a53",
]

@ -22,7 +22,7 @@
# SOFTWARE.
#
TARGET = aarch64-raspi3-none-elf
TARGET = aarch64-unknown-none
OBJCOPY = cargo objcopy --
OBJCOPY_PARAMS = --strip-all -O binary

@ -1,33 +0,0 @@
{
"arch": "aarch64",
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"--script=link.ld"
]
},
"llvm-target": "aarch64-unknown-none",
"no-compiler-rt": true,
"features": "+a53,+strict-align",
"max-atomic-width": 128,
"os": "none",
"panic": "abort",
"panic-strategy": "abort",
"relocation-model": "pic",
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"disable-redzone": true,
"abi-blacklist": [
"stdcall",
"fastcall",
"vectorcall",
"thiscall",
"win64",
"sysv64"
]
}

Binary file not shown.
Loading…
Cancel
Save