Linux用のデバイスドライバを書くときのバイブルとして多くのプログラマに支持され活用されてきたロングセラー書『Linuxデバイスドライバ』の改訂版。今回の第3版はカーネル2.6に完全対応です。カーネル2.6で様々な機能が追加されたデバイスモデル、カーネルタイマ、メモリ管理、ブロックデバイスについて大幅に加筆修正したほか、TTYドライバ、USBドライバ、その他のLinuxデバイスモデルなどの解説を追加しました。x86以外のアーキテクチャについても触れています。
Linuxデバイスドライバ 第3版
Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman 著、山崎 康宏, 山崎 邦子, 長原 宏治, 長原 陽子 訳
- TOPICS
- Linux
- 発行年月日
- 2005年10月
- PRINT LENGTH
- 648
- ISBN
- 4-87311-253-2
- 原書
- Linux Device Drivers, Third Edition
- FORMAT
目次
訳者まえがき(初版) 訳者まえがき(第2版) 訳者まえがき(第3版) まえがき 1章 デバイスドライバ入門 1.1 ドライバを書くという仕事 1.2 カーネルの分割 1.2.1 ロード可能なモジュール 1.3 デバイスやモジュールのクラス 1.4 セキュリティについて 1.5 バージョン番号 1.6 ライセンス 1.7 カーネル開発コミュニティに参加する 1.8 本書の構成 2章 モジュールの作成と実行 2.1 テスト用システムのセットアップ 2.2 Hellow Worldモジュール 2.3 モジュール対アプリケーション 2.3.1 ユーザ空間とカーネル空間 2.3.2 カーネル内の並行処理 2.3.3 カレントプロセス 2.3.4 その他の事柄 2.4 コンパイルとロード 2.4.1 モジュールのコンパイル 2.4.2 モジュールのロードと削除 2.4.3 カーネルのバージョンへの依存性 2.4.4 プラットフォームへの依存性 2.5 カーネルシンボルテーブル 2.6 準備情報 2.7 初期化とシャットダウン 2.7.1 クリーンアップ用の関数 2.7.2 初期化関数におけるエラー処理 2.7.3 モジュールロード時の競争 2.8 モジュールパラメータ 2.9 ユーザ空間を使う 2.10 クイックリファレンス 3章 キャラクタ型ドライバ 3.1 scullの設計方針 3.2 メジャー番号とマイナー番号 3.2.1 デバイス番号の内部表現 3.2.2 デバイス番号の割り当てと解放 3.2.3 メジャー番号の動的割り当て 3.3 重要なデータ構造 3.3.1 ファイル操作 3.3.2 file構造体 3.3.3 inode構造体 3.4 キャラクタ型デバイスの登録 3.4.1 scullにおけるデバイスの登録 3.4.2 以前の方法 3.5 openとrelease 3.5.1 openメソッド 3.5.2 releaseメソッド 3.6 scullのメモリ利用 3.7 readとwrite 3.7.1 readメソッド 3.7.2 writeメソッド 3.7.3 readvとwritev 3.8 新しいデバイスで遊んでみましょう 3.9 クイックリファレンス 4章 デバッグのテクニック 4.1 カーネルにおけるデバッグのサポート 4.2 表示させてのデバッグ 4.2.1 printk 4.2.2 コンソールメッセージのリダイレクション 4.2.3 メッセージを記録する方法 4.2.4 メッセージのオン、オフを切り替える 4.2.5 速度の制限 4.2.6 デバイス番号の表示 4.3 問い合わせによるデバッグ 4.3.1 /procファイルシステムを使う 4.3.2 ioctlメソッドを使う 4.4 観察によるデバッグ 4.5 システムフォルトのデバッグ 4.5.1 Oopsメッセージ 4.5.2 システムのハングアップ 4.6 デバッガと関連ツール 4.6.1 gdbを使う 4.6.2 kdbカーネルデバッガ 4.6.3 kgdbパッチ 4.6.4 ユーザモードLinux 4.6.5 Linux Trace Toolkit 4.6.6 Dynamic Probes 5章 並行処理と競争状態 5.1 scullの落とし穴 5.2 並行処理とその管理 5.3 セマフォとミューテックス 5.3.1 Linuxのセマフォを使う 5.3.2 scullでセマフォを使う 5.3.3 Reader/Writerのセマフォ 5.4 完了(completion) 5.5 スピンロック 5.5.1 スピンロックAPIの紹介 5.5.2 スピンロックとアトミックなコンテキスト 5.5.3 スピンロック関数 5.5.4 reader/writerのスピンロック 5.6 ロックの罠 5.6.1 曖昧なルール 5.6.2 ロック順序に関するルール 5.6.3 細かいロックと粗いロック 5.7 ロックに代わる方法 5.7.1 ロックフリーのアルゴリズム 5.7.2 アトミック変数 5.7.3 ビット操作 5.7.4 seqlock 5.7.5 Read-Copy-Update(RCU) 5.8 クイックリファレンス 6章 キャラクタ型ドライバの高度な機能 6.1 ioctl 6.1.1 ioctlコマンドの選び方 6.1.2 戻り値 6.1.3 あらかじめ定義されたコマンド 6.1.4 ioctl引数の使い方 6.1.5 互換性と制限される操作 6.1.6 ioctlコマンドの実装 6.1.7 ioctlを使わないデバイス制御 6.2 I/Oのブロック 6.2.1 スリープとは 6.2.2 単純なスリープの例 6.2.3 ブロックと非ブロック処理 6.2.4 ブロックI/Oのサンプル 6.2.5 高度なスリープ 6.2.6 Scullpipeドライバをテストする 6.3 pollとselect 6.3.1 readやwriteとの相互作用 6.3.2 背後にあるデータ構造 6.4 非同期通知 6.4.1 ドライバから見ると 6.5 デバイスを位置付ける 6.5.1 llseekの実装 6.6 デバイスファイルでのアクセス制御 6.6.1 1回だけオープンできるデバイス 6.6.2 同時にアクセスできるユーザを1人に制限する 6.6.3 EBUSYに代わるブロックopen 6.6.4 オープン時にデバイスを複製する 6.7 クイックリファレンス 7章 時の流れ 7.1 時間経過の計測 7.1.1 jiffiesカウンタを使う 7.1.2 プロセッサ固有のレジスタ 7.2 現在時刻を知る方法 7.3 実行を遅らせる 7.3.1 長い遅延 7.3.2 短い遅延 7.4 カーネルタイマ 7.4.1 タイマのAPI 7.4.2 カーネルタイマの実装 7.5 タスクレット 7.6 作業待ち列 7.6.1 共有待ち列 7.7 クイックリファレンス 7.7.1 時間の管理 7.8.2 遅延 7.7.3 カーネルタイマ 7.7.4 タスクレット 7.7.5 作業待ち列 8章 メモリの押さえ方 8.1 kmallocの真実 8.1.1 フラグ引数 8.1.2 サイズ引数 8.2 類似キャッシュ 8.2.1 SLABキャッシュを使ったscull:scullc 8.2.2 メモリプール 8.3 get_free_pageと仲間たち 8.3.1 ページをまるごと使う:scullp 8.3.2 alloc_pagesインタフェース 8.4 vmallocとその仲間たち 8.4.1 仮想アドレスを使うscull:scullv 8.5 CPUごとの変数 8.6 大きなバッファの獲得 8.6.1 起動時に専用バッファを取得する 8.7 クイックリファレンス 9章 ハードウェアとの通信 9.1 I/OポートとI/Oメモリ 9.1.1 I/Oレジスタとコンベンショナルメモリ 9.2 I/Oポートの使い方 9.2.1 I/Oポートの割り当て 9.2.2 I/Oポートの操作 9.2.3 ユーザ空間からのI/Oポートアクセス 9.2.4 ストリング操作 9.2.5 I/O処理の休止 9.2.6 プラットフォーム依存性 9.3 I/Oポートのサンプル 9.3.1 パラレルポートの概要 9.3.2 サンプルドライバ 9.4 I/Oメモリの使い方 9.4.1 I/Oメモリ割り当てとマッピング 9.4.2 I/Oメモリのアクセス 9.4.3 ポートをI/Oメモリとして扱う 9.4.4 I/Oメモリでもshortを使ってみる 9.4.5 1MB未満のISAメモリ 9.4.6 isa_readbと仲間たち 9.5 クイックリファレンス 10章 割り込み処理 10.1 パラレルポートの準備 10.2 割り込みハンドラのインストール 10.2.1 /procインタフェース 10.2.2 IRQ番号の自動推定 10.2.3 高速ハンドラと低速ハンドラ 10.3 ハンドラを実装する 10.3.1 ハンドラの引数と戻り値 10.3.2 割り込みの有効化と無効化 10.4 前半部と後半部 10.4.1 タスクレット 10.4.2 作業待ち列 10.5 割り込みの共有 10.5.1 共有ハンドラのインストール 10.5.2 ハンドラの実行 10.5.3 /procインタフェースと共有割り込み 10.6 割り込み駆動I/O 10.6.1 書き込みバッファリングのサンプル 10.7 クイックリファレンス 11章 カーネルにおけるデータの型 11.1 標準Cの型 11.2 データアイテムに明示的なサイズを割り当てる 11.3 インタフェースに固有の型 11.4 移植性に関するデータ型以外の問題 11.4.1 時間間隔 11.4.2 ページサイズ 11.4.3 バイトオーダー 11.4.4 データアラインメント 11.4.5 ポインタとエラー値 11.5 リンクリスト 11.6 クイックリファレンス 12章 PCIバス 12.1 PCIインタフェース 12.1.1 PCIアドレッシング 12.1.2 起動時 12.1.3 レジスタの設定と初期化 12.1.4 MODULE_DEVICE_TABLE 12.1.5 PCIドライバの登録 12.1.6 以前のスタイルのPCIプローブ 12.1.7 PCIデバイスの有効化 12.1.8 設定空間にアクセスする 12.1.9 I/O空間とメモリ空間にアクセスする 12.1.10 PCI割り込み 12.1.11 ハードウェア抽象化 12.2 プレイバックISA 12.2.1 ハードウェアリソース 12.2.2 ISAプログラミング 12.2.3 「プラグアンドプレイ」の仕様 12.3 PC/104とPC/104+ 12.4 その他のPCバス 12.4.1 MCA 12.4.2 EISA 12.4.3 VLB 12.5 SBus 12.6 NuBus 12.7 外部バス 12.8 クイックリファレンス 13章 USBドライバ 13.1 USBデバイスの基本 13.1.1 エンドポイント 13.1.2 インタフェース 13.1.3 構成(configuration) 13.2 USBとSysfs 13.3 USB要求ブロック(URB) 13.3.1 urb構造体 13.3.2 URBの作成と破棄 13.3.3 URBの送信 13.3.4 URBの完了:完了コールバックハンドラ 13.3.5 URBのキャンセル 13.4 USBドライバを書く 13.4.1 ドライバがサポートするデバイスは? 13.4.2 USBドライバの登録 13.4.3 プローブと切断の詳細 13.4.4 URBの送信と制御 13.5 URBを使わないUSB転送 13.5.1 usb_bulk_msg 13.5.2 usb_control_msg 13.5.3 それ以外のUSBデータ関数 13.6 クイックリファレンス 14章 Linuxデバイスモデル 14.1 kobject、kset、サブシステム 14.1.1 kobjectの基本 14.1.2 kobjectの階層、kset、サブシステム 14.2 下位レベルのsysfs操作 14.2.1 デフォルトの属性 14.2.2 デフォルト以外の属性 14.2.3 バイナリの属性 14.2.4 シンボリックリンク 14.3 ホットプラグイベントの生成 14.3.1 ホットプラグの操作 14.4 バス、デバイス、ドライバ 14.4.1 バス 14.4.2 デバイス 14.4.3 デバイスドライバ 14.5 クラス 14.5.1 class_simpleインタフェース 14.5.2 完全なクラスインタフェース 14.6 まとめてみましょう 14.6.1 デバイスの追加 14.6.2 デバイスの削除 14.6.3 ドライバの追加 14.6.4 ドライバの削除 14.7 ホットプラグ 14.7.1 動的なデバイス 14.7.2 /sbin/hotplugユーティリティ 14.7.3 /sbin/hotplugの使用 14.8 ファームウェアを扱う 14.8.1 カーネルファームウェアインタフェース 14.8.2 動作の様子 14.9 クイックリファレンス 14.9.1 kobject 14.9.2 Sysfs操作 14.9.3 バス、デバイス、ドライバ 14.9.4 クラス 14.9.5 ファームウェア 15章 メモリマッピングとDMA 15.1 Linuxでのメモリ管理 15.1.1 アドレスの種別 15.1.2 物理アドレスとページ 15.1.3 高位メモリと低位メモリ 15.1.4 メモリマップとstruct page 15.1.5 ページテーブル 15.1.6 仮想メモリ領域(VMA) 15.1.7 プロセスメモリマップ 15.2 mmapデバイス操作 15.2.1 remap_pfn_rangeの使用 15.2.2 シンプルな実装例 15.2.3 VMA操作の追加 15.2.4 nopageを使ったメモリマッピング 15.2.5 I/O領域のマッピングを変更する 15.2.6 RAMのマッピングを変更する 15.2.7 カーネル仮想アドレスのマッピングを変更する 15.3 ダイレクトI/Oを実行する 15.3.1 非同期I/O 15.4 DMA 15.4.1 DMA転送の概要 15.4.2 DMAバッファの割り当て 15.4.3 バスアドレス 15.4.4 汎用DMAレイヤ 15.4.5 ISAデバイスのためのDMA 15.5 クイックリファレンス 15.5.1 最初の部品 15.5.2 mmapの実装 15.5.3 ダイレクトI/Oの実装 15.5.4 DMA 16章 ブロック型ドライバ 16.1 登録 16.1.1 ブロック型ドライバの登録 16.1.2 ディスクの登録 16.1.3 sbullにおける初期化 16.1.4 セクタサイズに関する注意事項 16.2 ブロック型デバイスの操作 16.2.1 openメソッドとreleaseメソッド 16.2.2 リムーバブルメディアのサポート 16.2.3 ioctlメソッド 16.3 要求の処理 16.3.1 requestメソッドの概要 16.3.2 単純なrequestメソッド 16.3.3 要求待ち列 16.3.4 要求の分析 16.3.5 要求完了関数 16.4 その他の詳細 16.4.1 コマンドの前処理 16.4.2 タグ付きのコマンドのキューイング 16.5 クイックリファレンス 17章 ネットワークドライバ 17.1 snullの設計方針 17.1.1 IP番号の割り当て 17.1.2 パケットの物理的な転送 17.2 カーネルへの接続 17.2.1 デバイスの登録 17.2.2 各デバイスの初期化 17.2.3 モジュールの削除 17.3 net_device構造体の詳細 17.3.1 グローバル情報 17.3.2 ハードウェア情報 17.3.3 インタフェース情報 17.3.4 デバイスメソッド 17.3.5 ユーティリティフィールド 17.4 オープンとクローズ 17.5 パケットの送信 17.5.1 同時送信の制御 17.5.2 送信タイムアウト 17.5.3 切り貼りI/O 17.6 パケットの受信 17.7 割り込みハンドラ 17.8 割り込み受信の軽減 17.9 リンクステートの変更 17.10 ソケットバッファ 17.10.1 重要なフィールド 17.10.2 ソケットバッファに作用する関数 17.11 MACアドレスの解決 17.11.1 EthernetでARPを使う 17.11.2 ARPをオーバーライドする 17.11.3 Ethernet以外のヘッダ 17.12 ioctlコマンドのカスタマイズ 17.13 統計情報 17.14 マルチキャスト 17.14.1 カーネルによるマルチキャストサポート 17.14.2 典型的な実装 17.15 その他の詳細事項 17.15.1 メディアに依存しないインタフェースのサポート 17.15.2 Ethtoolのサポート 17.15.3 netpoll 17.16 クイックリファレンス 18章 TTYドライバ 18.1 小さなttyドライバ 18.1.1 struct termios 18.2 tty_driverのメソッド 18.2.1 openとclose 18.2.2 データの流れ 18.2.3 その他のバッファ関数 18.2.4 read関数はない? 18.3 tty回線設定 18.3.1 set_termios 18.3.2 tiocmgetとtiocmset 18.4 ioctl 18.5 ttyデバイスにおけるprocとsysfs 18.6 tty_driver構造体の詳細 18.7 tty_operations構造体の詳細 18.8 tty_struct構造体の詳細 18.9 クイックリファレンス 参考文献 書籍 Webサイト 索引