Rust x linux kernel 開発環境構築手順(2021/06/23)
Rust x linux kernel 開発環境構築手順(2021/06/23)
備忘録的に残しておきます。
目的
Rustによって開発可能なLinux Kernelが動作する環境を整備すること
やること
- next-linuxのビルド
- buildrootによるルートファイルシステムの作成
- qemuで実行
大まかに分けて上記3項目でRustによるKernel開発環境が整います。
1. next-linuxのビルド
1.1. rust側の環境構築
とりあえずgccを入れます。
$ sudo yum install gcc
そして、rustをビルドするためのコンパイラがなければ話は進みません。
コンパイラのインストールには、rustupというコンパイラなどのインストーラとバージョン管理を兼ねたツールを使用します。
上記リンクに記されたコマンドを実行
$ 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を先ほどのコマンドで導入している場合は既に入っているはずです。
次に、core
とalloc
のクロスコンパイルに必要な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のバージョンが古く、ビルド出来ませんでした。
そのため、ソースからビルドしました。
公式のGettingstartedに従ってビルド&インストール
今回の環境では優に六時間はかかりました。
また、中間生成物含め100G程の容量を必要とする為、注意しましょう。
私はインストールの段階でroot側の容量が足りないことに気がつき、色々と苦労しました。
これでllvmが入り、Kernelのビルドに必要な環境は整いました。
1.3 linuxのビルド
ソースを取得します。
今回は上記のリポジトリから取得しました。
$ git clone https://github.com/Rust-for-Linux/linux.git
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のサンプルモジュールが動作している様子が見えるはずです。
参考ページ
Discussion