書籍「実習Linuxカーネル」によるLinuxの学習を紹介します。
発行日は2001年12月30日です。
本書の感想
この本では、Linux 2.2.14 がベースになっています。 2部構成になっていて、第1部は、Linuxの概要を紹介しています。 第2部はLinuxのカーネルに関係する12の実習を行うことで、カーネルの理解を深めるようになっています。
現在のLinuxのカーネルは2.6.Xになっており、説明が実状にあっていない部分も多々あります。 そこはカーネルのバージョンの違いを理解するいい機会と思い、自分で違いを吸収する方法を調べながら読み進めています。 ちょうど、自宅に2.2.Xの次のバージョンの2.4.XのカーネルをインストールしたノートPCがあったので、 それを実習用に使います。2.4.Xで理解が終わったあとに、現状の2.6.Xのカーネルをインストールしなおして、 2.4.Xから2.6.Xのバージョンの違いを理解しながら、本書の内容を復習したいと思います。
実習の進め方としては、
1. 第1部をざっと読む
2. 第2部の演習のうちカーネルのリビルドが必要ないものを実施
3. 第2部の演習のうちカーネルのリビルドが必要なものを実施
4. 第1部を読み返す
というのが良いかと考えています。
第2部 1. Linuxの振る舞いを観察する
↑上へ戻る第2部 2. シェルプログラム
↑上へ戻る第2部 6. 共有メモリ
注:カーネルのリビルドが必要な実習です。
System Vの共有メモリ機能がカーネルでどのように実装されているかを学習します。
共有メモリが利用される目的は、プロセス間通信です。
異なる役割を持つプロセスが互いに情報をやりとりしようとするときに、 一番簡単な方法は、お互いの知っているグローバル変数を使うことです。 しかし、この方法は、グローバル変数名を知ってさえいれば、他のプロセスからも簡単に参照し、 更新することができてしまいます。セキュリティー面が弱い実現方法です。 また、参照できるプロセスを限定したとしても、 並列で動作するプロセスが想定する更新するタイミングと参照するタイミングが実際にずれてしまった場合に、 情報のミスマッチが発生しやすくなります。 これを防ぐためには、セマフォなどの排他処理が必要になります。
グローバル変数を使った場合のデメリットとして、データ構造が固定されるので、
変更に弱いと言えます。結合度が高いと言い換えられます。
共有メモリ用APIとしては、
shmget() : 共有メモリブロックを生成する
shmat() : 生成した共有メモリブロックをプロセスのアドレス空間にマップする
shmdt() : プロセスのアドレス空間への共有メモリブロックのマップを解除する
shmctl() : 共有メモリブロックを操作する
が用意されています。
これらは、Linuxのソースツリーの/linux/ipc/shm.cで実装されています。
↑上へ戻る第2部 7. 仮想メモリ
注:カーネルのリビルドが必要な実習です。
Linuxの仮想メモリの実装は、一般的なアーキテクチャ独立のメモリモデルを基本としています。 上位の抽象化層と下位のハードウェア依存層に分かれていて、たとえば、Intelのi386系CPUであれば、 i386が持つページテーブルの機能やメモリ管理機構に合うように実装がなされます。
アプリケーションプログラムやカーネルはこの仮想アドレス空間を使ってメモリ操作を行うことができ、 実際にハードウェアとしてのSDRAMなどのメインメモリにアクセスするための物理アドレスへの アドレス変換の部分は気にする必要をなくしています。
仮想メモリはページ単位で実施されます。マップされたページが実メモリ上に無い場合は、 ページフォールトと呼び、このとき、実メモリ上のデータをディスクなどに退避してから、 必要なデータを実メモリから読み込みます。この退避する動作がスワップ(交換)という処理になります。
仮想メモリは環境に対して非常に柔軟な設計ですが、メモリアクセスの度にアドレス変換が入るので、 そのオーバーヘッドが心配になります。そのため、アドレス変換はTLBと呼ばれる参照テーブルを メモリ上に確保して計算の代わりにテーブル参照するだけにしたり、 実装自体をアセンブラなどでチューニングにしたりしています。
通常、DMAのようにCPUを経由せずに、 独立したハードウェアがデータをメインメモリとの間でやり取りする場合は、 このアドレス変換がスキップされてしまうので、データの整合性が問題になります。 Linuxではこの問題をどう回避しているのでしょうか?
↑上へ戻る