Linuxカーネルが難しい?Rustで実装しよう!

FUJITA Tomonori
nttlabs
Published in
4 min readJul 20, 2020

「カーネル開発者になりたい!」

クラウドネイティブ世代の皆様は、何を言っているのか理解できないと思いますが、一昔前は、Linuxカーネル開発の魅力におぼれたエンジニアがたくさんいました。クラウドファースト時代に、誰もやってないだろうと、軽い気持ちで試すと、今もひっそりと生息しているカーネル開発者に、一晩中、指導をうけるはめになりかねません。前例のないRustなら安心です。

RustでLinuxカーネルモジュールが実装できる

Rustでカーネルモジュールを実装する利点

Rustへの愛だけが理由ではなく、カーネル開発にRustを用いると、様々なバグを減らすことができそうという利点があります。例えば、動的なメモリ管理で、うっかり、解放を忘れるとか、解放した後に使ってしまうと、往々として、辛いデバッグになります。

Rustで実装した簡単なカーネルモジュール

Rustのカーネルモジュール開発フレームワークにデバッグコードを追加して、動的なメモリ確保と解放を確認してみます。上記のモジュールは、カーネルにロードされた初期化時に、長さ32のu64の可変長配列を確保しています(16行目)。C言語であれば、kmalloc関数を明示的に呼び出してメモリを確保し、配列として初期化するところですが、Rustでは自動的にkmalloc関数を使って、配列が必要とする256バイトを確保してくれます。

# insmod helloworld.ko
# dmesg |tail -n 2
Hello kernel module!
kmalloc: addr=0xffff8dc887af8d00, size=256

C言語であれば、確保したメモリが不要になった際に、解放するために、kfree関数を明示的に呼び出す必要がありますが、Rustであれば、不要です。このモジュールでは、アンロードした際に、確保したメモリの所有者であるモジュールのインスタンスが削除されるため、自動的にメモリが解放されます。

# rmmod helloworld
# dmesg |tail -n 2
Goodbye kernel module!
kfree: addr=0xffff8dc887af8d00

動的なメモリ管理に関するバグが発生しないとなれば、安心して、他のバグの修正に集中することができますね!

どんな機能が実装できるのか

Rustでのカーネルモジュール開発が待ちきれない感じですね!

早速、何かモジュールを実装しようとすると、現在、このフレームワークは、ファイルシステムを登録する(ファイルシステムの中身は実装できない)、キャラクタデバイスを登録する(中身はほとんど実装できない)ぐらいしかサポートしておらず、意味のある機能は実装できないことを発見できるでしょう。

様々なモジュールをRustで実装できるようにするためには、下記のように、フレームワークを拡張する必要があります。

  1. Rustから、必要なLinuxカーネルのAPIが呼び出せるようにする。
  2. LinuxカーネルのAPIが確保するソースが、適切に解放されるように、Rustの所有権モデルに一致したAPIを実装する。

1は簡単で、Linuxカーネルのヘッダから、自動的に、Rustのコードを生成してくれます。2はRustへの愛で乗り越えていきましょう。

まとめ

現状、RustでのLinuxカーネルモジュール実装は、Rustだけなく、C言語でのカーネル開発知識も必要になり、C言語で実装したほうが簡単ということが分かりました。しかし、全てのLinuxカーネルモジュールを、Rustで書き直すとなれば、この先10年間ぐらい、エンジニアみんなの仕事を作ることができます。業界愛ですね。NTTでは、仲間を募集中です。連絡お待ちしています。

--

--

FUJITA Tomonori
nttlabs

Janitor at the 34th floor of NTT Tamachi office, had worked on Linux kernel, founded GoBGP, TGT, Ryu, RustyBGP, etc. https://twitter.com/brewaddict