Linux Device Driver 輪講 Che++. 第 6 章 キャラクタ型ドライバの高度な 機 第 1 回 (全 2 回)

Slides:



Advertisements
Similar presentations
プロセスの生成とコマンドの実行 プロセスの生成とコマンドの実行 プロセス生成のシステムコール プロセス生成のシステムコール プロセス生成のプログラム例 プロセス生成のプログラム例 プログラム実行のシステムコール プログラム実行のシステムコール 子プロセスの終了を待つシステムコール 子プロセスの終了を待つシステムコール.
Advertisements

アルゴリズムとデータ構造 第2回 線形リスト(復習).
コンパイラ 2011年11月14日
組み込み環境における ユーザレベル・デバイスドライバの検討 (進捗報告)
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
システムプログラミング 第6回、7回 main関数の引数 usageメッセージ システムコールのエラーメッセージ ファイル
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
Object Group ANalizer Graduate School of Information Science and Technology, Osaka University OGAN visualizes representative interactions between a pair.
オペレーティングシステム (OSの機能と構造)
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング システムプログラミング プロセス間通信(パイプ) 担当:青木義満
構造体.
F11: Analysis III (このセッションは論文2本です)
マスタリング バベル Boost.勉強会 #2 ( ).
プログラミング演習II 2004年12月 21日(第8回) 理学部数学科・木村巌.
CC/7700,CC32を用いた データ収集システム 筑波大学 木村 博美 小松原 哲郎 (c)2007 木村博美 筑波大学.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
オペレーティングシステム2005 デバイス管理 (1)
型付きアセンブリ言語を用いた安全なカーネル拡張
プログラミング論 関数ポインタ と 応用(qsort)
プログラミング2 関数
FreeBSDの デバイスドライバについて
関数の定義.
プログラミング 4 記憶の割り付け.
画像処理プログラムの説明.
実行時情報に基づく OSカーネルのコンフィグ最小化
Linux Device Driver 輪講 7. 時の流れ
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
デジタル画像とC言語.
オブジェクト指向言語論 第八回 知能情報学部 新田直也.
2005年度 データ構造とアルゴリズム 第6回 「ハッシュ法を用いた探索」
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
フロントエンドとバックエンドのインターフェース
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
Linux の世界に 触れてみよう! 情報実験 第 3 回 (2005/10/21)
オペレーティングシステム (OSの機能と構造)
参照されないリテラル 長谷川啓
11: 動的メモリ確保 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
実装について 前田俊行.
システムプログラミング 第6回 システムコールのエラーメッセージ ファイルシステム 情報工学科 篠埜 功.
オペレーティングシステムJ/K 2004年10月4日
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
ネットワーク・プログラミング デバイスドライバと環境変数.
高度プログラミング演習 (11).
ネットワーク・プログラミング TCPサーバ.
モジュール分割.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
ネットワーク・プログラミング 1対多のプロセス間通信.
オペレーティングシステム (OSの機能と構造)
11: 動的メモリ確保 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
全体の流れ 画像ファイルを開き,画像データをメモリ上にロード メモリ上にロードした画像データに処理を加える
プログラミング演習I 2003年6月11日(第9回) 木村巌.
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
ネットワーク・プログラミング プロセスとファイルシステム管理.
L4-Linux のメモリ管理における問題点とその解決策
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
プログラミング演習II 2003年12月10日(第7回) 木村巌.
プログラミング演習II 2004年11月 2日(第3回) 理学部数学科・木村巌.
情報処理Ⅱ 小テスト 2005年2月1日(火).
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
岡村耕二 TCP通信プログラム 岡村耕二 情報ネットワーク.
Presentation transcript:

Linux Device Driver 輪講 Che++

第 6 章 キャラクタ型ドライバの高度な 機 第 1 回 (全 2 回)

この章で学ぶ事 「完全な」キャラクタ型デバイスドライ バ作成のための概念 –ioctl システムコールの実装 – プロセスのスリープ – 非ブロッキング I/O の実装 – ユーザ空間へのアクセス許可通知 – いくつかのアクセスポリシーの実装方法 題材として scull ドライバを使う –3 章で作ったドライバの修正版

ioctl デバイスへの操作は ioctl システムコールで 行う int ioctl(int fd, unsigned long cmd,...); –UNIX システムコールの中では異色な存在 普通システムコールに ”…” は使わない – 第 3 引数の型が第 2 引数によって異なるため、 コンパイル時の型チェック回避のために ”…” が使われる

ioctl ioctl ドライバメソッドのプロトタイプ int (*ioctl) (struct inode* inode, struct file* filp,unsigned int cmd, unsigned long arg); –inode と filp はファイル記述子 fd に対応する値 open メソッドに対して渡されたパラメータと同じ –cmd はマクロでシンボリック名を用意する事 が多い –arg は整数値でもポインタでも unsigned long として渡される

ioctl コマンドの選び方 ioctl に渡す cmd の値はシステム全体でユ ニークになるように選ぶべき –0 や 1 から始めるのはよくない 他のドライバの ioctl との混同を避けるため カーネル内で使われる番号もある include/asm/ioctl.h と Documentation/ioctl- number.txt を調べる

ioctl コマンドの選び方 4 つのビットフィールドを使ってコマンド番号を 生成する –type マジック番号 –number 順序番号 –direction データ転送の方向 –size 対象となるユーザデータのサイズ マクロを使って生成

ioctl の選び方 scull での例 /* Use 'k' as magic number */ #define SCULL_IOC_MAGIC 'k' /* Please use a different 8-bit number in your code */ #define SCULL_IOCRESET _IO(SCULL_IOC_MAGIC, 0) /* * S means "Set" through a ptr, * T means "Tell" directly with the argument value * G means "Get": reply by setting through a pointer * Q means "Query": response is on the return value * X means "eXchange": switch G and S atomically * H means "sHift": switch T and Q atomically */ #define SCULL_IOCSQUANTUM _IOW(SCULL_IOC_MAGIC, 1, int) #define SCULL_IOCSQSET _IOW(SCULL_IOC_MAGIC, 2, int) #define SCULL_IOCTQUANTUM _IO(SCULL_IOC_MAGIC, 3) #define SCULL_IOCTQSET _IO(SCULL_IOC_MAGIC, 4) #define SCULL_IOCGQUANTUM _IOR(SCULL_IOC_MAGIC, 5, int) #define SCULL_IOCGQSET _IOR(SCULL_IOC_MAGIC, 6, int) #define SCULL_IOCQQUANTUM _IO(SCULL_IOC_MAGIC, 7) #define SCULL_IOCQQSET _IO(SCULL_IOC_MAGIC, 8) #define SCULL_IOCXQUANTUM _IOWR(SCULL_IOC_MAGIC, 9, int) #define SCULL_IOCXQSET _IOWR(SCULL_IOC_MAGIC,10, int) #define SCULL_IOCHQUANTUM _IO(SCULL_IOC_MAGIC, 11) #define SCULL_IOCHQSET _IO(SCULL_IOC_MAGIC, 12) #define SCULL_IOC_MAXNR 14

戻り値 ioctl は通常 cmd に応じる switch 文から成る –default 節の(一致するコマンド番号がない) 場合の戻り値は? -EINVAL (無効な引数)はよく使われる – 理にかなってはいる 標準では -ENOTTY (デバイスにとって不 適切な ioctl )が推奨される – 一般的にはこちらのメッセージの方が適切

あらかじめ定義されたコマンド いくつかの ioctl コマンドはカーネル本体に よって処理される – これらのコマンドがデバイスドライバコード に渡される事はない 普通のファイルや特殊なファイルに対す るコマンド、ファイルシステム固有なコ マンド等が該当する

ioctl 引数の使い方 ioctl 引数は整数値だったりポインタだった りする – 整数値だったら直接使えば問題ない – ポインタだったらユーザ空間にアクセスする 必要が生じる 第 3 章で出てきた copy_from_user や copy_to_user が使える – ただし効率が悪い

ioctl 引数の使い方 効率の良いデータ転送 – まずはアドレスの検証 int access_ok(int type, const void *addr, unsigned long size); – データ転送マクロ put_user(datum, ptr) __put_user(datum, ptr) get_user(local, ptr) __get_user(local, ptr)

互換性と制限される操作 通常デバイスドライバはパーミッション のチェックを行わない – デバイスへのアクセスはデバイスファイルの パーミッションによって制御されるべき 特定の動作についてはユーザの ” 能力 ” に よって制御したい – 読み書きはできてもフォーマットはさせたく ない – デバイスの設定は特定ユーザにしか許可した くない

互換性と制限される操作 デバイスドライバで扱う ” 能力 ” CAP_DAC_OVERRIDE CAP_NET_ADMIN CAP_SYS_MODULE CAP_SYS_RAWIO CAP_SYS_ADMIN CAP_SYS_TTY_CONFIG capable 関数で ” 能力 ” の有無のチェック int capable(int capability);

ioctl を使わないデバイス制御 ioctl を使わなくてもデバイスは制御可能 – 例えばコンソールでのエスケープシーケンス – デバイスによってはこちらの方が適している 場合もある 実装も利用も簡単になる

I/O のブロック デバイスドライバはプロセスをブロック する場合がある – デバイスが read や write の呼び出しにすぐに応 じることができない場合等

スリープとは スケジューラの待ち列から削除される事 アトミックなコンテキストを実行している時は スリープさせてはいけない 誰かがどこかでプロセスを起こすという確信が なければ、スリープさせてはいけない Linux では待ち列は wait_queue_head_t 構造体で 管理される – 初期化 DECLARE_WAIT_QUEUE_HEAD(name); または wait_queue_head_t my_queue; init_waitqueue_head(&my_queue);

簡単なスリープの例 wait_event マクロでプロセスをスリープさせる wait_event(queue, condition) wait_event_interruptible(queue, condition) wait_event_timeout(queue, condition, timeout) wait_event_interruptible_timeout(queue, condition, timeout) wake_up マクロでスリープしているプロセスを 起こす void wake_up(wait_queue_head_t *queue); void wake_up_interruptible(wait_queue_head_t *queue);

簡単なスリープの例 static DECLARE_WAIT_QUEUE_HEAD(wq); static int flag = 0; ssize_t sleepy_read (struct file *filp, char __user *buf, size_t count, loff_t *pos) { printk(KERN_DEBUG "process %i (%s) going to sleep\n", current->pid, current->comm); wait_event_interruptible(wq, flag != 0); flag = 0; printk(KERN_DEBUG "awoken %i (%s)\n", current->pid, current->comm); return 0; /* EOF */ } ssize_t sleepy_write (struct file *filp, const char __user *buf, size_t count, loff_t *pos) { printk(KERN_DEBUG "process %i (%s) awakening the readers...\n", current->pid, current->comm); flag = 1; wake_up_interruptible(&wq); return count; /* succeed, to avoid retrial */ }

ブロックと非ブロック処理 プロセスの中にはブロックしてほしくな いものもある –flip->f_flags に O_NONBLOCK がセットされて いるものはブロックしてはいけない

排他的な待ち wake_up マクロは全ての待ちプロセスを実行可 能にする – それぞれのプロセスがリソースの取り合いをして、 勝ったプロセスが実行を続ける – その他のプロセスは再びスリープ – 待ち列が大量にある時は困る 待ち列エントリに WQ_FLAG_EXCLUSIVE を指 定すると 1 個ずつプロセスを起こせる void prepare_to_wait_exclusive(wait_queue_head_t* queue, wait_queue_t *wait, int state);