🐧 Linux 総合学習プラットフォーム
システムコール ・ 上級

システムコールの呼び出し機構(番号・トラップ・ラッパ)

read や write を呼ぶと何が起きるのか。番号付けされたシステムコールが、CPUのトラップ(ソフト割込み)でカーネルへ制御を渡し、glibcのラッパ関数がその橋渡しをする流れをたどる。

read や write を書くと、まるでただの関数呼び出しのように見える。だが実際には、そこでユーザ空間からカーネル空間へ制御が渡るという、普通の関数呼び出しとはまったく違う出来事が起きている。その境界を越える仕組みが、システムコールの呼び出し機構だ。

🧩 番号で管理されている

カーネルは、どのシステムコールを呼びたいのかを名前ではなく番号で受け取る。read なら何番、write なら何番、と決まった対応表があり、その番号は環境によって異なるがヘッダで定義されている。

💡
ポイントNOTE: システムコール番号の一覧は `sys/syscall.h` などから辿れる。番号はアーキテクチャ(x86_64 と ARM など)で異なるため、同じ read でも番号は同じとは限らない。

🧩 トラップでカーネルに入る

番号を決めたら、CPUに特別な命令(トラップ、いわゆるソフト割込み)を実行させる。これによりCPUは特権レベルを上げてカーネルの入口へジャンプし、カーネルは渡された番号を見て対応する処理を実行する。終わると結果を持ってユーザ空間へ戻る。

💡
ポイントANALOGY: 銀行の窓口のようなもの。客(プログラム)はカウンタの内側(カーネル)に直接入れない。番号札(システムコール番号)を持って呼び鈴(トラップ)を鳴らし、行員(カーネル)に作業してもらって結果だけ受け取る。

🧩 glibc のラッパが橋渡しする

C言語で read() と書けるのは、glibc がラッパ関数を用意しているからだ。ラッパは番号を積んでトラップを起こし、戻ってきた値を確認して、失敗なら errno を設定して -1 を返す、という定型処理を肩代わりする。だから我々は番号やトラップを意識せずに関数として呼べる。

💡
ポイントEX: `strace ./a.out` を実行すると、`execve(...)`, `brk(0)`, `write(1, "...", 14)` のように、そのプログラムが実際に発行したシステムコールが番号ではなく名前で並んで見える。ここがユーザ空間とカーネル空間の会話の記録になっている。

この項目に出てくる用語

システムコール番号しすてむこーるばんごう
各システムコールに割り当てられた識別番号。
トラップ(ソフト割込み)とらっぷ
ユーザ空間からカーネルへ制御を渡すCPUの仕掛け。

▶ 学習アプリでこの続きを学ぶ・演習する