Rust on Bare-metal Raspberry Pi を写経してる時の詰まり処

2022/04/11に公開

Rust on Bare-metal Raspberry Pi Vol.1+2+3を写経してる時に詰まったので残しておきます。

本書では1.47-nightlyで動作確認をしているようなので、1.62.0-nightlyでは普通にやるとコンパイルエラーが大量にでてサンプルコードがコンパイルできないよというお話。
なお忘れる前に書いておきたかったためコンパイル通るところまでしか確認はしていません。

toolchains

とりあえず下記のような状態で確認。

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu
nightly-x86_64-unknown-linux-gnu (default)

installed targets for active toolchain
--------------------------------------

aarch64-unknown-none
x86_64-unknown-linux-gnu

active toolchain
----------------

nightly-x86_64-unknown-linux-gnu (default)
rustc 1.62.0-nightly (8f36334ca 2022-04-06)

エラー内容

ほぼ下記エラーがすべてなのでこれの解消がメイン。

error[E0635]: unknown feature `llvm_asm`
  --> raspi3_boot/src/lib.rs:30:12
   |
30 | #![feature(llvm_asm)]

修正箇所

Cargo.toml

エラーを見ると一つだけ~/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-a-3.0.5/*あたりにllvm_asm!のエラーがいるのでバージョンを確認。
現状最新のcortex_aが7.2.0なのでCargo.tomlを修正。

Cargo.toml
-cortex-a = { version = "3.0.x"}
+cortex-a = { version = "7.2.x"}

raspi3_boot・main

cortex_aがバージョンアップにてエラーがなくなったので、
どのように修正されたかを参考にしつつ各ファイルにあるllvm_asm!を修正。

cortex_a
- llvm_asm!("nop" :::: "volatile"); //3.0.5
+ core::arch::asm!("nop", options(nomem, nostack)); //7.2.0

#![feature()]に関しては削除のみで対応。
llvm_asmとglobal_asmに関してはuseする(後述)から多分大丈夫。
著者のGitHubのIssueでは少し前のツールチェーンを使うのが手っ取り早いと書いてあるがとりあえずコンパイルを通すことのみ考える。
ということで一旦const_fnは削除のみ。

error: the feature `global_asm` has been stable since 1.59.0 and no longer requires an attribute to enable
  --> raspi3_boot/src/lib.rs:29:12
   |
29 | #![feature(global_asm)]
   |            ^^^^^^^^^^
   |
error[E0557]: feature has been removed
  --> src/main.rs:29:12
   |
29 | #![feature(const_fn)]
   |            ^^^^^^^^ feature has been removed
   |
   = note: split into finer-grained feature gates

featureの削除・llvm_asm!の置き換え
全部乗せるのはさすがにいかがなものかと思ったので抜粋。
useしなくてもcore::arch::asm!って書いても可。

respi3_boot/*
-#![feature(global_asm)]
-#![feature(llvm_asm)]
+use core::arch::asm;
+use core::arch::global_asm;

-    llvm_asm!("***");
+    asm!("***");

src直下のファイルで7か所ほど下記のような修正を実施してます。

src/*
             unsafe {
-                llvm_asm!("wfe" :::: "volatile");
+                core::arch::asm!("wfe", options(nomem, nostack));
             } // If UART fails, abort early
	     
-            unsafe { llvm_asm!("nop" :::: "volatile") };
+            unsafe {
+                core::arch::asm!("nop", options(nomem, nostack));
+                }; 

修正後

warningはあれどとりあえずimgが作れたので多分大丈夫

cargo clean
cargo build --release
   Compiling proc-macro2 v1.0.37
   Compiling unicode-xid v0.2.2
   Compiling syn v1.0.91
   Compiling proc-macro-hack v0.5.19
   Compiling panic-abort v0.3.2
   Compiling tock-registers v0.7.0
   Compiling tock-registers v0.5.0
   Compiling r0 v0.2.2
   Compiling static_assertions v1.1.0
   Compiling nt_allocator v0.1.0 (https://github.com/naotaco/nt-global-alloc-rs.git#6f96e678)
   Compiling raspi3_boot v0.1.0 (/home/User/rust-on-bare-metal-raspi3-samples/raspi3_boot)
   Compiling cortex-a v7.2.0
   Compiling register v0.5.1
warning: unknown feature specified for `-Ctarget-feature`: `fp-armv8`
  |
  = note: it is still passed through to the codegen backend
  = note: consider filing a feature request

warning: `raspi3_boot` (lib) generated 1 warning
   Compiling quote v1.0.17
   Compiling arr_macro_impl v0.1.3
   Compiling arr_macro v0.1.3
   Compiling kernel8 v0.1.0 (/home/User/rust-on-bare-metal-raspi3-samples)
warning: `kernel8` (bin "kernel8") generated 1 warning (1 duplicate)
    Finished release [optimized] target(s) in 7.55s
cargo objcopy --release -- --strip-all -O binary kernel8.img
    Finished release [optimized] target(s) in 0.05s
warning: unknown feature specified for `-Ctarget-feature`: `fp-armv8`
  |
  = note: it is still passed through to the codegen backend
  = note: consider filing a feature request

warning: 1 warning emitted

warning: unknown feature specified for `-Ctarget-feature`: `fp-armv8`
  |
  = note: it is still passed through to the codegen backend
  = note: consider filing a feature request

warning: 1 warning emitted

懸念点

cortex-aを参考に修正をしたが、そもそもllvm_asm!で行ってたことを理解してないのでコンパイルは通るしimgを焼けたとしても動作上の問題が発生する可能性はどうしても否めない。
Unstable bookの3.14 asmを見ると多分大丈夫っぽいですが...
下記該当箇所引用

#![feature(asm, llvm_asm)]
unsafe {
    asm!("fldcw [{}]", in(reg) &control, options(nostack));

    // Previously this would have been written with the deprecated `llvm_asm!` like this
    llvm_asm!("fldcw $0" :: "m" (control) :: "volatile");
}

Discussion