🎇

Rust x linux kernel 開発環境構築手順(2021/06/23)

4 min read

Rust x linux kernel 開発環境構築手順(2021/06/23)

備忘録的に残しておきます。

目的

Rustによって開発可能なLinux Kernelが動作する環境を整備すること

やること

  1. next-linuxのビルド
  2. buildrootによるルートファイルシステムの作成
  3. qemuで実行

大まかに分けて上記3項目でRustによるKernel開発環境が整います。

1. next-linuxのビルド

1.1. rust側の環境構築

とりあえずgccを入れます。

$ sudo yum install gcc

そして、rustをビルドするためのコンパイラがなければ話は進みません。
コンパイラのインストールには、rustupというコンパイラなどのインストーラとバージョン管理を兼ねたツールを使用します。

https://rustup.rs/#

上記リンクに記されたコマンドを実行

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

next-linuxではrustの先行検討版であるnightlyの機能を使用しているため、そのコンパイラをinstallします。

$ rustup toolchain install nightly-2021-05-29
$ rustup default nightly-2021-05-29

ビルド時にC側のコードとのbindingを生成するbindgenをインストールします。

$ cargo install --locked --version 0.56.0 bindgen

cargoとはrustのビルドシステム兼パッケージマネージャで、rustupを先ほどのコマンドで導入している場合は既に入っているはずです。

次に、coreallocのクロスコンパイルに必要なrust標準ライブラリのソースを追加します。

$ rustup component add rust-src

これでビルドに必要なRust側のツールはすべて入りました。次はclangです。

1.2 clangの用意

前述のbindgenというツールはlibclang.soを用いてC側のコードを理解します。そのため、clangをインストールする必要があります。
Clang10.0.1以降を要求する用なので、apt-get環境なら

$ sudo apt-get install clang-11

で入るclang11で事足りると思われます。

しかし、私が使っているCentOS7ではyumで引っ張ってこれるClangのバージョンが古く、ビルド出来ませんでした。
そのため、ソースからビルドしました。

https://clang.llvm.org/get_started.html

公式のGettingstartedに従ってビルド&インストール
今回の環境では優に六時間はかかりました。
また、中間生成物含め100G程の容量を必要とする為、注意しましょう。
私はインストールの段階でroot側の容量が足りないことに気がつき、色々と苦労しました。

これでllvmが入り、Kernelのビルドに必要な環境は整いました。

1.3 linuxのビルド

ソースを取得します。

https://github.com/Rust-for-Linux/linux

今回は上記のリポジトリから取得しました。

$ git clone https://github.com/Rust-for-Linux/linux.git

ここ最近のnightly(2021-05-29以降)によるnext-linux本線のビルドは失敗します。nightlyでconst_fnが削除された影響のようです。Rust-for-Linuxでは既に対応が入っていますが、まだnext-linuxには入っていません。
今回はRust-for-Linuxを用いますが、nightly-2021-02-20を使用してnext-linuxをビルドすることも可能です。

※7/20追記
next-linuxのnext-20210706タグにてビルドの要求バージョンがbeta-2021-06-23へ更新されました。

kernelのビルドにはflex,bison,libssl-devが必要なので合わせてinstallします。

$ sudo yum install flex bison libssl-dev

linux/に入り、configを作成します。

$ make CC=clang defconfig
$ make CC=clang menuconfig

でmenuを表示して設定していきます。
General Setup->Rust Supportを * とします。
上記でRustを用いたKernelのビルドは可能になります。
これだけではもの悲しいので、用意されているサンプルをビルドするようにしましょう。
Kernel Hacking->Sample kernel code->Rust samples以下すべてを *

今回はqemuで動作させる為、必要ない設定(gpuドライバやらpower系やら)は消しておいても良いかも知れません。
最後にsaveしてexitしてconfigの作成は完了です。

config作成が完了したら、以下コマンドでmakeします。

$ make -j4 CC=clang LOCALVERSION=-ver-rust

-j以降の値は環境に応じて変更してください。
今回のマシンスペックだと1時間ほどかかったのでどうにかしたいところ。
kernelビルド高速化について知見がある方、是非アドバイスをお願いします。

ビルドが正常に終了すると、arch/x86/boot/bzImageが出力されているはずです。
これがqemuに渡すイメージファイルになります。

2. buildrootを用いたルートファイルシステムの構築

qemuに渡すもう一つのパラメータ、ルートファイルシステムを作成する為にbuildrootを使用します。

$ git clone https://git.buildroot.net/buildroot

buildrootのビルドにはg++とgzipが必要な為、入っていなければinstallします。

$ sudo yum install g++ gzip

menuconfigを用いてconfigファイルを設定します。

$ make menuconfig

今回はTarget options->Target Architectureをx86、Filesystem images->ext2/3/4 root filesystemを * にし、ext2/3/4 variantをext4に指定しました。
BuildrootにはKernelをビルドする機能も付いていますが、今回は外部でビルドするのでKernel->Linux Kernelのチェックを外します。
また、make時にHost utilities内のチェックが付いているツールを色々とインストールしてくれるのですが、その分だけビルドに時間がかかります。
眺めてみて不必要だと判断したツールはチェックをはずしましょう。

設定が終わったら保存し、以下コマンドでビルドします。

$ make -j4

このビルドも結構かかります。

成功すれば、output/images/rootfs.ext4が生成されます。
これがqemuへ渡すもう一つのパラメータ、ルートファイルシステムです。

これで下ごしらえは終了です。あとは実行あるのみ

3. qemuで実行

これはyumで入ります。

$ sudo yum install qemu

以下コマンドで実行

$ qemu-system-x86_64 -boot c -m 1024M \
  -kernel ${KERNEL_DIR}/arch/x86/boot/bzImage \
  -hda ${BUILDROOT_DIR}/output/images/rootfs.ext4 \
  -append "root=/dev/sda rw console=ttyS0,115200 acpi=off" -nographic

ダラーっとログが流れて、

buildroot:

となったら起動完了です。
rootのパスワードなしでログイン出来ます。

起動時のログで、Rustのサンプルモジュールが動作している様子が見えるはずです。

参考ページ

https://github.com/Rust-for-Linux/linux/blob/rust/Documentation/rust/quick-start.rst
https://qiita.com/shougun71/items/af34632551c6525281f4
https://kuniyu.jp/ja/blog/2/

Discussion

ログインするとコメントできます