以前GDBを使って、printf()のリバースエンジニアリングを行ったのですが、
最終的にはシステムコールである write() が 発行されていました。
この後は、カーネル空間に入るので、詳しくは探査出来なかったのですが・・・
#システムコール発行後の処理はどうなっているのでしょうか??
write()システムコールは デバイスファイルに対して書き込みを行うはずです。
このデバイスファイルに書かれた内容に基づいて、デバイスドライバがデバイスを制御すると思います。
ここまでは、正しいでしょうか?
この「デバイスファイルが更新された」というのは、デーモンプロセスが常にデバイスファイルを監視している必要がありますよね??
割り込みハンドラとは、ハードウェア割り込み発生の際に出てくるプログラムですよね?
システムコール発行時(ソフトウェア割り込み)は、割り込みハンドラを使いますか?
このデバイスファイルからデバイスドライバへの連携はどのようにして行われているのでしょうか??
カーネル空間の質問なんですが、教えてください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
こんにちは。
この「デバイスファイルが更新された」というのは、デーモンプロセスが常にデバイスファイルを監視している必要がありますよね??
デバイスファイルについて、微妙に捉え方を間違っているようです。
上記のWikipediaにあるように「ファイルシステム上であたかも通常のファイルのような形で提示されるデバイスドライバのインタフェースである。」ですので、物理的なファイルがあるわけではないです。
デバイスに「ファイル名」の構文で名前を付けたと考えて良いと思います。
ファイルやデバイスへのopenコールが「ファイル名」を解析して、適切なデバイス・ドライバと結びつけたデバイス制御用データを生成し、デバイス・ドライバのopenルーチンを呼んで初期化してから、デバイス制御用データのハンドルを返却します。
writeコールではそのハンドルを指定します。OSはそれを見て適切なデバイス・ドライバのwriteルーチンを呼びます。
(linuxのソースを読んだのはかなり昔だったので、微妙に違う部分はあるかも。)
投稿2017/04/27 14:12
総合スコア23272
0
Chironianさんが回答されてますので補足だけします。
カーネル空間でプログラムはカーネルスレッドと呼ばれる特権プロセスで動作します。これはユーザーモードプロセスとは明確に異なります。
デーモンが監視するというのはプロセスを中心にしてみていますが、幾つものプログラムが独立して並列に動いているように見えるのはOSの仕組みです。CPUを中心に見ると1msなり4msなりで次々と実行するプログラムを切り替えています。それを決めるのはスケジューラーというOSの機能で、スケジューラーの上でカーネル空間で動くタスク(カーネルスレッドで動作するプログラム)とユーザー空間で動くタスク(ユーザーモードプロセスで動くプログラム)は優先度が異なります。
またプログラムが切り替わる(コンテキストがスイッチする)条件は、
- タイムスライスを使い切ったとき
- システムコールを呼び出したとき
- IO待ちからの復帰時
- プロセス生成、終了時
などでこれ以外にもいくつかあったと思います(が思い出せません)
プロセスのスケジュールに関する統計は/proc/プロセスID/schedで見ることができます。
以下例としてbashのスケジュール統計。
nr_switchesが1091なので138回スイッチされています。
nr_voluntary_switchesは自発的なスイッチ回数です。
一方でnr_involuntary_switchesは非自発的なスイッチ回数で、タイムスライスを使い切ると多くなります。
[root@localhost ~]# cat /proc/18060/sched bash (18060, #threads: 1) ------------------------------------------------------------------- se.exec_start : 1159654106.105410 se.vruntime : 18776825.967971 se.sum_exec_runtime : 4619.692993 nr_switches : 1091 nr_voluntary_switches : 1042 nr_involuntary_switches : 49 se.load.weight : 1024 policy : 0 prio : 120 clock-delta : 25 mm->numa_scan_seq : 0 numa_migrations, 0 numa_faults_memory, 0, 0, 1, 0, -1 numa_faults_memory, 1, 0, 0, 0, -1 #ビジーループを回してみる [root@localhost ~]# while [ 1 ]; do a=$(( 1 + 1 )); done [root@localhost ~]# cat /proc/18060/sched bash (18060, #threads: 1) ------------------------------------------------------------------- se.exec_start : 1159675494.749491 se.vruntime : 18776298.610844 se.sum_exec_runtime : 21809.142310 nr_switches : 1322 nr_voluntary_switches : 1049 nr_involuntary_switches : 273 se.load.weight : 1024 policy : 0 prio : 120 clock-delta : 21 mm->numa_scan_seq : 0 numa_migrations, 0 numa_faults_memory, 0, 0, 1, 0, -1 numa_faults_memory, 1, 0, 0, 0, -1
投稿2017/04/28 01:56
総合スコア910
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/27 14:39 編集
2017/04/27 15:15
2017/04/27 15:36
2017/04/27 16:12
2017/04/28 03:18
2017/04/28 03:34
2017/04/28 03:39
2017/04/28 03:47
2017/04/28 04:19
2017/04/28 04:26
2017/04/28 05:18
2017/04/28 15:19