level2
open system callを処理する部分を見つけよ。Linuxのシステムコールは、
- アプリケーションが呼び出すライブラリ
- ライブラリが呼び出すtrap
- trapを受け取り振り分ける部分
- 実際にkernel内部で処理する部分
がある。それぞれ、どこにあるのか調べよ。
システムコールとは、オペレーティングシステムの機能を呼び出すために使用さ
れる機構のこと。
実際のプログラミングにおいてはOSの機能は、関数(API)呼び出しによって
実現されるので、
OSの備える関数(API)のことを指すこともあります。
システムコールは、多くの場合、ソフトウェア割り込みによって実行されます。
ソフトウェア割り込みを用いてCPUの動作モードを遷移させることによって、
通常のアプリケーションプログラムからはアクセスできない保護された
メモリ領域にアクセスすることや、
保護されたレジスタを操作すること、また、自らCPUの動作モードを
変更することなどが可能になります。
アプリケーションがライブラリを呼び出す際、つまり、プログラムのmake時
には、
リンカ(ld)はまず/usr/lib/libc.soにアクセスします。このファイルは、以
下のようなldのスクリプトになっています。
/* GNU ld script
Use the shared librarys but some functions are only in
the staticc library. so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
GROUP(/lib/libc.so.6 /usr/lib/libc_nonshared.a )
Linuxのシステムコールは、レジスタに引数を設定してint 0x80によるソフトウェ
ア割り込みで呼び出します。
/usr/src/linux/init/main.cでは、カーネルの起動部分で割り込みテーブ
ルの設定をしています。
369 printK("kernel command line : %\n".saved_command_line);
370 parse_options(command line);
371 trap_init();
372 init_IRQ();
373 sched_init();
371行目にあるtrap_init()でシステムコールの入り口が設定されます。
それを、実際に設定している部分は、
/usr/src/linux/arch/i386/kernel/traps.c
にあり、以下のようになっています。
957 void __init trap_init(void)
958 {
...
989 set_system_gate(SYSCALL_VECTOR,system_call);
SYSCALL_VECTORは、別のファイルで0x80と設定されています。
ライブラリからtrapを受け取り、システムコールを振り分ける部分は、
/usr/src/linux/arch/i386/kernel/のentry.Sにあります。
entry.Sの中は、以下のように実装されています。
222 ENTRY(system_call)
223 push %eax
224 SAVE_ALL
225 GET_CURRENT(%ebx)
226 testb $0x02.tsk_ptrace(%ebx)
227 jne tracesys
228 cmpl $(NR_syscalls) .%eas
229 jae badsys
230 call * SYMBOL_NAME(sys_call_table)(.%eax.4)
231 movl %eax.EAX(%esp)
230行目の call *SYMBOL_NAME(sys_call_table)(.%eax 4)では、
eaxに指定されたシステムコール番号を入れることで、処理を振り分けます。
システムコール openのプログラムの場所は、/usr/src/linux/fs/open.cにあり
ます。
他のシステムコールのプログラムも、/usr/src/linux-2.4.27/fs/や
/usr/src/linux/kernel/等にあります。
このLevel2の実験で、システムコールやライブラリ関数について色々と調べて
みた結果、
ライブラリ関数が内部でシステムコールを呼び出していることが分かりました。
そこで、
システムコールを使わずにライブラリ関数を使うメリットについて調べてみたら、
以下のようなことが挙げられました。
- 移植性の向上
- バッファリングによる速度向上
- 利便性向上(システムコールを使うよりライブラリを使った方が簡単かつ
短く書ける)
つまり、プログラムを書く際は、できるだけライブラリ関数を使用した方が良い
プログラムになると思います。
Linuxでアセンブリプログラミング
http://www.nk.rim.or.jp/~jun/lxasm/asm_idx.html
Linux C Library(libc)について
http://www.linux.or.jp/JF/JFdocs/libc-intro.html
システムコールとは
アプリケーションが呼び出すライブラリ
ライブラリが呼び出すtrap
trapを受け取り振り分ける部分
実際にkernel内部で処理する部分
考察
参考リンク
level1
top
level3