Linuxにおけるデバイスドライバの開発とデバッグの実際

株式会社デバイスドライバーズ
hidaka@devdrv.com
2002/10/9

Linux Kernel Conference 20021

はじめにnデバイスドライバとは？

n

なぜLinuxなのか？

2002/10/9

Linux Kernel Conference 2002

Device Drivers

2Linuxデバイスドライバ開発
n

準備と心構えn

カーネルとデバイスドライバ
デバイスドライバ開発
デバッグツール
実機デモ

nnn

2002/10/9

Linux Kernel Conference 2002

Device Drivers

3確認：スキルと環境n

開発に必要なスキル
nnn

n

開発に必要なもの
nnn

2002/10/9

ハードウェアの知識
ソフトウェアの知識＋アルファ（度胸、経験、根性、発想、人脈、英語力）

開発環境
ターゲット環境
テスト用アプリケーション

Linux Kernel Conference 2002

ProtocolSoftwareDeviceHardwareAlgolithm

ApplicationDevice Drivers

4

準備：マシン環境n

新しくて速いマシンを用意
nnnn複数DISK

速いCPU
速いディスク128MB以上のメモリモニタ切替機

標準でサポートのビデオカードとNIC
nnnn

2002/10/9

裏技

ATI Radeon
GeForce2 MX400
Matrox G400
オンボード・ビデオには注意！
Linux Kernel Conference 2002

Device Drivers

5

準備：
OS環境
n

カーネル2.4系
nnn

kernel.org の純粋カーネルnn

2.4.10以降がおすすめ必要なオプションのインストール
nn

2002/10/9

Redhat 7.1以降
Turbo Linux, Vine, Debian, Slackware,

カーネル開発環境
ネットワーク環境の動作Linux Kernel Conference 2002

Device Drivers

6準備：
ツール類の使いこなし
nn

OSのインストール
Shell, コマンド，ツールnn

エディタ, X-Window
nnsh, Perl, …

C言語プログラミングnn

2002/10/9

vi, …

スクリプト言語nn

bash, ln, tar, gzip, patch, diff, rpm, linuxconf, ftp

Makefileとmakegccのオプション、ライブラリ
Linux Kernel Conference 2002

Device Drivers

7インターネットの活用n

情報の検索術nnn

コミュニティの活用術
nn

メール、BBS、人脈

情報の発信術n

2002/10/9

検索エンジン
オープンソースの活用

ホームページの作成

Linux Kernel Conference 2002

Device Drivers

8情報サイト（英語）nnhttp://kernel.org/
The Linux Document Projectnn

Linux usbnn
nhttp://www.linux-usb.org/

http://examples.oreilly.com/linuxdrive2/
The Open Source Development Networknnn2002/10/9

http://www.tldp.org/

http://www.osdn.com/
http://sourceforge.net/
http://freshmeat.net/
Linux Kernel Conference 2002

Device Drivers

9情報サイト（日本語）n

日本のLinux情報
nn

OSDN Japannn

http://www.changelog.net/

ASCII Linuxn

2002/10/9

http://www-6.ibm.com/jp/linux/

Change Lognn

http://osdn.jp/

Linux at IBMnn

http://www.linux.or.jp/

http://linux.ascii24.com/
Linux Kernel Conference 2002

Device Drivers

10さらに上を目指すためのヒントn

アプリケーション開発経験n

ハードウェアとデバイスの知識n

各種計測器の使いこなしn

ネットワークとセキュリティn

GPL、Open Source、FreeSoftの理解と区別

2002/10/9

Linux Kernel Conference 2002

Device Drivers

11まとめ：準備と心構え
n

開発効率を向上させるために
nn

n

最新のハードウェアとソフトウェア標準品のデバイススキルを向上させるために
nn

OSインストールやカーネルコンパイル
日頃からUnix / Linuxに親しむ
n Unix系のコマンドと操作

nn

情報を収集、活用するためにn

2002/10/9

プログラミング以外の開発作業に慣れる
インターネットの活用
Linux Kernel Conference 2002

Device Drivers

12Linuxデバイスドライバ開発
n

準備と心構えn

カーネルとデバイスドライバ

n

デバイスドライバ開発
デバッグツール
実機デモnn

2002/10/9

Linux Kernel Conference 2002

Device Drivers

13Linuxカーネルの構造
アプリケーションライブラリ

システムコール・インタフェイス
ファイルシステム
文字型

プロセス制御ブロック型

デバイスドライバ
ハードウェア制御機構

ハードウェア
2002/10/9

Linux Kernel Conference 2002

Device Drivers

14システムコールn

デバイス入出力システムコール処理の流れ
アプリケーション
ユーザ・ライブラリ

ユーザ空間

システムコール・ライブラリ
トラップ
システムコール・インタフェイス

デバイスドライバ

2002/10/9

Linux Kernel Conference 2002

システム空間カーネル

Device Drivers

15

入出力とシステムコール
n

入出力＝ファイル、デバイス用

nLinuxのシステムコール
nnn

デバイスドライバn

2002/10/9

メソッド(method)とよぶ
open, read, write, release, ioctl, lseek, …
メソッドの実体を提供するのがドライバ

Linux Kernel Conference 2002

Device Drivers

16

デバイスドライバの仕事
nreadのコードの例

int read (struct inode *inode, struct file *file, char *buffer, int count)
ドライバ・モジュール

inodeカーネル

filecountbuffer（ドライバ）

2002/10/9

buffermemcpy_to_fs()

Linux Kernel Conference 2002

（アプリケーション）

Device Drivers

17

メジャー番号とマイナー番号n /dev/ディレクトリの下の特殊ファイル（ノード）n デバイスノード（＝mknodという特別なコマンドで作成）

n メジャー番号がドライバとデバイスを結びつける
n デバイスドライバの種類＝メジャー番号で決定

n マイナー番号が個々の同一型デバイスを区別
n デバイスドライバにはマイナー番号がそのまま渡される

n メジャー番号＆マイナー番号＝デバイスとドライバの接続点
n 動的な割り当てと静的な割り当て（固定割り当て）がある
2002/10/9

Linux Kernel Conference 2002

Device Drivers

18ローダブル・モジュール
スタティックリンクのドライバ

ローダブルモジュールのドライバ

アプリケーション

アプリケーション

カーネル

カーネル

デバイスドライバ

デバイス
ドライバ

ハードウェア

2002/10/9

ダイナミッ
クロード
IF
ハードウェアLinux Kernel Conference 2002

Device Drivers

19ローダブル・モジュールの操作
n

自動的なロードnnn

手作業でのロードnnnn
n2002/10/9/lib/modules/2.4.??-*/kernel/ 以下/etc/modules.conf の記述

insmod aaa.ormmod aaa
modprobe aaa
lsmod
depmod -a
Linux Kernel Conference 2002

Device Drivers

20ダイナミック・ローディング
ドライバ・モジュール

insmodinit_module()

カーネル
register_capability()

エントリの登録
lseek()
read()
write()…..

rmmod2002/10/9

cleanup_module()Linux Kernel Conference 2002

capabilities[]
printk() ….

register_capability()

Device Drivers

21Linuxデバイスドライバ開発
n

準備と心構えカーネルとデバイスドライバ

n

デバイスドライバ開発nデバッグツール
実機デモnn

2002/10/9

Linux Kernel Conference 2002

Device Drivers

22バージョン名nMakefileの記述例

nバージョン名管理

ディレクトリ名
linux-2.4.2-2
linux-2.4.18
linux-2.4.18ikd
2002/10/9

VERSION=2
PATCH-LEVEL=4
SUB̲LEVEL=14
EXTRAVERSION=-2

Makefile/modules
ファイル名
vmlinuz-2.4.2-2
2.4.2-2
vmlinuz-2.4.18
2.4.18
vmlinuz-2.4.18ikd
2.4.18ikd
Linux Kernel Conference 2002LILOのラベル
linux
linux-18
ikd-linux

Device Drivers

23カーネル開発用ディレクトリ
/usr/src/linux-2.4.2-2/kernel/driver/arch

2.4.2-2の開発用ディレクトリ

/linux-2.4.18/kernel/driver/arch

2.4.14の開発用ディレクトリ

linux
2002/10/9

Linux Kernel Conference 2002

2.4.18へのシンボリック・リンク
Device Drivers

24カーネル・コンパイルn

手順とコマンドn

トップディレクトリの必要ファイル確認make mrproper → パラメータや設定ファイルの初期化
make *config → コンフィグファイルの作成＆修正
make dep → 依存情報とシンボル情報の生成
make clean → 古いオブジェクトの削除
make bzImage → カーネルのコンパイルmake modules→ モジュールのコンパイルmake modules_install → モジュールのインストールn

カーネルのコピーとブート設定

nnnnnnn

2002/10/9

Linux Kernel Conference 2002

Device Drivers

25

デバイスドライバのコンパイル
モジュール化nnmake *configで‘m’を選択

make modules 以降の作業
n KERNELオプションとMODULEオプションnn

コンパイルスクリプトの例

gcc -D__KERNEL__ -I/usr/src/linux-2.4.18/include -Wall -Wstrict-prototypes ¥-Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common ¥-pipe -mpreferred-stack-boundary=2 -march=i686 -DMODULE -DMODVERSIONS ¥-include /usr/src/linux/include/linux/modversions.h ¥-DKBUILD_BASENAME=serial -DEXPORT_SYMTAB -c serial.c2002/10/9

Linux Kernel Conference 2002

Device Drivers

26

デバイスドライバのロードとテスト
n

デバイスノードの作成
nn

コマンドnnnn
n2002/10/9

mknod
insmod → モジュールのロード
rmmod → モジュールのアンロード
lsmod → モジュール・ディレクトリの表示
depmod → モジュール依存関係を作成
modprobe → モジュールの依存関係を配慮したロードLinux Kernel Conference 2002

Device Drivers

27デバッグ環境n

ターゲットの準備
nnn

アプリケーションnn
n

2002/10/9

実機デバイス、類似デバイスシミュレータ、エミュレータ
エンドユーザ向けアプリケーション
デバッグ用アプリケーション
テスト用アプリケーション

Linux Kernel Conference 2002

Device Drivers

28

補足情報
n

カーネルとサービス・コール（ドライバ・インタフェイス）は頻繁に変わる
nnn

ドライバの書き方はUnixと互換性は無い
n2002/10/9

動作環境の各バージョン確認が必須（上位互換性が無い）
正確な情報の収集と解析が必要

特にネットワーク、Socketインタフェイス
Linux Kernel Conference 2002

Device Drivers

29Linuxデバイスドライバ開発

n

準備と心構えカーネルとデバイスドライバ
デバイスドライバ開発nデバッグツール

n

実機デモ

nn

2002/10/9

Linux Kernel Conference 2002

Device Drivers

30デバッグツール
gdb – 汎用デバッガ、リモートデバッグ
n printk() – メッセージ
n SysRq – マジック・キー
n /proc ファイルシステム
n kdb –静的デバッグ
n kdbg – リモートデバッグ
n IKD – 静的オンタイムデータ収集
n2002/10/9

Linux Kernel Conference 2002

Device Drivers

31printk()n

標準でも利用されるメッセージ出力nnfloat, doubleなどの浮動小数点は表示できない

使い方
nn

printk(KERN̲ERR “Help = %d¥n”, help);
メッセージ・レベル#define KERN̲EMERG#define KERN̲ALERT#define KERN̲CRIT#define KERN̲ERR#define KERN̲WARNING#define KERN̲NOTICE#define KERN̲INFO#define KERN̲DEBUG

2002/10/9"<0>""<1>""<2>""<3>"
"<4>"
"<5>"
"<6>"
"<7>"

/* system is unusable/* action must be taken immediately/* critical conditions/* error conditions/* warning conditions/* normal but significant condition/* informational/* debug‑level messages

Linux Kernel Conference 2002

Device Drivers

*/
*/
*/
*/
*/
*/
*/
*/

32

SysRq‘神秘の’ ‘魔法の’ SysRqキー
n 緊急時やシステム制御のコマンド実行
n カーネルに標準で組み込み済
nn

Kernel 2.1.x 以降で利用可能
n ただしEnableしておけば…

n2002/10/9

kdb等でキーがハングしたときに有効Linux Kernel Conference 2002

Device Drivers33

/proc ファイルシステム
n/proc/下の特別なテキスト・ファイルnnn/proc/devices （デバイス割り当てメジャー番号の表示）/proc/ioports （物理IOポートの割り当て表示）/proc/interrupts （物理IRQの割り当て表示）

ドライバとユーザのインタフェイス
n サンプル・ソース
n2002/10/9

Linux Kernel Conference 2002

Device Drivers34

kdb (Built-In kernel debugger)
http://oss.sgi.com/projects/kdb/
n パッチ組込みカーネルデバッガ
n アセンブラレベルのデバッグ
n マニュアルやドキュメントが整備されていて紹介サイトが多い
nn

2002/10/9

実機デバッグのデモLinux Kernel Conference 2002

Device Drivers

35

kgdb (linux kernel source level debugger )nnn

http://kgdb.sourceforge.net/
gdbベースで2台のPCをシリアルケーブルで接続
Cソースコードレベル・デバッガn

カーネル全体をframe pointer optionで再コンパイルする
必要がある

Target側
2002/10/9

Host側Linux Kernel Conference 2002

Device Drivers

36

IKD (Integrated Kernel Debugging Facilities)n

http://www.kernel.org/pub/linux/kernel/people/andrea/ikd/n

パッチ組込みカーネルデバッガ
nnnn2002/10/9

2.2.12-ikd5 以降のIKD にはkdbが入っている
データテーブルにgdbでアクセス可能TraceやMemleak機能等もある

カーネル本体のデバッグ用
Linux Kernel Conference 2002

Device Drivers37

その他のデバッグ・ツール
n lhcd (Linux Kernel Crash Dumps)
n http://lkcd.sourceforge.net/

n lockmeter (Kernel spinlock metering for Linux)
n http://oss.sgi.com/projects/lockmeter/
n KMSGDUMP (Linux Kernel Messages Dump Tool)n http://www-miaif.lip6.fr/willy/pub/linux-patches/

2002/10/9

Linux Kernel Conference 2002

Device Drivers

38Linuxデバイスドライバ開発

n

準備と心構えカーネルとデバイスドライバ
デバイスドライバ開発
デバッグツール

n

実機デモ

nn
n

2002/10/9

Linux Kernel Conference 2002

Device Drivers

39

実機でのデバッグ例
n

デモ用ターゲットn

USBキャプチャ・カメラEE-260
n http://e-kit.jp/ で販売

nnn

OmniVision OV511 + OmniVision OV7620
http://www.ovt.com/pdfs/ds_511P.pdf

アプリケーション
nW3CAMn http://mpx.freeshell.org/

n2002/10/9

デバッグ用アプリケーション
Linux Kernel Conference 2002

Device Drivers

40デバッグ用アプリケーション例(1)nWebカメラcginnvidcatw3cam.cgi
n netscape等のブラウザで確認

n

テスト用shell#!/bin/sh ‑f
while [ 1 ]; do (./vidcat > /dev/null ; echo capt); done

2002/10/9

Linux Kernel Conference 2002

Device Drivers

41デバッグ用アプリケーション例(2)#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <linux/types.h>static char *device = "/dev/video";main(){
char b[256];
int i, fd = 0;
while(1) {b[0] = 0;
printf("Open, Close, Quit ?> ");scanf("%s", &b[0]);switch(b[0]) {case 'o': case 'O':
if ((i = open(device, O̲RDWR)) < 0) {printf("open error = %d¥n", i);break;}
fd = i;printf("Opened = %d¥n", fd);
break;
2002/10/9

case 'c': case 'C':
if (fd == 3) {printf("not opened = %d¥n", fd);
break;}
else if ((i = close(fd)) < 0) {printf("close error = %d¥n", i);break;}
printf("Closed = %d¥n", fd);
fd =0;
break;
case 'q': case 'Q':printf("will quit...¥n");exit(0);break;
default:
printf("Invalid command = %s¥n", b);
break;}}}

Linux Kernel Conference 2002

Device Drivers42

補足：kdbの代表的なコマンド
CommandUsage
Description‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
md<vaddr>
Display Memory Contents
mdr<vaddr> <bytes>
Display Raw Memorymds<vaddr>
Display Memory Symbolicallymm<vaddr> <contents>
Modify Memory Contents
id<vaddr>
Display Instructions
go[<vaddr>]
Continue Executionrd
Display Registers
rm<reg> <contents>
Modify Registers
ef<vaddr>
Display exception framebt[<vaddr>]
Stack traceback
btp<pid>
Display stack for process <pid>bta
Display stack all processesps
Display active task list
sections
List kernel and module sections
lsmod
List loaded kernel modules
rmmod<modname>Remove a kernel modulebp[<vaddr>]
Set/Display breakpoints
bl[<vaddr>]
Display breakpoints
bpa[<vaddr>]Set/Display global breakpoints
bc<bpnum>Clear Breakpointss[<#steps>]
Single Stepssb
Single step to branch/call

2002/10/9

Linux Kernel Conference 2002

Device Drivers43