i8253 PIT をアクセスするデバイスドライバ
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
* i8253 PIT をアクセスするデバイスドライバ [#j256b81d]
デバイスをアクセスするドライバを作ります。Windows そして...
#textbox(note, 今時の PC の i8253 Channel1 は D-RAM 制御...
今どきの完全な PC の回路が公開されていないので、断言はで...
[[440BX North Bridge:https://www.google.co.jp/search?num...
}}
次に示す左側の図が PC の構成で i8253 PIT が存在する位置、...
CENTER:&ref(bus_tree_to_i8253.png); &ref(i8253.png);
* 仕様 [#r1d54f9f]
おおよその仕様は次の通りです。
|項目|仕様|h
|動作環境|PC-AT 仕様のパソコン、PentiumIII あるいはこれよ...
|対象デバイス|i8253 PIT channel1|
|デバイスの形態|platform device|
|ドライバの機能|read counter, write rate, readback rate (...
|ドライバの種類|platform device driver|
|ドライバ実装形態|kernel に直接組み込む部分とモジュール部...
|user space API|sysfs node|
割り込み処理は実装しません。物足りないかもしれません。
仕様に書かれた内容を見ていきます。
** platform device [#hb677a0e]
platform device とは実行環境に固定的に接続され、ほかのデ...
#textbox(note, on board の PCI 接続デバイスはどの様な扱い...
&ogfileone(/drivers/pci,/drivers/pci); にある PCI bus ド...
}}
** platform driver [#hb677a0e]
platform driver は platform device のためのドライバです。...
** kernel と module に組み込み場所を分割する [#y3bfccd1]
kernel に静的にリンクするコードと module として構成し動的...
*** kernel に静的にリンクするコード [#c83dc2c2]
kernel を修正するパッチと構築する方法は [[kernel に組み込...
|実装|機能|h
|kernel に静的にリンクするコード [[i8253_ref_setup.c]]|i8...
|kernel の [[Makefile>i8253_ref-kernel-Makefile]]|[[i8253...
|kernel の [[Kconfig>i8253_ref-kernel-kconfig]]|[[i8253_r...
|device header file [[i8253_control.h]] |i8253 のレジスタ...
|driver header file [[i8253_ref.h]]|platform device の I...
*** module として構成し動的にリンクするコード [#g1946788]
module として構築するソースは &ref(i8253_ref.tar.gz); か...
|実装|機能|h
|module として構成したドライバ [[i8253_ref.c]]|i8253 chan...
|上の [[Makefile>i8253_ref-module-Makefile]]|[[i8253_ref....
急に大規模な開発になった様に感じるかもしれません。Linux k...
#textbox(thought, デバイスとドライバを一つのモジュール(ソ...
ドライバを作ろうとするデバイスのレジスタアドレスが固定的...
}}
** sysfs node を API にする [#fc3f7e95]
&ogdefs(DEVICE_ATTR(),DEVICE_ATTR,device.h); を使い sysfs...
i8253_ref_setup.c と i8253_ref.c を組み込んだことで新しく...
別のページ [[sysfs ノードからデバイスをアクセスする]] で ...
汎用性が高い [[mknod(1):https://linuxjm.osdn.jp/html/GNU_...
* 実行してみる [#u764cf56]
kernel への組み込みとドライバモジュールの構築が終了した所...
#pre(soft){{
&span(ConsoleOut){/home/furuta/work/i8253_ref # };&span(C...
&span(ConsoleOut){/home/furuta/work/i8253_ref # };&span(C...
-- snip --
&span(ConsoleOut){[ 83.406414] i8253_ref: module verifi...
&span(ConsoleOut){[ 83.406646] i8253_ref_init: Called.};
&span(ConsoleOut){[ 83.406672] i8253_ref_probe: Called....
&span(ConsoleOut){[ 83.406679] i8253_ref i8253_ref.0.au...
&span(ConsoleOut){[ 83.406692] i8253_ref i8253_ref.0.au...
&span(ConsoleOut){/home/furuta/work/i8253_ref # };&span(C...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){total 0};
&span(ConsoleOut){drwxr-xr-x 3 root root 0 9月 14 13...
&span(ConsoleOut){drwxr-xr-x 13 root root 0 9月 10 16...
&span(ConsoleOut){-r--r--r-- 1 root root 4096 9月 14 13...
&span(ConsoleOut){lrwxrwxrwx 1 root root 0 9月 14 13...
&span(ConsoleOut){-rw-r--r-- 1 root root 4096 9月 10 16...
&span(ConsoleOut){-r--r--r-- 1 root root 4096 9月 10 16...
&span(ConsoleOut){drwxr-xr-x 2 root root 0 9月 10 16...
&span(ConsoleOut){-rw-r--r-- 1 root root 4096 9月 14 13...
&span(ConsoleOut){lrwxrwxrwx 1 root root 0 9月 10 16...
&span(ConsoleOut){-rw-r--r-- 1 root root 4096 9月 10 16...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){-1};
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){> {};
&span(ConsoleOut){> i=10};
&span(ConsoleOut){> while (( $i > 0 ));...
&span(ConsoleOut){> i=$(( $i - 1 ))};
&span(ConsoleOut){> done};
&span(ConsoleOut){> echo};
&span(ConsoleOut){> }};
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){1024};
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){231 130 182 138 279 244 333 347 454 478...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){4077 3004 1975 1019 3989 2732 1812 48 3...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){10136 5012 16161 10961 6046 814 12356 7...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){24422 19127 13902 8937 3789 31305 26177...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){59635 52731 47698 42600 37532 32366 273...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
--snip--
&span(ConsoleOut){[ 259.205029] i8253_ref_exit: Called.};
&span(ConsoleOut){[ 259.205075] i8253_ref i8253_ref.0.au...
}}
* i8253_ref 全体のデータ構造 [#wc5356f6]
次の図は i8253 PIT channel1 デバイスとこれを操作するため...
CENTER:&ref(i8253_ref_data_structure.png);
うす青 &ref(i8253_ref_light_blue_color.png); の構造体は L...
"Prepared in i8253_ref_setup.c" と書かれた囲みの中が kern...
"Allocated in i8253_ref.c" と書かれた囲みの中がドライバの...
#textbox(note, device 構造体の driver_data メンバ getter/...
&ogdefs(device,device,device.h); 構造体の driver_data メ...
}}
* i8253_ref_setup.c: kernel に platform device を登録する...
kernel の初期化処理で i8253 を platform device として登録...
#textbox(note, ディレクトリの下に配置したソースをコンパイ...
C 言語で書いたソースをディレクトリに置いただけではコンパ...
}}
** initcall [#q22e6b93]
次のコード片は [[i8253_ref_setup.c]] の初期化処理部分です。
#code(c,overflow:scroll,/i8253_ref_device_initcall/..=-3+...
kernel 初期化処理の時に呼ぶ関数を &ogdefs(arch_initcall()...
&ogdefs(arch_initcall(),arch_initcall); で指定した i8253_...
** platform device と platform driver の繋がり [#z225cc3f]
次のコード片は i8253_ref_device_initcall() で kernel に登...
#code(c,overflow:scroll,/counter and control port resourc...
kernel に登録した情報の中に device と driver を結びつける...
#code(c,overflow:scroll,/I8253_REF_DEVICE_NAME/../I8253_R...
* i8253_ref.c: i8253 をアクセスするドライバ [#gae3e986]
[[i8253_ref.c]] がソースコード全体です。
** init [#a78be01f]
モジュールを初期化する処理から見ていきましょう。&ogdefs(m...
#code(c,overflow:scroll,/i8253_ref_init/../^}$/,begin-=5,...
#code(c,overflow:scroll,/module_init/..+1,i8253_ref.c);
登録するドライバ i8253_ref_driver の内容を見てみましょう...
#code(c,overflow:scroll,/dev_pm_ops/../i8253_ref_shutdown...
*** platform_driver のメソッド(関数テーブル) [#s6d57faf]
&ogdefs(platform_driver,platform_driver,platform_device.h...
|メンバ変数|変数が指した先の関数機能|h
|probe|対応するデバイスが見つかった(kernel に{登録されて...
|remove|対応するデバイスが外された(kernel から削除された)...
|shutdown|shutdown または reboot の時に呼び出されます。一...
|driver->pm.suspend|state&sup([1]); = {freeze | stan...
|driver->pm.resume|state&sup([1]); = {freeze | stand...
&sup([1]); [[/sys/power/state]] ノードです。このノードに...
ほかにも i8253_ref driver で出てこなかった関数を指すメン...
#textbox(note,driver->pm.suspend と suspend メンバのどち...
&ogdefs(platform_driver,platform_driver,platform_device.h...
}}
** probe [#m174041c]
probe 処理 i8253_ref_probe() を見ていきます。i8253_ref_dr...
#code(c,overflow:scroll,/i8253_ref_probe/../platform_get_...
probe 処理の順番はデバイスの挙動、確保するリソース同士の...
#code(c,overflow:scroll,/platform_get_resource_byname.*I8...
&ogdefs(platform_device_register(),platform_device_regist...
#code(c,overflow:scroll,/dev[[:space:]]*=[[:space:]]*&\(p...
&ogdefs(dev_set_drvdata()); は &ogdefs(device,device,/inc...
#code(c,overflow:scroll,/dev_set_drvdata/../dev_set_drvda...
&ogfile(/drivers/base); を主要な処理とする kernel の中で...
user space 向け API を sysfs node に作ります。&ogdefs(DEV...
&ogdefs(S_IRUGO,S_IRUGO, stat.h);, &ogdefs(S_IWUSR,S_IWUS...
#code(c,overflow:scroll,/DEVICE_ATTR.*counter/../[.]attrs...
配列 &ogdefs(attribute*,attribute,sysfs.h);[] の要素を &o...
#code(c,overflow:scroll,/sysfs_create_group/../^}$/,i8253...
ノードを作った直後から user space のアプリケーションから...
** remove [#o2f070f6]
i8253_ref_remove() はデバイスが外された時 (&ogdefs(platfo...
#code(c,overflow:scroll,/i8253_ref_remove/../^}$/,begin-=...
&ogdefs(sysfs_remove_group()); で &ogdefs(DEVICE_ATTR(),D...
** shutdown [#p749d1f7]
i8253_ref_shutdown() は shutdown または reboot するときに...
#code(c,overflow:scroll,/i8253_ref_shutdown/../^}$/,begin...
i8253_ref ドライバは呼びだされたことを表示するだけの処理...
- ドライバの therad や workqueue などで継続している処理を...
- デバイスの動作を停止する。DMA を使用して転送処理中であ...
- 割り込みを禁止または発生しないようにして、デバイスが電...
#textbox(note,shutdown で確保したメモリ領域などを開放する...
開放せず、そのまま保持していて良いと考えています。remove ...
}}
** read and write [#y950da90]
ドライバにとって必須の機能「デバイスをアクセスする」を見...
#textbox(thought,spin_lock_irqsave() と spin_unlock_irqre...
&ogdefs(raw_spin_lock_irqsave());, &ogdefs(raw_spin_unloc...
&ogdefs(spin_lock_irqsave());, &ogdefs(spin_unlock_irqre...
}}
*** read counter [#tc85339c]
次の i8253_ref_counter_read() 関数は i8253 の counter を...
#code(c,overflow:scroll,/i8253_ref_counter_read/../^}$/,b...
#textbox(note,outb_p() の実装はどこにあるの?){{
&ogdefs(outb_p()); のリンク先を辿っても、待ち処理が入った...
}}
*** write rate [#e7ceadca]
次の i8253_ref_rate_write() 関数は i8253 の rate (分周比)...
#code(c,overflow:scroll,/i8253_ref_rate_write/../^}$/,beg...
** show and store [#qd77e49d]
&ogdefs(sysfs_create_group()); で登録した counter, rate ...
#code(c,/DEVICE_ATTR.*counter/../DEVICE_ATTR.*rate/,begin...
*** _show() - read() system call に対応する処理 [#dfab3eee]
i8253_ref_counter_show() は read() system call に対して返...
#textbox(note,DEVICE_ATTR() の _show() 関数(メソッド)で返...
&ogdefs(DEVICE_ATTR()); の _show() 関数が返せる文字列の長...
}}
#code(c,overflow:scroll,/i8253_ref_counter_show/../^}$/,b...
dev 引数は &ogdefs(device,device,/include/linux/device.h)...
i8253_ref_rate_show() もほぼ同様な実装です。read back す...
#code(c,overflow:scroll,/i8253_ref_rate_show/../^}$/,begi...
*** _store() - write() system call に対応する処理 [#ibd50...
i8253_ref_rate_store() は write() に対応するコードです。b...
#textbox(note,DEVICE_ATTR() の _store() 関数に渡される文...
&ogdefs(kernfs_fop_write()); で文字列の最大長が制限されて...
}}
#code(c,overflow:scroll,/i8253_ref_rate_store/../^}$/,beg...
文字列から整数に変換する関数は &ogfileone(/include/linux/...
#textbox(thought, simple_strtoul() は obsolete ですか...){{
"This function is obsolete. Please use kstrtoul instead."
}}
** suspend and resume [#j9be16c0]
ドライバの電源管理 call back のうち、suspend と resume を...
*** suspend [#x712e06d]
i8253_ref_suspend() はデバイスを低消費電力状態に遷移させ...
#code(c,overflow:scroll,/i8253_ref_suspend/../^}$/,begin-...
一般的なドライバで suspend 処理で実装される内容は次の通り...
- 一連の制御シーケンスを伴うデバイス制御をしている場合は...
- 割り込みを禁止するか、デバイスが wakeup 機能を持ってい...
- デバイスを低消費電力状態に遷移させる: クロック周波数を...
#textbox(note){{
機器全体の機能として CPU が停止しても、周辺デバイスを動作...
}}
#textbox(thought, i8253 でも僅かな低消費電力化は可能かも...
PC-AT 互換機の回路構成で使われている i8253 channel 1 はカ...
}}
*** resume [#h51fc36d]
i8253_ref_resume() はデバイスを低消費電力から復帰させる必...
#code(c,overflow:scroll,/i8253_ref_resume/../^}$/,begin-=...
** exit [#cc84e856]
i8253_ref_exit() は i8253_ref.ko モジュールが kernel から...
#code(c,overflow:scroll,/i8253_ref_exit/../^}$/,begin-=4,...
&ogdefs(platform_driver_unregister()); を呼び出しドライバ...
* まとめ [#e375f7d9]
次はこのページに出てきた主な項目です。並びはページの構成...
- [[kernel にソースを組み込む>kernel に組み込む - i8253 P...
-- [[Makefile>kernel に組み込む - i8253 PIT をアクセスす...
-- [[Kconfig>kernel に組み込む - i8253 PIT をアクセスする...
- &ogdefs(platform_device);
-- &ogdefs(platform_device_register());
-- &ogdefs(platform_device_unregister());
-- &ogdefs(resource,resource,ioport.h);
- struct &ogdefs(device,device,device.h);
-- platform_data
-- driver_data
--- &ogdefs(dev_set_drvdata());
--- &ogdefs(dev_get_drvdata());
- &ogdefs(platform_driver);
-- &ogdefs(platform_driver_register());
-- &ogdefs(platform_driver_unregister());
-- [[platform device との対応>#z225cc3f]]
- driver module
-- [[init>#z225cc3f]]
-- [[exit>#cc84e856]]
- driver call back
-- [[probe>#m174041c]]
-- [[remove>#o2f070f6]]
-- [[shutdown>#p749d1f7]]
-- &ogdefs(dev_pm_ops);
--- [[suspend>#x712e06d]]
--- [[resume>#h51fc36d]]
--- [[sys/power/state]]
- &ogdefs(DEVICE_ATTR());
-- [[/sys/devices/platform/i8253_ref.0.auto>kernel に組...
-- &ogdefs(sysfs_create_group());
-- &ogdefs(sysfs_remove_group());
-- [[_show()>#dfab3eee]]
-- [[_store()>#ibd50f03]]
- &ogdefs(kzalloc());, &ogdefs(kfree());
- [[spin lock>spin lock による排他制御]]
- &ogdefs(outb());, &ogdefs(inb());, &ogdefs(outb_p());, ...
-- [[outb_p() の実装はどこにあるの?]]
終了行:
* i8253 PIT をアクセスするデバイスドライバ [#j256b81d]
デバイスをアクセスするドライバを作ります。Windows そして...
#textbox(note, 今時の PC の i8253 Channel1 は D-RAM 制御...
今どきの完全な PC の回路が公開されていないので、断言はで...
[[440BX North Bridge:https://www.google.co.jp/search?num...
}}
次に示す左側の図が PC の構成で i8253 PIT が存在する位置、...
CENTER:&ref(bus_tree_to_i8253.png); &ref(i8253.png);
* 仕様 [#r1d54f9f]
おおよその仕様は次の通りです。
|項目|仕様|h
|動作環境|PC-AT 仕様のパソコン、PentiumIII あるいはこれよ...
|対象デバイス|i8253 PIT channel1|
|デバイスの形態|platform device|
|ドライバの機能|read counter, write rate, readback rate (...
|ドライバの種類|platform device driver|
|ドライバ実装形態|kernel に直接組み込む部分とモジュール部...
|user space API|sysfs node|
割り込み処理は実装しません。物足りないかもしれません。
仕様に書かれた内容を見ていきます。
** platform device [#hb677a0e]
platform device とは実行環境に固定的に接続され、ほかのデ...
#textbox(note, on board の PCI 接続デバイスはどの様な扱い...
&ogfileone(/drivers/pci,/drivers/pci); にある PCI bus ド...
}}
** platform driver [#hb677a0e]
platform driver は platform device のためのドライバです。...
** kernel と module に組み込み場所を分割する [#y3bfccd1]
kernel に静的にリンクするコードと module として構成し動的...
*** kernel に静的にリンクするコード [#c83dc2c2]
kernel を修正するパッチと構築する方法は [[kernel に組み込...
|実装|機能|h
|kernel に静的にリンクするコード [[i8253_ref_setup.c]]|i8...
|kernel の [[Makefile>i8253_ref-kernel-Makefile]]|[[i8253...
|kernel の [[Kconfig>i8253_ref-kernel-kconfig]]|[[i8253_r...
|device header file [[i8253_control.h]] |i8253 のレジスタ...
|driver header file [[i8253_ref.h]]|platform device の I...
*** module として構成し動的にリンクするコード [#g1946788]
module として構築するソースは &ref(i8253_ref.tar.gz); か...
|実装|機能|h
|module として構成したドライバ [[i8253_ref.c]]|i8253 chan...
|上の [[Makefile>i8253_ref-module-Makefile]]|[[i8253_ref....
急に大規模な開発になった様に感じるかもしれません。Linux k...
#textbox(thought, デバイスとドライバを一つのモジュール(ソ...
ドライバを作ろうとするデバイスのレジスタアドレスが固定的...
}}
** sysfs node を API にする [#fc3f7e95]
&ogdefs(DEVICE_ATTR(),DEVICE_ATTR,device.h); を使い sysfs...
i8253_ref_setup.c と i8253_ref.c を組み込んだことで新しく...
別のページ [[sysfs ノードからデバイスをアクセスする]] で ...
汎用性が高い [[mknod(1):https://linuxjm.osdn.jp/html/GNU_...
* 実行してみる [#u764cf56]
kernel への組み込みとドライバモジュールの構築が終了した所...
#pre(soft){{
&span(ConsoleOut){/home/furuta/work/i8253_ref # };&span(C...
&span(ConsoleOut){/home/furuta/work/i8253_ref # };&span(C...
-- snip --
&span(ConsoleOut){[ 83.406414] i8253_ref: module verifi...
&span(ConsoleOut){[ 83.406646] i8253_ref_init: Called.};
&span(ConsoleOut){[ 83.406672] i8253_ref_probe: Called....
&span(ConsoleOut){[ 83.406679] i8253_ref i8253_ref.0.au...
&span(ConsoleOut){[ 83.406692] i8253_ref i8253_ref.0.au...
&span(ConsoleOut){/home/furuta/work/i8253_ref # };&span(C...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){total 0};
&span(ConsoleOut){drwxr-xr-x 3 root root 0 9月 14 13...
&span(ConsoleOut){drwxr-xr-x 13 root root 0 9月 10 16...
&span(ConsoleOut){-r--r--r-- 1 root root 4096 9月 14 13...
&span(ConsoleOut){lrwxrwxrwx 1 root root 0 9月 14 13...
&span(ConsoleOut){-rw-r--r-- 1 root root 4096 9月 10 16...
&span(ConsoleOut){-r--r--r-- 1 root root 4096 9月 10 16...
&span(ConsoleOut){drwxr-xr-x 2 root root 0 9月 10 16...
&span(ConsoleOut){-rw-r--r-- 1 root root 4096 9月 14 13...
&span(ConsoleOut){lrwxrwxrwx 1 root root 0 9月 10 16...
&span(ConsoleOut){-rw-r--r-- 1 root root 4096 9月 10 16...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){-1};
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){> {};
&span(ConsoleOut){> i=10};
&span(ConsoleOut){> while (( $i > 0 ));...
&span(ConsoleOut){> i=$(( $i - 1 ))};
&span(ConsoleOut){> done};
&span(ConsoleOut){> echo};
&span(ConsoleOut){> }};
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){1024};
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){231 130 182 138 279 244 333 347 454 478...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){4077 3004 1975 1019 3989 2732 1812 48 3...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){10136 5012 16161 10961 6046 814 12356 7...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){24422 19127 13902 8937 3789 31305 26177...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){59635 52731 47698 42600 37532 32366 273...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
&span(ConsoleOut){/sys/devices/platform/i8253_ref.0.auto ...
--snip--
&span(ConsoleOut){[ 259.205029] i8253_ref_exit: Called.};
&span(ConsoleOut){[ 259.205075] i8253_ref i8253_ref.0.au...
}}
* i8253_ref 全体のデータ構造 [#wc5356f6]
次の図は i8253 PIT channel1 デバイスとこれを操作するため...
CENTER:&ref(i8253_ref_data_structure.png);
うす青 &ref(i8253_ref_light_blue_color.png); の構造体は L...
"Prepared in i8253_ref_setup.c" と書かれた囲みの中が kern...
"Allocated in i8253_ref.c" と書かれた囲みの中がドライバの...
#textbox(note, device 構造体の driver_data メンバ getter/...
&ogdefs(device,device,device.h); 構造体の driver_data メ...
}}
* i8253_ref_setup.c: kernel に platform device を登録する...
kernel の初期化処理で i8253 を platform device として登録...
#textbox(note, ディレクトリの下に配置したソースをコンパイ...
C 言語で書いたソースをディレクトリに置いただけではコンパ...
}}
** initcall [#q22e6b93]
次のコード片は [[i8253_ref_setup.c]] の初期化処理部分です。
#code(c,overflow:scroll,/i8253_ref_device_initcall/..=-3+...
kernel 初期化処理の時に呼ぶ関数を &ogdefs(arch_initcall()...
&ogdefs(arch_initcall(),arch_initcall); で指定した i8253_...
** platform device と platform driver の繋がり [#z225cc3f]
次のコード片は i8253_ref_device_initcall() で kernel に登...
#code(c,overflow:scroll,/counter and control port resourc...
kernel に登録した情報の中に device と driver を結びつける...
#code(c,overflow:scroll,/I8253_REF_DEVICE_NAME/../I8253_R...
* i8253_ref.c: i8253 をアクセスするドライバ [#gae3e986]
[[i8253_ref.c]] がソースコード全体です。
** init [#a78be01f]
モジュールを初期化する処理から見ていきましょう。&ogdefs(m...
#code(c,overflow:scroll,/i8253_ref_init/../^}$/,begin-=5,...
#code(c,overflow:scroll,/module_init/..+1,i8253_ref.c);
登録するドライバ i8253_ref_driver の内容を見てみましょう...
#code(c,overflow:scroll,/dev_pm_ops/../i8253_ref_shutdown...
*** platform_driver のメソッド(関数テーブル) [#s6d57faf]
&ogdefs(platform_driver,platform_driver,platform_device.h...
|メンバ変数|変数が指した先の関数機能|h
|probe|対応するデバイスが見つかった(kernel に{登録されて...
|remove|対応するデバイスが外された(kernel から削除された)...
|shutdown|shutdown または reboot の時に呼び出されます。一...
|driver->pm.suspend|state&sup([1]); = {freeze | stan...
|driver->pm.resume|state&sup([1]); = {freeze | stand...
&sup([1]); [[/sys/power/state]] ノードです。このノードに...
ほかにも i8253_ref driver で出てこなかった関数を指すメン...
#textbox(note,driver->pm.suspend と suspend メンバのどち...
&ogdefs(platform_driver,platform_driver,platform_device.h...
}}
** probe [#m174041c]
probe 処理 i8253_ref_probe() を見ていきます。i8253_ref_dr...
#code(c,overflow:scroll,/i8253_ref_probe/../platform_get_...
probe 処理の順番はデバイスの挙動、確保するリソース同士の...
#code(c,overflow:scroll,/platform_get_resource_byname.*I8...
&ogdefs(platform_device_register(),platform_device_regist...
#code(c,overflow:scroll,/dev[[:space:]]*=[[:space:]]*&\(p...
&ogdefs(dev_set_drvdata()); は &ogdefs(device,device,/inc...
#code(c,overflow:scroll,/dev_set_drvdata/../dev_set_drvda...
&ogfile(/drivers/base); を主要な処理とする kernel の中で...
user space 向け API を sysfs node に作ります。&ogdefs(DEV...
&ogdefs(S_IRUGO,S_IRUGO, stat.h);, &ogdefs(S_IWUSR,S_IWUS...
#code(c,overflow:scroll,/DEVICE_ATTR.*counter/../[.]attrs...
配列 &ogdefs(attribute*,attribute,sysfs.h);[] の要素を &o...
#code(c,overflow:scroll,/sysfs_create_group/../^}$/,i8253...
ノードを作った直後から user space のアプリケーションから...
** remove [#o2f070f6]
i8253_ref_remove() はデバイスが外された時 (&ogdefs(platfo...
#code(c,overflow:scroll,/i8253_ref_remove/../^}$/,begin-=...
&ogdefs(sysfs_remove_group()); で &ogdefs(DEVICE_ATTR(),D...
** shutdown [#p749d1f7]
i8253_ref_shutdown() は shutdown または reboot するときに...
#code(c,overflow:scroll,/i8253_ref_shutdown/../^}$/,begin...
i8253_ref ドライバは呼びだされたことを表示するだけの処理...
- ドライバの therad や workqueue などで継続している処理を...
- デバイスの動作を停止する。DMA を使用して転送処理中であ...
- 割り込みを禁止または発生しないようにして、デバイスが電...
#textbox(note,shutdown で確保したメモリ領域などを開放する...
開放せず、そのまま保持していて良いと考えています。remove ...
}}
** read and write [#y950da90]
ドライバにとって必須の機能「デバイスをアクセスする」を見...
#textbox(thought,spin_lock_irqsave() と spin_unlock_irqre...
&ogdefs(raw_spin_lock_irqsave());, &ogdefs(raw_spin_unloc...
&ogdefs(spin_lock_irqsave());, &ogdefs(spin_unlock_irqre...
}}
*** read counter [#tc85339c]
次の i8253_ref_counter_read() 関数は i8253 の counter を...
#code(c,overflow:scroll,/i8253_ref_counter_read/../^}$/,b...
#textbox(note,outb_p() の実装はどこにあるの?){{
&ogdefs(outb_p()); のリンク先を辿っても、待ち処理が入った...
}}
*** write rate [#e7ceadca]
次の i8253_ref_rate_write() 関数は i8253 の rate (分周比)...
#code(c,overflow:scroll,/i8253_ref_rate_write/../^}$/,beg...
** show and store [#qd77e49d]
&ogdefs(sysfs_create_group()); で登録した counter, rate ...
#code(c,/DEVICE_ATTR.*counter/../DEVICE_ATTR.*rate/,begin...
*** _show() - read() system call に対応する処理 [#dfab3eee]
i8253_ref_counter_show() は read() system call に対して返...
#textbox(note,DEVICE_ATTR() の _show() 関数(メソッド)で返...
&ogdefs(DEVICE_ATTR()); の _show() 関数が返せる文字列の長...
}}
#code(c,overflow:scroll,/i8253_ref_counter_show/../^}$/,b...
dev 引数は &ogdefs(device,device,/include/linux/device.h)...
i8253_ref_rate_show() もほぼ同様な実装です。read back す...
#code(c,overflow:scroll,/i8253_ref_rate_show/../^}$/,begi...
*** _store() - write() system call に対応する処理 [#ibd50...
i8253_ref_rate_store() は write() に対応するコードです。b...
#textbox(note,DEVICE_ATTR() の _store() 関数に渡される文...
&ogdefs(kernfs_fop_write()); で文字列の最大長が制限されて...
}}
#code(c,overflow:scroll,/i8253_ref_rate_store/../^}$/,beg...
文字列から整数に変換する関数は &ogfileone(/include/linux/...
#textbox(thought, simple_strtoul() は obsolete ですか...){{
"This function is obsolete. Please use kstrtoul instead."
}}
** suspend and resume [#j9be16c0]
ドライバの電源管理 call back のうち、suspend と resume を...
*** suspend [#x712e06d]
i8253_ref_suspend() はデバイスを低消費電力状態に遷移させ...
#code(c,overflow:scroll,/i8253_ref_suspend/../^}$/,begin-...
一般的なドライバで suspend 処理で実装される内容は次の通り...
- 一連の制御シーケンスを伴うデバイス制御をしている場合は...
- 割り込みを禁止するか、デバイスが wakeup 機能を持ってい...
- デバイスを低消費電力状態に遷移させる: クロック周波数を...
#textbox(note){{
機器全体の機能として CPU が停止しても、周辺デバイスを動作...
}}
#textbox(thought, i8253 でも僅かな低消費電力化は可能かも...
PC-AT 互換機の回路構成で使われている i8253 channel 1 はカ...
}}
*** resume [#h51fc36d]
i8253_ref_resume() はデバイスを低消費電力から復帰させる必...
#code(c,overflow:scroll,/i8253_ref_resume/../^}$/,begin-=...
** exit [#cc84e856]
i8253_ref_exit() は i8253_ref.ko モジュールが kernel から...
#code(c,overflow:scroll,/i8253_ref_exit/../^}$/,begin-=4,...
&ogdefs(platform_driver_unregister()); を呼び出しドライバ...
* まとめ [#e375f7d9]
次はこのページに出てきた主な項目です。並びはページの構成...
- [[kernel にソースを組み込む>kernel に組み込む - i8253 P...
-- [[Makefile>kernel に組み込む - i8253 PIT をアクセスす...
-- [[Kconfig>kernel に組み込む - i8253 PIT をアクセスする...
- &ogdefs(platform_device);
-- &ogdefs(platform_device_register());
-- &ogdefs(platform_device_unregister());
-- &ogdefs(resource,resource,ioport.h);
- struct &ogdefs(device,device,device.h);
-- platform_data
-- driver_data
--- &ogdefs(dev_set_drvdata());
--- &ogdefs(dev_get_drvdata());
- &ogdefs(platform_driver);
-- &ogdefs(platform_driver_register());
-- &ogdefs(platform_driver_unregister());
-- [[platform device との対応>#z225cc3f]]
- driver module
-- [[init>#z225cc3f]]
-- [[exit>#cc84e856]]
- driver call back
-- [[probe>#m174041c]]
-- [[remove>#o2f070f6]]
-- [[shutdown>#p749d1f7]]
-- &ogdefs(dev_pm_ops);
--- [[suspend>#x712e06d]]
--- [[resume>#h51fc36d]]
--- [[sys/power/state]]
- &ogdefs(DEVICE_ATTR());
-- [[/sys/devices/platform/i8253_ref.0.auto>kernel に組...
-- &ogdefs(sysfs_create_group());
-- &ogdefs(sysfs_remove_group());
-- [[_show()>#dfab3eee]]
-- [[_store()>#ibd50f03]]
- &ogdefs(kzalloc());, &ogdefs(kfree());
- [[spin lock>spin lock による排他制御]]
- &ogdefs(outb());, &ogdefs(inb());, &ogdefs(outb_p());, ...
-- [[outb_p() の実装はどこにあるの?]]
ページ名: