適当に調べたことをめもっておくブログ。
間違い、勘違い多数あり。
Linuxデバイスドライバメモ
Kernel2.6.21のrequest_irq&free_irq変更点
・request_irq, free_irq
Linuxデバイスドライバ基礎
kernel_thread→kthread_createへ変更
・kernel_thread, kthread_create
kthreadの使い方とか
・kthread_run, kthread_should_stop, kthread_stop
参照値渡し
wait_event
・wait_event, wake_up, init_waitqueue_head
wait_eventいろいろ
・wait_event_interruptible, wait_event_timeout, wait_event_interruptible_timeout, wake_up_interruptible
init_moduleとcleanup_module
・module_init, module_exit
insmodの時に引数を渡したい
・module_param
キャラクタデバイスの登録
・register_chrdev_region, alloc_chrdev_region, unregister_chrdev_region, cdev_init, cdev_add, cdev_del
/procファイルを使う
・create_proc_read_entry, read_proc, remove_proc_entry
セマフォを使う(その1)
subversionコマンド
ログメッセージの修正
間違い、勘違い多数あり。
Linuxデバイスドライバメモ
Kernel2.6.21のrequest_irq&free_irq変更点
・request_irq, free_irq
Linuxデバイスドライバ基礎
kernel_thread→kthread_createへ変更
・kernel_thread, kthread_create
kthreadの使い方とか
・kthread_run, kthread_should_stop, kthread_stop
参照値渡し
wait_event
・wait_event, wake_up, init_waitqueue_head
wait_eventいろいろ
・wait_event_interruptible, wait_event_timeout, wait_event_interruptible_timeout, wake_up_interruptible
init_moduleとcleanup_module
・module_init, module_exit
insmodの時に引数を渡したい
・module_param
キャラクタデバイスの登録
・register_chrdev_region, alloc_chrdev_region, unregister_chrdev_region, cdev_init, cdev_add, cdev_del
/procファイルを使う
・create_proc_read_entry, read_proc, remove_proc_entry
セマフォを使う(その1)
subversionコマンド
ログメッセージの修正
Comment:0 | Trackback:0 | Edit | Page Top.↑
納品の時期ですっかりBlogのことを忘れてた。
というわけで久しぶりに更新。
Kernel2.6.20を今まで使っていて、今回2.6.21に変更したら
担当ドライバをinsmodしたときにNULLポインタにアクセスして
カーネルパニックを起こすようになっちゃった。
そんなわけで、コードの見直しを迫られたわけですが、
どうやら、request_irq近辺で落ちているらしい。
で、コンソールにデバッグ出力させたら、どうやらrequest_irqで
登録するhandlerがなぜか呼ばれていると。
このドライバでは、ユーザがinit処理を呼び出してから割り込みが
発生するという前提の下、作られていたわけで
insmod時に割り込みハンドラが呼ばれたせいでinit処理していない変数を
参照したためにNULLポインタアクセスエラーになったという落ちでした。
で、request_irqの何が変わったんだということを調べると
というわけで久しぶりに更新。
Kernel2.6.20を今まで使っていて、今回2.6.21に変更したら
担当ドライバをinsmodしたときにNULLポインタにアクセスして
カーネルパニックを起こすようになっちゃった。
そんなわけで、コードの見直しを迫られたわけですが、
どうやら、request_irq近辺で落ちているらしい。
で、コンソールにデバッグ出力させたら、どうやらrequest_irqで
登録するhandlerがなぜか呼ばれていると。
このドライバでは、ユーザがinit処理を呼び出してから割り込みが
発生するという前提の下、作られていたわけで
insmod時に割り込みハンドラが呼ばれたせいでinit処理していない変数を
参照したためにNULLポインタアクセスエラーになったという落ちでした。
で、request_irqの何が変わったんだということを調べると
Comment:0 | Trackback:0 | Edit | Page Top.↑
Comment:0 | Trackback:0 | Edit | Page Top.↑
Comment:0 | Trackback:0 | Edit | Page Top.↑
/procファイルって何?
ソフトウェアが作成する特殊なファイルシステムらしい。
カーネルが情報を外部にエクスポートするために使用するらしい。
デバイスドライバの情報を簡単に外部(ユーザ空間)に出せるって考えればいいのかな?
デバッグなんかでprintkでコンソールに情報を出すのもいいけど
タイミングがシビアなドライバだとprintkの処理による処理落ちで内部処理が
変わってきちゃうからそんなのとかの回避に使うといいみたい。
まずは関数から
エントリーを作成する関数がこれ。
struct proc_dir_entry *create_proc_read_entry(const char *name, mode_t mode,
struct proc_dir_entry *base, read_proc_t *read_proc, void *data)
長い。
引数1:nameは作成するファイル名。
引数2:modeはファイルの保護マスク。保護マスクって何?デフォルトモードは0らしい。
引数3:baseはファイルが作成されるディレクトリ。NULLだと/procになる。
引数4:read_procは/proc読み出すときに呼ばれる関数を指定。
引数5:dataは謎。カーネルは無視するけどread_procには渡されるとか。
で、引数4のread_procってのは
int (*read_proc) (char *page, char **start, off_t offset, int count, int *eof, void *data)
って関数を使うらしい。
引数1:pageはデータを書き込む先のバッファ
引数2:startは対照のデータがpageのどこをさしているかを示す
引数3:offsetはアクセスしている位置
引数4:countはread出来る最大文字数
引数5:eofはデータがすべて書かれたときに返す値
引数6:dataは内部処理に使うらしい
エントリーの逆も必要なわけで。
void remove_proc_entry(const char *name, struct proc_dir_entry *base)
引数1:nameは生成のときのnameと一緒
引数2:baseも生成のときのbaseと一緒
で、今回は読み取り関数だけを使用する場合だけど、書き込みも出来るらしい。
それの覚書はまた今度。
で、いつもどおり続きに動くかわからないサンプルコード。
いいかげんな関数の説明より、実装例を見たほうがたぶん簡単。
ソフトウェアが作成する特殊なファイルシステムらしい。
カーネルが情報を外部にエクスポートするために使用するらしい。
デバイスドライバの情報を簡単に外部(ユーザ空間)に出せるって考えればいいのかな?
デバッグなんかでprintkでコンソールに情報を出すのもいいけど
タイミングがシビアなドライバだとprintkの処理による処理落ちで内部処理が
変わってきちゃうからそんなのとかの回避に使うといいみたい。
まずは関数から
エントリーを作成する関数がこれ。
struct proc_dir_entry *create_proc_read_entry(const char *name, mode_t mode,
struct proc_dir_entry *base, read_proc_t *read_proc, void *data)
長い。
引数1:nameは作成するファイル名。
引数2:modeはファイルの保護マスク。保護マスクって何?デフォルトモードは0らしい。
引数3:baseはファイルが作成されるディレクトリ。NULLだと/procになる。
引数4:read_procは/proc読み出すときに呼ばれる関数を指定。
引数5:dataは謎。カーネルは無視するけどread_procには渡されるとか。
で、引数4のread_procってのは
int (*read_proc) (char *page, char **start, off_t offset, int count, int *eof, void *data)
って関数を使うらしい。
引数1:pageはデータを書き込む先のバッファ
引数2:startは対照のデータがpageのどこをさしているかを示す
引数3:offsetはアクセスしている位置
引数4:countはread出来る最大文字数
引数5:eofはデータがすべて書かれたときに返す値
引数6:dataは内部処理に使うらしい
エントリーの逆も必要なわけで。
void remove_proc_entry(const char *name, struct proc_dir_entry *base)
引数1:nameは生成のときのnameと一緒
引数2:baseも生成のときのbaseと一緒
で、今回は読み取り関数だけを使用する場合だけど、書き込みも出来るらしい。
それの覚書はまた今度。
で、いつもどおり続きに動くかわからないサンプルコード。
いいかげんな関数の説明より、実装例を見たほうがたぶん簡単。
Comment:0 | Trackback:0 | Edit | Page Top.↑

