高等学校工業/ソフトウェア技術/カーネルとユーザーランド

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

OSの内部構造[編集]

カーネルとスーパバイザ[編集]

OSの機能の中には、メモリの制御など、普通の人には使い方が難しい機能もある。また、メモリの制御やCPUの制御に失敗すると、データを破壊してしまったりする場合もある。

なので、普通の使用方法では、メモリの制御やCPUの制御などは、利用者は、直接は細かい動作指示はできないようになっている。OSが、自動的に判断して、メモリやCPUの制御を行ってるのである。

そのいっぽうで、そのパソコンに、なにもかも利用者が指示できなかったら、そもそもコンピューターを使う意味がない。(たとえば、インターネットを閲覧するための機能すら指示できなかったら、webすら見られない。)

そこでOSでは、利用者が簡単に指示できる事と、簡単には指示できない事とを分けている。

慣習的に、OS内のプログラムのうち、メモリの制御やCPUの制御などのためのプログラムで、利用者が直接は指示できないプログラムのことをカーネル(kernel)という。

そして、(カーネル以外の)他のプログラムが、メモリやCPUなどを制御する必要のある場合は、カーネルを仲介して、制御するようになっている。 また、カーネル以外の一般のプログラムが、カーネルにメモリやCPUなどの制御を依頼することを、スーパバイザコールという。(OSによっては「システムコール」ともいう。)

カーネル以外[編集]

実務的には、カーネル以外のプログラムでも、OSの利用に必要不可欠のものはある。たとえば、マウス入力によるマウスカーソルの制御などのプログラムは、べつにメモリでもなければCPUでもないが、しかしマウスカーソルの制御プログラムがなければ、マウス操作すらできない。また、GUI画面も、それがなければ、さまざまな入力操作が不便であろう。

(※ 「GUI」という用語については、普通科高校の『情報の科学』などで習うはず。)

このマウスカーソル制御のような、カーネルではないが、そのOSでは明らかに必要不可欠なプログラムがある。

また、マウスカーソルの制御の前提として、OSがマウスを認識する必要があり、マウスからの入出力を認識する必要がある。結局、OSは、入出力デバイスを認識する必要がある。このような、入出力デバイスなど、外部デバイスを認識するためのプログラムのことをデバイスドライバ(device driver)という。

デバイスドライバは、OSが提供する場合もあるが、ハードウェア生産業者が提供する場合もある。

たとえば、プリンタやデジタルカメラなどのパソコン用ハードウェアを購入したさい、windowsパソコンでそのプリンタやデジカメを動作させるためのデバイスドライバをインストールするためのCD(コンパクトディスク)などが、購入品に付属している場合もある。

なお、そのハードウェアの生産業者のwebサイトから、デバイスドライバをダウンロード出来る場合もある。

(※ 普通科高校『情報の科学』『情報と社会』の検定教科書では、デバイスドライバについて扱っていない。)


※ 範囲外: シェル[編集]

(※ 信ぴょう性は、読者の自己責任で判断してください。)

GUI(グラフィカルユーザーインターフェース)画面は、一見するとCUI(キャラクタユーザインタフェース)のコマンド入力画面とは別物に見えるが、じつはGUI画面を表示していても、OS内部のいくつかのプログラムには、CUIのコマンド入力画面でも使うプログラムと同じものがある。

たとえば、ファイルの移動やコピーの機能は、GUIでもCUIでも必要である。

ファイル操作の機能の提供のように、カーネルではないが、GUIモードでもCUIモードでも、OSでほぼ必ず必要になると思われるプログラム郡のことを「シェル」(shell)という。shell とは。そのカーネルを覆っている殻(から)という意味であるらしい。シェルは、CUI操作で使えるため、そのOSのCUI端末モード(windowsの場合は「DOSプロンプト」)のことを「シェル」という場合もある。

※ 範囲外: ユーザランド[編集]

カーネル以外にも、デバイスドライバやシェル、さらにはOS提供のGUI(グラフィカルユーザーインターフェース)、OS提供のライブラリなど、OSに必要な機能が多くある。

OSの提供するプログラムのうち、カーネル以外のプログラムすべてをまとめてユーザランド(user land)という。

スーパバイザコールを使わないでも、そのパソコンの利用者がパソコン上で操作できる範囲のOS機能が、ユーザランドの範囲内の機能だという事になる。


プログラミングの手法[編集]

オペレーティングシステムの特徴のひとつとして、プログラミングの作業負担を減らすために様々な機能が提供されている、という特徴がある。

オペレーティングシステムの機能は、必ずしもプログラミングのためだけのものではないが、ともかくプログラミングの負担を減らすことも、オペレーティングシステムの機能のひとつである。

このため、オペレーティングシステムの仕組みを勉強する前に、我々は予備知識として、プログラミング手法について勉強しよう。

また、OS自体がプログラムでもあるので、プログラミング手法を理解する事は有益である。

OS自体、構造化(下記に説明されている)がされており、さまざまなモジュール(自動車に例えると「タイヤ」や「フロントワイパー」のような、ある程度まとまって自身の機能・目的を持つ部品のような意味)の集合体になっている。

※ 範囲外: 構造化プログラミング[編集]

構造化してないダメな例[編集]

まず、ダメなプログラミング手法の例を説明する。

たとえばゲーム制作のため、そのゲームをプログラミングをするさい、ジャンルがRPG(ロールプレイングゲーム)だとして(RPGやドラクエやファイナルファンタジーみたいなジャンル)、いちいち

「スライムが敵モンスターとして出現した場合に、『たたかう』『にげる』コマンド入力などの戦闘に必要なアルゴリズムの設計」や
「ゴブリンが敵モンスターとして出現した場合に、『たたかう』『にげる』コマンド入力などの戦闘に必要なアルゴリズムの設計」や
「ゾンビが敵モンスターとして出現した場合に、『たたかう』『にげる』コマンド入力などの戦闘に必要なアルゴリズムの設計」

などのように、いちいち敵モンスターごとに同じ戦闘コマンド(『たたかう』『にげる』)を、別々の戦闘アルゴリズムとして設計するゲーム作家は、普通は、いないだろう。

以上、ダメなプログラミング手法の例である。

構造化してある良い例[編集]

では、どのようにプログラミング手法を改善すれば良いだろうか。

上記のRPGゲームのゲームプログラミングの場合、『たたかう』『にげる』コマンドのように、どんなモンスターの場合でも使う共通コマンドのアルゴリズムは、独立した1つのアルゴリズムとして置くと良い。

つまり、

プログラムA: 現れた敵モンスターごとに異なるアルゴリズム。モンスターの強さや外見、特殊攻撃(スライムなら、「溶かす」攻撃)、弱点(ゾンビは、僧侶の成仏攻撃に弱い)など。
プログラムB: プレイヤーの入力コマンド『たたかう』『にげる』など、モンスターの種類に関係しない、共通のアルゴリズム。

のように、あらかじめ分離して作成しておき、その共通コマンドのアルゴリズムの使用のさいには、共通コマンドのアルゴリズムを呼び出して使うようにすれば、いちいちモンスターごとに作り直しをする必要がなく、再利用による効率化である。 (何百体もモンスターがいるゲームだってある! モンスターの数だけ共通コマンドのアルゴリズムを作りなおしたら、時間の無駄であるし、そのゲームを入れるためのCD➖ROMやハードディスク容量も無駄に消費する。)


なお、戦闘発生時に共通コマンドの呼び出しをするため、さらに次のようなプログラム

プログラムC: 戦闘が発生した場合は、プログラムAとプログラムBを実行する。

が必要になる。


上記の改善案をまとめると、

プログラムA: 現れた敵モンスターごとに異なるアルゴリズム。モンスターの強さや外見、特殊攻撃(スライムなら、「溶かす」攻撃)、弱点(ゾンビは、僧侶の成仏(じょうぶつ)攻撃に弱い)など。
プログラムB: プレイヤーの入力コマンド『たたかう』『にげる』など、モンスターの種類に関係しない、共通のアルゴリズム。
プログラムC: 戦闘が発生した場合は、プログラムAとプログラムBを実行する。

のように、動作ごとにアルゴリズムを分けて設計したほうが、効率的である、・・・という当然のことでしかない。


このように、もし自分のつくったプログラムにおいて、もし、つくったプログラムの一部分が、何度も利用する場合が生じたときは、いっそ、何度も再利用する部分を、別プログラムにしてしまうのが、効率的だろう(作業的にも、メモリ的にも、効率的だろう)。

このように、プログラミングのさい、動作内容の異なるアルゴリズムは作り分けておいて、そのアルゴリズムが必要になったときに呼び出しをするようにしておいて、制作の手間を省いたりするプログラミング手法のことを構造化プログラミングという。


なお、説明の簡単化のため、ゲーム制作を例として説明したが、「構造化プログラミング」とは、なにもゲームプログラミングだけに限らず、あらゆるプログラミングにおいて便利になる事の多い、重要な考え方である。


(※ 科目『プログラミング技術』の範囲: ) なお、プログラミング言語の「C言語」には、「関数」という機能があり(※ 数学用語の「関数」とは意味がちがう!)、C言語の「関数」機能によって、いくつもの処理をまとめて、ひとまとめの「関数」として記述できるようになっている。
さらに、C言語には「構造体」(こうぞうたい)という機能があり、たとえば、「モンスター名 = スライム、 HP=9、攻撃力=5、ゴールド=3」のような関連した数値のグループを「構造体」というのを使って、ひとまとめにできる。この「構造体」機能をつかう事で、関連性のあるデータを、ソースコード内に、ひとまとめに記述できるようになっている。

なので、C言語で普通に「関数」機能や「構造体」機能を活用すれば、いくつもの処理やデータのあつまりを、構造的に まとめる事ができ、構造化プログラミングを行いやすくなる。


ライブラリとランタイム[編集]

ライブラリ[編集]

プログラム作成のさい、三角計算などの、よく使うアルゴリズムは、すでに、プログラミング言語の作成者によりプログラムが用意されている場合があり、プログラマーは、いちいち自分でアルゴリズムを書きおこさなくても、プログラミング言語の用意してくれるアルゴリズムを呼びだすためのコードだけを書けばいい。

このような仕組みを、ライブラリ(library)という。

プログラミング言語やオペレーティングシステムなどが、すでに、プログラミング制作において良く必要になるライブラリを用意してくれている場合がある。

プログラミング言語の専門書を読めば、その言語で使えるライブラリが紹介されているだろう。

また、OSの用意するライブラリは、別々のアプリケーションでも、利用できる。


さて、技術的に重要なこととして、ライブラリは、単にプログラム作成者の作業の負担を減らすだけでなく、さらに、そのプログラムを検査する人の負担も減らす事に気づいてほしい。

また、プログラムのコードの長さを減らすことは、一般に、そのプログラムが使用するメモリの量を減らす事につながりやすく、ハードウェアの利用効率の向上にも、つながる。

どうしても、よくあるアルゴリズムを使用するさいに、既存のライブラリを使用せずに自分でアルゴリズムを記述したい場合でも、せめて、そのアルゴリズムは、再利用をできるように、してほしい。


なお、OSの提供するライブラリは、OSが異なると使用できないのが一般的である。

たとえば、windowsの提供するライブラリは、LinuxやMacなどでは、普通の方法では、利用できない。

windowsのアプリケーションなどで、そのファイルの中身が表示されているアプリケーションである場合に、拡張子が「.dll」のファイルのものを見かけることがある。この「.dll」ファイル形式こそ、windowsアプリケーションにおいてライブラリのような機能を使っているファイルである。dllは「ダイナミック・リンク・ライブラリ」(Dynamic Link Library)のことである。

※ なお linux では「.so.」などとファイル名にあるものが、ライブラリ的な機能を用いている。

なお、アプリケーションがOSの機能を呼び出すときの命令のライブラリのことをAPI(エーピーアイ、application programming interface)という場合もある。


また、なお、冒頭の節ではゲームプログラミングを例に構造化プログラミングを説明したが、しかし、OSや一般のプログラミング言語は、こういうゲーム制作専用のライブラリを提供しない。(ゲーム制作ソフトなどが、こういうゲーム制作専用の、ライブラリと似た機能を提供していたりする。ただし、名称は異なり、ゲーム制作ソフトなどでは、このようなコードの再利用の仕組みがあっても、「ライブラリ」とは呼ばないのが一般的である。詳しい仕様は、そのゲーム制作ソフトごとに異なるし、そもそも本科目はゲーム制作の科目ではないので、本書では、これ以上は深入りしない。)


範囲外: 「ランタイム」[編集]

なお、「Java」(ジャバ)というプログラミング言語でつくられたアプリケーションを動かすさいに「Javaランタイム」などと呼ばれるプログラムをインストールしておく作業が必要になる。

「ランタイム」といわれる種類のプログラムも、このライブラリと似たようなものである。


例として、パソコン用のゲーム制作用ソフトで制作されたゲームを、通常のプレイヤー(遊び手)が遊ぶ場合考えよう。(なお、Javaは別にゲーム制作ソフトではないので、誤解しないように。)

一般のプレイヤーにとっては、プログラミングの機能は不要である。また、もしプレイヤーがゲームをプレイするさいに、プログラミングのファイルを実行してしまっては、混乱のもとになる。なので、ゲームを配布するさいに、プログラミングの機能のためのファイルは、配布しないでおくか、プログラミングの勉強をした希望者だけに配布するなどの工夫が必要である。

しかし、そのゲーム制作ソフトの用意している専用ライブラリ(またはライブラリのような物)が、プレイヤーのパソコン内にインストールされていないと、そのゲーム制作ソフトで制作されたゲームは、作動しないか、異常終了する。(なぜなら、そのゲームが、専用ライブラリを用いているから。「ライブラリを参照しろ」とプログラム内に書かれているゲームの起動作業において、参照先のライブラリがパソコンに無ければ、そのゲームが起動しないか異常終了するのは、当然である。)

なので、そのゲームを配布するさい、なんらかの方法で、専用ライブラリを、プレイヤーのパソコンにインストールさせるか、もしくはプレイヤーのパソコン内で利用可能な状況に設定する必要がある。

そのためには、そのゲーム制作ソフトの用意するライブラリ群などゲーム動作に必要なものを、あらかじめ、まとめて、1つのパッケージにしておいて、配布する必要がある。(ゲーム制作ソフトの生産企業などが、こういう仕事を行っていたりする。)

いっぽう、ゲームごとに、ゲーム作家が別々のライブラリ郡を配布するのは、非効率であるし、そのライブラリ郡を検証するのに余計な手間が掛かる。

なので、ゲーム制作ソフトの生産企業が、ライブラリ群などを、あらかじめ、まとめて、1つのパッケージにして配布したりするわけがある。

そのゲーム制作ソフトの用意するライブラリ群をインストールさえしておけば、プレイヤーは、あとはゲームそのものを入手するだけで、ゲームをプレイできる、・・・という仕組みである。


このように、アプリケーションを動作させるために、ライブラリなどのような、アプリケーション動作のために追加する必要のあるものをまとめたパッケージ郡のことを「ランタイム」(runtime)という。あるファイルを「ランタイム」という場合、通常は、開発・制作などの機能は、外してあるのが一般的である。

例として、ゲーム制作ソフトを例にあげたが、「ランタイム」は別にゲーム産業にかぎった用語ではない。


OSの提供する、さまざまな機能[編集]

スワップ[編集]

パソコンの使用中で、メモリ基板の用意している容量よりも大規模なプログラムを処理する場合などに、メモリ基板の記憶容量が足りなくなる場合がある。このような場合、メモリ基板のかわりにハードディスクに処理中のデータを一時記憶する事ができ、このような仕組みをスワップという。

スワップの欠点として、スワップが実行されると、処理速度が遅くなる。なぜなら、一般にハードディスクは、(メモリ基板と比べると)ハードディスクは記憶容量は膨大であるが、しかしハードディスクは処理速度が、メモリ基板とくらべて、かなり遅い。

(そもそも、もし仮にハードディスクの処理速度が、まるでメモリ基板波に高速ならば(※ 実態とは異なる。)、そのハードディスクを主記憶装置として用いれば済むのである。もちろん実態は、ハードディスクは高速ではないので、かわりにメモリ基板を主記憶装置にしているのである。)

いわゆる「仮想メモリ」が、このスワップの事である。なお、「実メモリ」がメモリ基板のことである。ハードディスクなどの「仮想メモリ」に対して、メモリ基板を「実メモリ」と読んでいるわけである。