章3メカニズム(下)システムコール
まず、知識の一般化
割り込みベクタ0x80の間のサービスルーチンエントリ割り込みSYSTEM_CALL関係
は0x80はtrap_init関数は割込みベクタシステムコール0x80を含むset_system_trap_gate機能を呼び出し、サービスルーチンを中断SYSTEM_CALL、SYSTEM_CALLはtrap_init機能start_kernel関数と呼ばれるサービス・ルーチンのエントリを、割り込み対応します関数ポインタエントリ、SYSTEM_CALLは、関数として宣言し、割り込みベクタは0x80とSYSTEM_CALL割り込みサービスルーチンのエントリー後set_system_trap_gateを結合することにより機能、一度int型は0x80を実行され、CPUは、この場所のSYSTEM_CALLの実行にジャンプします。ユーザーモードとカーネルのシステムコールハンドラへのシステムコールインタフェースは、システムによって呼び出される番号を照合します。
ystem_call割り込みサービスルーチンの手順が
あるシステムコール番号、現在のタスクは、syscall_exit_work扱うsyscall_exit_workを入力するかどうかを判定するsyscall_exitのシステムコール対応するハンドラに記載のテーブルsys_call_table位置を確認するために、エントリ(SYSTEM_CALL)から実行されます最も一般的なプロセススケジューリングタイミングポイント。
前記sys_call_table(%eaxに、4)、ディスパッチ・テーブル内の各エントリは4バイトに理解されるように、最初のシステムコール番号(EAX)は4、プラスsys_call_tableディスパッチテーブルの開始アドレスが乗算され、システムコールは、ポインタ番号に対応するシステムコールカーネルハンドラを取得します。
以下に示すようSYSTEM_CALLフローチャートが実行されます。
CMPL部分は(nr_syscalls未満でなければならない)システムコール番号を確認することである、それは、回復、戻り値のMOVL一部が、もしあればsyscall_exit_workが入力され、タスクが対処する必要があるかどうかを確認syscall_exit、スタックに保存されているsyscall_badsys例外処理にジャンプする法的ではありませんサイト。
第二に、実験:分析は、処理を中断SYSTEM_CALL
メニューの古いディレクトリを削除し、新しいバージョンを再ダウンロードしてください。次のように:
$ cd /home/shiyanlou/LinuxKernel
$ rm -rf menu
$ git clone http://github.com/mengning/menu.git
$ cd menu
test.cのは、ディレクトリのメニュー内のファイルを変更し、独自のコードを書くための最後のクラスは、システムコールのリストに追加した2つのメニューコマンドを作っています。test.cのファイルには、次のコードを追加します。
#include <sys/stat.h>
#include <sys/types.h>
...
int MakeDir() {
int ret = 0;
ret = mkdir("./testdir", 0777);
printf("ret is: %d.\n", ret);
return 0;
}
int MakeDirAsm() {
int ret = 0;
//ret = mkdir("./testdir", 0777);
char *dir = "./testdir";
int mode = 0777;
asm volatile(
"movl %1, %%ebx\n\t"
"movl %2, %%ecx\n\t"
"movl $39, %%eax\n\t"
"int $0x80\n\t"
"movl %%eax, %0\n\t"
: "=m"(ret)
: "m"(dir), "m"(mode)
);
printf("ret is: %d.\n", ret);
return 0;
}
int main()
{
...
MenuConfig("make-dir","Make Directory",MakeDir);
MenuConfig("make-dir-asm","Make Directory(asm)",MakeDirAsm);
...
}
プログラムを再コンパイルして起動します。
$ make rootfs
インターフェイスでhelpコマンドを入力し、あなたがmake-dirのを見ると、これらの2つのコマンドは正常にこのシステムに適用されている-DIR-ASMを作ることができます。また、コマンドが正常に実行されたことを示し、通常0を返すの結果であり得るメイクDIRコマンドを実行します。下図のように:
再起動するカーネルへのコマンドおよび次のコマンドを実行するには、「フリーズ」システムを-sと-Sパラメータを使用qumuを使用します。
$ cd /home/shiyanlou/LinuxKernel
$ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
プログラムは次のような効果がある、ウィンドウを起動すると、プログラムを促し、「フリーズ」「[停止しました]」
gdbデバッガでこのケースでは、それは水平スプリット・ウィンドウを必要とし、次のように入力します。
$ gdb
(gdb) file linux-3.18.6/vmlinux
Reading symbols from linux-3.18.6/vmlinux...done.
(gdb) target remote:1234
Remote debugging using :1234
0x0000fff0 in ?? ()
(gdb) continue
fileコマンドは、シンボルテーブルのLinuxカーネルのコードをロードするために使用されている、プログラムを接続するためのターゲットは、GDBデバッガを開始されました。終了後、実行はプログラムを継続し続けます。
システムの起動が完了した後は、<C + C>プログラムにブレークポイント割り込みシステムをマークし、次のようにプログラムの実行が継続し続けます。
(gdb) break sys_mkdir
Breakpoint 1 at 0xc1139220: file fs/namei.c, line 3525.
(gdb) continue
設定しsys_time
、ブレークポイントを起動menuOS
時における停止するシステムコールを入力するには、実行時間のコマンドをsys_time
この機能。
システムコール
どのようにシステムの動作は、それを呼び出しますか?上記の例では、それはそれのsys_mkdirカーネル関数を呼び出すことができるようにする方法ですか?
プログラムは、この0x80の命令INTがSYSTEM_CALLで実行するために立ち上がります実行すると、この対応は、時間によって、固定の割り込みベクター設計です。
time_asm
それはに駐車見つかったsys_time
中で、位置sys_call
停止しません。
第三に、要約
- SYSTEM_CALLシステムコールを処理するコードのこのセクションは、システムコールが中断の特別な点は、一般的に拡張することができ、私たちは、保護とリカバリサイトSAVE_ALLサイトrestore_allを持っています。
- システムコール:、プロセスを扱う入場システムコールから行くシーンSAVE_ALLを保存し、システムコール番号がrestore_allとIRET復旧サイトの後、カーネルハンドラを呼び出すことが正当かつ合法的でチェックし、ユーザーモードに戻るには、このプロセスの間に実施することができますタスクの切り替え処理。