---
title: カーネルモジュールと no_std
url: https://doc.liz6.com/ja/rust/11-ffi-and-system-interaction/02-kernel-modules-and-no-std
locale: ja
area: rust
tags:
- rust
- ffi-and-system-interaction
date: 2026-06-30
modified: 2026-07-16
description: std は OS（スレッド、ファイル、ヒープ割り当て）に依存しており、ボートメタルやカーネルモジュールにはそれらが存在しません。#![no_std] は std を除去し、OS に依存しない core crate のみを残しますが、alloc（ヒープ割り当て）と panic_handler（パニック時の処理）は自分で提供する必要があります。Rust-for-Linux は、no_std とカーネルが提供する alloc 実装を用いて、Linux カーネル内で Rust コードを実行します。
---

# カーネルモジュールと no_std

> std は OS（スレッド、ファイル、ヒープ割り当て）に依存しており、ボートメタルやカーネルモジュールにはそれらが存在しません。`#![no_std]` は std を除去し、OS に依存しない `core` crate のみを残しますが、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 のみを残します：

```rust
#![no_std]
#![no_main]

extern crate alloc;                  // オプション: ヒープ割り当てが必要ない場合にのみ導入

use core::panic::PanicInfo;
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {}                          // 出力不可、unwind 不可
}
```

`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 製カーネルモジュールがサポートされています。主要な抽象化：

```rust
use kernel::prelude::*;

kernel::module! {
    type: MyModule,
    name: "my_module",
    license: "GPL",
}

struct MyModule;
impl kernel::Module for MyModule {
    fn init(_module: &'static ThisModule) -> Result<Self> { Ok(MyModule) }
}

// ファイル操作の実装
struct MyFile;
#[vtable]
impl kernel::file::Operations for MyFile {
    fn read(&self, _data: ()) -> Result<Vec<u8>> {
        Ok(b"Hello from Rust kernel module!\n".to_vec())
    }
}
```

`#[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*
