Mímisbrunnr知恵の泉

← コンピュータ基礎 一覧

🎓 レベル:基礎 | 重要度:A(必須)

📎 前提:入出力とバス・割り込み | 関連:プロセスとスレッド物理メモリと論理アドレス

要点(BLUF)

概念 ── OSは「ハードの受付係 兼 警備員」

コンピュータには1つのCPU(実際は数コア)、有限のメモリ、各種I/O機器しかありません。そこで多数のプログラムを同時に走らせ、互いに干渉させず、ハードを壊させないために、仲介者が要ります。それがOSです。

OSの仕事は大きく2つ:

  1. 仮想化(抽象化):物理資源を扱いやすい形に見せる。1つのCPUを「各プロセス専用CPU」に、物理メモリを「各プロセス専用アドレス空間」(物理メモリと論理アドレス)に、ディスクを「ファイル」(ファイルシステムの構造)に。
  2. 保護と調停:あるプログラムが他のメモリを壊したり、ハードを独占したりしないよう、アクセスを管理し公平に配分する(CPUスケジューリング)。

要するにOSは、限られたハードを「みんなが安全に・公平に使える共有設備」に変える管理者です。

仕組み① ── 特権モードとユーザモード

もしどのプログラムもハードを直接いじれたら、1つのバグや悪意が全体を巻き込みます。そこでCPUは2つの動作モードを持ちます。

flowchart TB
    subgraph U["ユーザモード(アプリが動く・権限が低い)"]
      app["アプリA / アプリB / ..."]
    end
    subgraph K["カーネルモード(特権・ハードを直接操作)"]
      kern["カーネル(スケジューラ・メモリ管理・ドライバ)"]
    end
    app -->|"システムコール (trap)"| kern
    kern -->|"結果を返す / 復帰"| app

この線引きがあるから、アプリのバグはそのプロセス内に閉じ、カーネルとOS全体は守られます。CPUがハード機構として「今どちらのモードか」を持つのがポイント(ソフトの約束だけでは破れる)。

仕組み② ── システムコール

ユーザモードのアプリがファイルを読む・メモリを増やす・プロセスを作るには、結局カーネルの力が要ります。その依頼の窓口が システムコールです。

sequenceDiagram
    participant A as アプリ(ユーザモード)
    participant C as CPU
    participant K as カーネル(特権モード)
    A->>C: システムコール命令 (trap)
    Note over C: モードをカーネルへ切替・PCをハンドラへ
    C->>K: システムコールハンドラ起動
    K->>K: 引数を検証し処理(例: ディスク読み取り)
    K-->>C: 復帰命令
    Note over C: モードをユーザへ戻す
    C-->>A: 戻り値を返す

read()write()open()fork()プロセスとスレッド)といったライブラリ関数の内部は、最終的にこのtrap命令でカーネルへ制御を移します。これは 入出力とバス・割り込み の割り込みと同じ「PCを書き換えてハンドラへ飛ぶ」機構を、ソフトから意図的に起こすもの(ソフトウェア割り込み)。

要するにシステムコールは、特権の壁に開いた、検査付きの唯一の窓口。アプリは「何をしてほしいか」だけを渡し、危険な操作の実体はカーネルが代行します。

具体例 ── 実機でシステムコールを覗く

Linuxでは strace でプロセスが発行するシステムコールを一覧できます(対応ラボ)。strace ls とすると、openatreadwriteclose などが並び、「ls という小さなコマンドすら、ファイル一覧の取得や画面出力をすべてカーネル依頼で行っている」ことが見えます。

仕組みの直観 ── なぜこの設計か

⚠️ よくある誤解・落とし穴

対応ラボ

cs-foundations-study/labs/02-01_strace.md(Linux: strace ls でユーザコマンドが発行するシステムコール列を観察し、I/Oがすべてカーネル依頼であることを確認する手順)。

関連

第2章 オペレーティングシステム 目次