まずはC言語
カーネルを読みたければC言語が必須だけど、書けなくても、要は読めればよろしい。
カーネルに main 関数はない。割り込みがかかってその都度呼び出されるから。
% cat -n p.c 1 #include <stdio.h> 2 3 string() 4 { 5 char msg[]="Linux"; 6 fprintf(stdout, "msg[1]=%c\n", msg[1]); 7 } 8 9 10 main() 11 { 12 int abc=123; 13 fprintf(stdout, "abc=%d\n", abc); 14 string(); 15 } 16
コンパイルすると a.out ができる。実行してみよう。
% cc p.c % ls a.out* p.c % ./a.out abc=123 msg[1]=i
実行プログラム a.out がどんなライブラリを利用しているかは ldd でわかる。
% ldd ./a.out linux-gate.so.1 => (0xffffe000) libc.so.6 => /lib/i686/libc.so.6 (0xb7e26000) /lib/ld-linux.so.2 (0xb7f51000)
libc.so.6 がライブラリ名で、/lib/i686/libc.so.6 がライブラリファイル名となる。
$ nm /lib/i686/libc.so.6 nm: /lib/i686/libc.so.6: シンボルがありません $ ls -l /lib/i686/libc.so.6 lrwxrwxrwx 1 root root 13 12月16日 14:32 /lib/i686/libc.so.6 -> libc-2.3.4.so* $ nm /lib/i686/libc-2.3.4.so nm: /lib/i686/libc-2.3.4.so: シンボルがありません
なんでじゃ、まあよい、先に進もう。
% rpm -qif /lib/i686/libc-2.3.4.so Name : glibc Relocations: (not relocatable) Version : 2.3.4 Vendor: (none) Release : 2vl3 Build Date: 2006年07月17日 21時19分45秒 Install Date: 2006年12月16日 14時32分35秒 Build Host: windy.local.dicey.org Group : System Environment/Libraries Source RPM: glibc-2.3.4-2vl3.src.rpm Size : 9405038 License: LGPL Signature : DSA/SHA1, 2006年07月17日 21時19分49秒, Key ID 90bf4c0974322cb0 Packager : Daisuke SUZUKI <daisuke@linux.or.jp> Summary : GNU libc ライブラリ Description : glibc パッケージはシステム上の複数のプログラムで使われる標準ライブラリを ふくみます。ディスクスペースとメモリを節約したり、アップグレードを 用意にするために、共通のシステムコードは一つの場所におかれ、プログラム 間で共有されます。この部分的なパッケージはシェアドライブラリのかなり 重要なセットをふくみます: 標準 C ライブラリと標準数値ライブラリです。 この二つのライブラリ抜きでは、Linux システムは機能しません。
今回のプログラムは fprintf で標準出力に表示してるだけだけど、ちょっとだけカーネルの処理が入っている。fprintfはvfprintfという別の関数に分岐していて、vfprintf関数は画面に表示するために write() という関数を呼び出している。write はライブラリではなくカーネルの一部。つまりwrite関数のソースはカーネルソースに書かれている。カーネルの関数をシステムコールと呼んでいる。
システムコールかライブラリかを簡単に見分ける方法はオンラインマニュアルのどのセクションに書かれているかで判断できる。
セクション | 内容 |
---|---|
1 | ユーザコマンド |
2 | システムコール |
3 | ライブラリ関数 |