まずは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 ライブラリ関数