このページの目次
カーネルモジュールと no_std
std は OS(スレッド、ファイル、ヒープ割り当て)に依存しており、ボートメタルやカーネルモジュールにはそれらが存在しません。
#![no_std]は std を除去し、OS に依存しないcorecrate のみを残しますが、alloc(ヒープ割り当て)と panic_handler(パニック時の処理)は自分で提供する必要があります。Rust-for-Linux は、no_std とカーネルが提供する alloc 実装を用いて、Linux カーネル内で Rust コードを実行します。
std の除去: no_std 環境
std は OS に依存しています——スレッド、ファイル IO、ネットワーク、ヒープ割り当ては、すべて OS の存在を前提としています。ボートメタル(bare metal)、組み込みシステム、カーネルモジュールにはそれらが存在しません。#![no_std] は std を除去し、OS に依存しない core crate のみを残します:
extern crate alloc; // オプション: ヒープ割り当てが必要ない場合にのみ導入
use PanicInfo;
!
core には以下が含まれます:Option, Result, Iterator, Clone, Copy, 基本マクロ(format_args! は含まれますが、format! を使用するには write_str の実装を自分で提供する必要があります)、アトミック操作。alloc crate は GlobalAlloc が実装されている場合に利用可能になり、Box, Vec, String, Rc, Arc, HashMap を提供します。
Rust-for-Linux (Linux カーネル)
Linux 6.1 以降では Rust 製カーネルモジュールがサポートされています。主要な抽象化:
use *;
module!
;
// ファイル操作の実装
;
#[vtable] マクロは、C 互換の関数ポインタテーブルを生成するコードを trait に生成します——これにより、カーネルの C コードにおける file_operations 構造体と連携します。カーネル内の Rust はユーザー空間よりも多くの制約があります:
- 独自のアロケータ:カーネルでは
#[global_allocator]を使用できません。カーネルのアロケータ(kmalloc/kfree)を使用する必要があります——kernel::allocを介してアクセスします - 独自の同期プリミティブ:
kernel::sync::Mutexはカーネルのミューテックス(struct mutex)の Rust によるラッパーであり、std::sync::Mutexではありません - 独自のエラー型:
kernel::error::Errorは Linux の errno にマッピングされます - Panic = BUG():カーネルでは unwind できません——
panic_handlerはBUG()を呼び出します(スタックの出力 + カーネルの停止)
参考
- Rust-for-Linux: rust-for-linux.com
- Embedded Rust Book: docs.rust-embedded.org
- Phil Opp's blog: os.phil-opp.com
Keywords: no_std, core, alloc, panic_handler, kernel module, Rust-for-Linux, embedded, BUG