Linux道場入門編
第6回Linuxの構造
今回はLinuxの構造についてのお話です。構造といっても、ここでお話しするのはカーネルの内部的なことではなく、少し表面的な部分です。カーネルとそれをとりまくソフトウェアやライブラリ、ブートローダ以降の起動シーケンスにおける、プログラムの起動やディストリビューションごとの際などが今回のお話です。このあたりは、第二回の「ディストリビューションとは」で少し触れましたが、今回は少し踏み込んでお話したいと思います。
Linuxカーネルの特徴
OSの構造には色々なタイプがありますが、Linuxカーネルのタイプはモノシリックカーネルと呼ばれ、全ての機能がカーネル内に1つに統合されています。これとは逆のタイプがマイクロカーネルと呼ばれるもので、マイクロカーネルはカーネルの機能をコンパクトにまとめてその他の機能は別の機能として実装し、それらが連携して動作するというものになります。
- ※モノリシックとは「一枚岩の」という意味です。
これはカーネルを含む全ての機能が1つの岩のようにまとまって見えるようなことからこのように呼ばれます。
モノリシックカーネルは、一見すると柔軟性のないものに見えますが、Linuxの場合モジュールのダイナミックローディングという機構を採用しているため、モノリシックカーネルでありながら、柔軟なカーネル構造になっています。モジュールのダイナミックローディングとはドライバなどをモジュールとして扱い、それを動的にロードする仕組みです。この機能により、カーネルのサイズを自由に調整したり、必要なものを必要なときにロードすることが可能になっています。例えば、このダイナミックローディングの機能がなければ、ドライバを新たに追加するたびにカーネルを作り直す必要があり、サードパーティなどが Linux用の新しいデバイスドライバだけを配布することが困難になります。
- ※いくらダイナミックローディングの機能があっても、
異なるカーネルバージョンのドライバを動的にロードすることはできませんが。
Linuxはこの仕組みによりカーネルを柔軟にカスタマイズすることができるため、フロッピーディスク1枚にカーネルを入れたり、組込み環境などの低リソース環境にカーネルを移植することもできます。さらに、オープンソースであるということもあいまって、カスタマイズには基本的に制限はないといっていいでしょう。
ライブラリ
一般的にライブラリとは、プログラムの再利用可能な共通部分を抜き出して、様々なプログラムから利用可能にしたプログラムの道具のことをいいます。 Linuxでは、カーネルも含めて様々なアプリケーションやサーバなどのプログラムは、C言語というプログラミング言語で記述されており、C言語のライブラリを標準で用意することで、様々なプログラムを動作可能にしています。このライブラリをglibcといい、LinuxというOSを構成する上において、重要な役割を果たします。
基本的にディストリビューションに含まれる様々なアプリケーションは、このglibcがあることを前提としており、glibcはアプリケーションを動作させる要素として必要不可欠な存在であるといえます。
正確には、アプリケーションが記述されたプログラミング言語によって必要とされるライブラリは異なります。しかし、glibcはシェルなどのLinuxを扱う上で基本的なコマンド群からも利用されるとともに、カーネルからも利用されるというLinuxを構成する上で重要な要素といえます。
initプロセスとランレベル
前回のブートローダのお話で、ブートローダがどのようのようなもので、Linuxがどのように起動されるかをお話しました。ブートローダにより Linuxカーネルが起動された後に、様々なサービスが起動しますが、このサービスの起動を行う大元のプログラムがinitといわれるものです。通常プログラムが実行され、起動されるとLinux上でプロセスという存在になります。プロセスは、プログラムが実行によりLinuxにメモリ空間などのコンピュータリソースを割り当てられた実行状態のことをさします。Linux上でプロセスは階層構造で管理されており、この階層構造のトップにあるのが initプロセスです。
initプロセスはカーネルが最初に実行するプロセスで、このinitプロセスが起動すると、カーネルは制御をinitプロセスに移行し、init プロセスが様々なサービスを起動する仕組みになっています。通常プログラムからさらに別のプログラムが実行される場合、起動後のプロセスに親子関係ができます。起動した側のプロセスを親プロセス、起動された側のプロセスを子プロセスと表現します。このことから、initプロセスは全てのプロセスの親プロセスと呼ばれ、常にプロセスの構造の最上位になっています。
initプロセスは起動時に色々なプログラムを実行する仕組みを持っていますが、このinitプロセスが実行するプログラムによりLinuxの実行形態が変化します。このinitプロセスが実行する内容によるLinuxの実行の変化を、ランレベルといいます。ランレベルには0〜6までのレベルがあり、それぞれに以下のような意味があります。
ランレベル | 動作内容 |
---|---|
ランレベル0 | システムの停止 |
ランレベル1、s、S | シングルユーザモード |
ランレベル2 | NFSファイル共有のないマルチユーザモード Debian:完全マルチユーザモード(GUIベース) |
ランレベル3 | 完全マルチユーザモード(テキストベース) |
ランレベル4 | 通常、未使用 Debian:完全マルチユーザモード(GUIベース) |
ランレベル5 | 完全マルチユーザモード(GUIベース) |
ランレベル6 | システムの再起動 |
通常起動時のランレベルは3などになり、システムをシャットダウンするという行為はランレベル0を呼び出しているということになります。このランレベルは結局initプロセスの動作を指定するもので、起動から停止に至る制御をinitプロセスが行っているということを端的に示すものです。
initプロセスが実行するプログラム群は、自由に設定することができ、その起動の順番も制御することができます。起動順を指定することは重要で、起動の順番を不正なものにすると起動できないサービスがでてきます。例えば、サーバなどを起動時に実行したい場合、起動ランレベルにサーバプログラムを登録しますが、このサーバの起動順がネットワークサービスより早く設定されてしまうと、サーバは起動できません。無論これはネットワーク機能が有効になっていないのにサーバは機能できないからです。
- ※通常、基本機能は最初のほうに実行されるようになっているため、このような心配をすることはあまりないと思います。
注意が必要なのは、ランレベルにはディストリビューションごとに差異があるということです。基本的にランレベルで実行されるプログラム群は特定の場所に起動スクリプトが配置されるようになっていますが、これはディストリビューションごとに配置場所がことなります。またランレベルの定義もディストリビューションごとに異なっています。実はLinuxの標準仕様で定義されているのは、ランレベル0、1、6の動作だけです。その他の2〜5の動作については特に標準定義がなく、ディストリビューションによっているため、ディストリビューションによっては通常起動レベルがことなる場合があります。
- ※Redhat系のディストリビューションでは、ランレベル3か5が通常起動になっています。
今回は代表的なLinuxを構成する要素のお話をしましたが、その他にも細かい要素は色々あります。このような構成を自身で紐解いていくのも1つの勉強方法かもしれません。
コラム執筆/末永 貴一
株式会社エイチアイ研究開発部 部長
ヒューマンインターフェイスの研究開発、コンテンツの開発を行う株式会社エイチアイで次世代技術の研究開発を行う業務を担当している。 オープン系のシステム開発事業、教育事業を経て、自社独自の組込み機器向け3DリアルタイムレンダリングエンジンであるミドルウェアのMascotCapsuleを中心とした開発に従事した。数年前にLinuxを知ってからはサーバ構築、開発、教育、執筆などさまざまな場面で関わるようになり、現在では組込み開発でもLinuxを利用することもある。