rust - 如何将 Rust 代码编译为裸机 32 位 x86 (i686) 代码?我应该使用什么编译目标?
问题描述
我想使用 cargo/Rust 为 x86(又名 i686 又名 x86_64 在 32 位模式下)编译裸机 32 位代码。我需要什么目标?在官方支持的目标列表中我找不到任何东西,这很实用。
解决方案
不幸的是,Rust 编译器没有为此提供内置目标定义 [ Rust nightly 1.54, June 2021 ],但您可以提供自定义目标定义:
<project-root>/x86-unknown-bare_metal.json
{
"llvm-target": "i686-unknown-none",
"data-layout": "e-m:e-i32:32-f80:128-n8:16:32-S128-p:32:32",
"arch": "x86",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"disable-redzone": true,
"features": "+soft-float,+sse"
}
此定义将指针宽度设置为 32,旨在编译可用于早期 x86 引导过程的代码(当您已经处于 32 位保护模式时)。我不是 100% 确定“功能”,因为它们可能取决于您想要做什么/需要什么。i686
指的是 32 位模式下的 x86_64,这里解释了数据布局。
此外,您应该添加文件
<项目根>/.cargo/config.toml
[unstable]
# cross compile core library for custom target
build-std = ["core", "compiler_builtins"]
build-std-features = ["compiler-builtins-mem"]
[build]
# points to file in project root
target = "x86-unknown-bare_metal.json"
现在您可以使用cargo build
.
// disable rust standard library
#![no_std]
// disables Rust runtime init,
#![no_main]
// see https://docs.rust-embedded.org/embedonomicon/smallest-no-std.html
#![feature(lang_items)]
// see https://docs.rust-embedded.org/embedonomicon/smallest-no-std.html
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
use core::panic::PanicInfo;
use core::sync::atomic;
use core::sync::atomic::Ordering;
#[no_mangle]
/// The name **must be** `_start`, otherwise the compiler throws away all code as unused.
/// The name can be changed by passing a different entry symbol as linker argument.
fn _start() -> ! {
loop {}
}
#[inline(never)]
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {
atomic::compiler_fence(Ordering::SeqCst);
}
}
为方便起见,您还应该添加
<project-root>/rust-toolchain.toml
# With this file, another toolchain to the currently selected one will be used, when you execute `cargo build`.
# https://rust-lang.github.io/rustup/overrides.html
[toolchain]
# equals to rust nightly 1.54 as of the release day 2021-05-10
channel = "nightly-2021-05-10"
components = [ "rust-src", "rust-std", "rustc", "cargo" ]
推荐阅读
- matlab - 扩展卡尔曼滤波器预测更新时间
- python - 从文本中的缩写中查找首字母缩写词
- c# - 在 UI 元素设置期间忽略属性设置调用
- json - 将 json 列表发布到烧瓶路由时出现 TypeError
- mysql - 我正在尝试在触发器上使用算术,但我的触发器不起作用
- c# - Swashbuckle 多态性需要鉴别器作为更新时的第一个属性
- java - 我正在开发一个 spring mvc 项目,我想从两个下拉框和一个文本框提交值
- android - 有什么地方可以上传两个要翻译的字符串 xml 文件吗?
- javascript - 检查样本库/文档 Vue JS 中是否出现相同的值
- python - Django没有从CSS文件加载图像