level2

open system callを処理する部分を見つけよ。Linuxのシステムコールは、
  1. アプリケーションが呼び出すライブラリ
  2. ライブラリが呼び出すtrap
  3. trapを受け取り振り分ける部分
  4. 実際にkernel内部で処理する部分
がある。それぞれ、どこにあるのか調べよ。

システムコールとは

システムコールとは、オペレーティングシステムの機能を呼び出すために使用さ れる機構のこと。

実際のプログラミングにおいてはOSの機能は、関数(API)呼び出しによって 実現されるので、 OSの備える関数(API)のことを指すこともあります。

システムコールは、多くの場合、ソフトウェア割り込みによって実行されます。

ソフトウェア割り込みを用いてCPUの動作モードを遷移させることによって、 通常のアプリケーションプログラムからはアクセスできない保護された メモリ領域にアクセスすることや、 保護されたレジスタを操作すること、また、自らCPUの動作モードを 変更することなどが可能になります。


1.アプリケーションが呼び出すライブラリ

アプリケーションがライブラリを呼び出す際、つまり、プログラムの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 )

2.ライブラリが呼び出すtrap

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と設定されています。

3.trapを受け取り振り分ける部分

ライブラリから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に指定されたシステムコール番号を入れることで、処理を振り分けます。

4.実際にkernel内部で処理する部分

システムコール 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