簡體   English   中英

如何將 Rust 代碼編譯為裸機 32 位 x86 (i686) 代碼? 我應該使用什么編譯目標?

[英]How to compile Rust code to bare metal 32 bit x86 (i686) code? What compile target should I use?

我想使用 cargo/Rust 為 x86(又名 i686 又名 x86_64 在 32 位模式下)編譯裸機 32 位代碼。 我需要什么目標? 官方支持的目標列表中我找不到任何東西,這很實用。

不幸的是,Rust 編譯器沒有內置目標定義 [ Rust nightly 1.54, June 2021 ],但您可以提供自定義目標定義:

<項目根>/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具有 32 位 x86 代碼的裸機二進制文件。

// 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 doesn't output anything
/// to the object file. I don't know why it is like this.
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" ]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM