― Linux Device Modelから考える設計と移行判断 ―
Linuxでキャラクタデバイスを実装する方法はいくつかある。
古い実装から新しい実装まで選択肢が存在するため、「今は何が推奨なのか」という観点だけで見てしまいがちだ。しかし実際には、単純に古いAPIを使っているから問題になるわけではない。
重要なのは、
ドライバが決めたデバイスの状態と、ユーザー空間に公開される状態を、どこまで一元的に管理したいのか
である。
そのため、まずはLinux Device Modelが何を解決しようとしたのかを理解すると、実装方式の違いが見えやすくなる。
Linux Device Modelとは何か
Linuxではデバイスを次の4つの観点で整理している。
| 層 | 役割 |
|---|---|
| Bus | デバイスがどこに接続されているか |
| Driver | どのドライバが管理するか |
| Class | ユーザー空間から何として扱うか |
| Device Node | ユーザー空間がアクセスする入口 |
重要なのは、/dev ファイルの作成そのものが目的ではないという点である。
本来は、
デバイスをOSの管理対象として登録する
↓
sysfsへ公開される
↓
devtmpfs/udevが/devを生成する
という流れになっている。
つまり /dev は結果であり、出発点ではない。
Linux Device Model以前
初期のLinuxでは、デバイスファイルは手作業で作成していた。
ドライバ初期化
↓
major/minor決定
↓
mknodで/dev作成
この方式は単純で分かりやすい。
一方で、
- デバイス追加・削除との同期
- 権限管理
- 複数デバイスの扱い
- デバイス状態との整合性
などが利用者や運用スクリプト側へ漏れやすい。
試作や固定構成では十分実用的だが、規模が大きくなるほど管理責任が分散しやすい。
Linux Device Modelが目指したもの
Linux Device Modelでは、
Bus
↓
Driver
↓
Device
↓
Class
↓
/sys
↓
/dev
という構造でデバイスを管理する。
この構造によって、
- デバイスの追加・削除
- 親子関係
- sysfsによる状態公開
- udevとの連携
-
/devの生成
をOS側の共通基盤に乗せられるようになった。
キャラクタデバイスの主な実装方法
1. mknodを利用する方法
特徴
- 実装量が最小
- 固定構成に向く
-
/dev管理が外部へ分散しやすい
向いている場面
- 試作
- デバッグ
- 完全固定構成
- 古い環境との互換維持
向かない場面
- デバイス数が変化する
- 動的生成・削除がある
- 権限管理を自動化したい
2. register_chrdev()
特徴
-
file_operationsの登録が容易 - 実装差分が小さい
- 古くから使われている
利点
- 既存資産を活かしやすい
- レビュー負荷を抑えやすい
注意点
-
/devの生成責任を別へ逃がしやすい - minorごとのライフサイクル管理は明示的ではない
重要なのは、
register_chrdev()を使っていること自体が直ちに問題ではない
という点である。
長期間運用されている製品では、十分整理された実装になっている場合も少なくない。
3. class_create() / device_create()
特徴
Linux Device Modelへ参加するための入口。
device_create()
↓
sysfs生成
↓
uevent通知
↓
devtmpfs/udev
↓
/dev生成
利点
-
/dev生成をOSへ委譲できる - sysfsで状態を追える
- udevと連携できる
- ドライバと公開状態の整合性を取りやすい
欠点
- 初期化と終了処理が増える
- エラーパスのレビュー範囲が広がる
4. cdev
特徴
minor単位でデバイスを明示的に管理するための仕組み。
利点
- 複数デバイス管理に強い
- ライフタイム管理が明確
- Linux Device Modelとの親和性が高い
欠点
- 実装量が増える
- 移行差分が大きい
新規設計では有力だが、
「今ある実装が問題なく動いている」という事実より優先されるものではない。
5. miscdevice
特徴
小規模なキャラクタデバイス向けの簡易実装。
利点
- 実装が非常に簡単
-
/devと/sys/class/miscが自動生成される
欠点
- 製品固有の管理には窮屈
- 大規模な複数デバイス管理には向きにくい
既存実装を変えるべきか
ここが最も重要になる。
次の理由だけでは弱い。
- 古いAPIだから
- 最近のサンプルがそうだから
- Linux Device Modelの方がきれいだから
一方で、次のような状況では変更価値が高くなる。
-
/devの生成責任が外部へ分散している - デバイス数が動的に変化する
- 複数デバイス管理が複雑化している
- 状態をsysfsで可視化したい
- udevによる権限管理を行いたい
- remove処理を確実にしたい
- 将来的にhotplugへ対応したい
つまり、
APIの新旧ではなく、現在の実装が抱えている管理上の問題を解決できるか
で判断するべきである。
まとめ
Linux Device Modelは、「新しいAPI群」ではない。
デバイスの状態、公開方法、ライフサイクル管理をOS全体で一貫して扱うための考え方である。
そのため、
- 小規模で固定構成ならシンプルな実装も十分成立する
- 一方で、動的なデバイス管理や長期保守を考えるなら、Linux Device Modelへ責任を寄せていく価値がある
という整理になる。
そして既存ドライバの改善を考える際は、
「レガシーだから作り直す」のではなく、「現在困っている責務の分散を解消できるか」で判断する。