livaの雑記帳

seccamp2018(補足2)

注:このページは、セキュリティ・キャンプ2018全国大会x86 OS ゼミにおいて私が担当するテーマ(最先端OS談義)について解説したものです。

詳しくはトップページを御覧ください。

 

「OSってなんだろう?」という問いで考える、物事の考え方

 

OSの定義は結構曖昧で、いろいろな解釈ができます。「OSとはなんぞや?」という問いに皆さんは答える事ができるでしょうか?

セキュリティ・キャンプに参加したいと思ってこの文章を読んでいる方にとっては、少し難しい問いかもしれません。でも今から考えていくので、この瞬間にこの問いに答えられなくても大丈夫ですよ。

(OSの定義をご存知の方にとっては、この先の話は退屈になるかもしれません。ごめんなさい。。。)

 

話が脱線しますが、世の中には「自分がOSと定義したものがOSなんだ!」なんて事を言う人もいるようです。

そういう意見を否定はしませんが、少し乱暴なように私には思えます。これについては別トピックとして書いたので、こちらをご覧ください。

 

話を元に戻しましょう。

先に書いておくと、OSの定義は存在します。調べれば出て来ますし、既にご存知の方もいらっしゃるかもしれません。なので私の方から「OSとはこういうものだ!」と言ってしまうのも1つの方法なのですが、それでは皆さんの考える機会を奪ってしまう事になるでしょう。

そこで、禅問答チックに「私の方から皆さんに対して小さな問題を問いかけてみて、皆さんがそれに答える過程で最初の問題の答えを見つける」というようなやり方でやってみたいと思います。

このやり方は遠回りなのですが、私としては皆さん自身が似たような問いにぶつかった際、自分の力で考える上での参考にして頂ければ嬉しいです。

 

禅問答の方向性ですが、少なくとも「OSが最低でも実装していなければいけない役割/機能って何だろう?それが分かればOSの本質が分かるはずだ」というのを目指したいと思います。

それでは早速質問です。最初は簡単な質問から行きましょうか。皆さんも考えてみてください。

注:この後の話はとても長いので、時間に余裕がある時に読んでくださいね。

 

 

 

Q. LinuxWindowsはOS?

 

はい、これは殆どの人がOSだと思いますよね。では次はどうでしょう?

 
Q. OSは何もソフトウェアがインストールされていないパソコンに一番最初にインストールされているものか?(ハイパーバイザ上で動いているケースを除く)

 

以後の議論では仮想マシンやハイパーバイザの存在を少し脇に置かせてください。

その前提で考えれば、何となくこの定義は正しそうな気がします。

 

でもちょっと待ってください。パソコンには最初からブートファームウェアBIOSなりUEFIなり)が入っていますし、OSをインストールした後新しいOSをインストールしてデュアルブート構成にする、なんて事もありますよね。

なのでこれは少し違いそうです。

 
Q. OSは他のソフトウェアに依存せず、独立して動くソフトウェアであるか?

 

ちょっと意図が伝わりにくいかもしれないので補足しましょう。

皆さんが良く使うアプリケーションはOSの上で動いています。でもOSの下で動くソフトウェアは無さそうですよね。

つまりアプリケーションはOSに依存して動いているけれど、OSは何か別のソフトウェアに依存する事なく動いています。なので、これはOSの1つの特徴と言えそうです。

 

でもこれだとOSが最低限持つべき機能がイマイチはっきりしませんね。

少し質問の方向性を変えてみましょうか。

 

Q. Webブラウザを含んでいないWindowsはOSでは無い?

 

昨今のOSの多くはWebブラウザを含んでいます。WindowsであればEdge/Internet ExplorerMacならSafari等。。。

じゃあWebブラウザが無いとOSでは無いのか、と言うと別にそんな事はないですよね。実際、世の中にはWebブラウザを搭載していないOSも沢山ありますし、WindowsからWEBブラウザをアンインストールするとOSでは無くなる、なんて事はありません。

 

では少し単語を変えて同じ質問をさせてください。

 

Q. シェルがインストールされていないLinuxはOSでは無い?

 

この問いだと悩む人もいるのではないでしょうか。

シェルすらインストールされていないLinuxはOSとして価値が無いから、OSじゃ無いんじゃないか、みたいに思う人がいても不思議では無いと思います。

 

ではLinuxからシェルをアンインストールすれば、OSでは無くなってしまうのでしょうか?

もしOSで無くなってしまうのであれば、シェルとWebブラウザにどれだけの違いがあるのでしょう?シェルもWebブラウザも規模が違うだけでどちらも所詮ソフトウェアです。本質的にはさほど差は無いのではないでしょうか。

 

こう書くと「Webブラウザが無くてもパソコンは操作できるけれど、シェルが無いとパソコンを操作する事はできないじゃないか!」という反論が飛んできそうです。

しかし多くの人はお気づきでしょうが、シェルが無くてもパソコンは操作できます。いや、むしろ今時はシェルを使ってパソコンを操作する人の方が少ないですよね。情報系の人間にとってはシェルを使うのが当たり前でも、世の中の大半の人間にとってはパソコンはGUIで操作し、ファイルマネージャーやOfficeソフトを使うためのものです。

 

なのでシェルが無いからといってOSでは無いと断じるのは早計ですし、シェルがOSの本質、というわけでもありません。

「多くのOSはシェルというユーザー対話型のコマンドラインインターフェースを含んでいる」としておくぐらいが丁度良いでしょう。

 

 

 

 

なんだか話がずれていっている気がしますね。少し話を整理してみましょう。

Webブラウザもシェルも、ユーザーがコンピュータを操作するための機能を提供しています。どちらのアプリケーションもOSに無くてはならないもの、というわけではないです。

であれば次のような問いはどうでしょうか?

 

Q.「ユーザーがコンピュータを操作するための機能」を提供する事はOSの本質ではない?

 

一般的に「ユーザーがコンピュータを操作するための機能」を提供するのはアプリケーションの仕事です。Webブラウザも、ファイルマネージャも、シェルも、全てアプリケーションです。

「アプリとOS」という区分けをするなら、アプリケーションはOSに入らないわけですから、「ユーザーがコンピュータを操作する機能」はOSの仕事ではない、となります。

 

しかし一般的なOSでは、Webブラウザやファイルマネージャも含まれてOSとして売られている事が殆どです。最近はアプリケーションストアが含まれている事も多いですよね。どういう事なのでしょう?

 

これを考えるために、「OSとは多義的である」という最初の話まで戻ってみます。様々なアプリケーションを含んでいるOSを、「プロダクトとしてのOS」という観点から見てみるのはどうでしょうか?

 

最近はOSが端末にプレインストールされた状態の方が多いですが、昔はOSがパッケージとして売られていました。(これを読んでいる皆さんなら、パッケージとして売られていたり、インターネット上に公開されているOSを手に入れてインストールした経験があるかもしれません)

パッケージとして販売されているOSは、「とりあえずOSを入れたら、一通りやりたい事ができる」事を目指しています。だってそうでないと「OSをインストールしたけど、追加でソフトを沢山インストールしない限り何もできない」みたいな事になってしまいますよね。

 

ここで大事な事は、「プロダクトとしてのOS」は一般消費者から見た時のOS像であり、「ソフトウェアの分類の1つとしてのOS」とは切り口が異なるわけです。

もちろんどちらもOSですが、今恐らく(エンジニアである)皆さんが興味があるのは、後者のOSが何たるか、でしょう。

 

あ、前者が無意味と言うつもりはありませんよ?例えば話を前に戻して、「シェルはOSの一部である」と言うと納得する人が多いでしょう。シェルはユーザーが端末を容易に使えるためのアプリケーションであり、「プロダクトとしてのOS」がそれを提供している、それは全く間違っていません。

あくまで「ソフトウェアの分類の1つとしてのOS」を考える際、一緒に考えると頭がこんがらがるので、ひとまず脇に置いておきましょう、というだけの話です。

 

話を元に戻すと、「ソフトウェアの分類の1つ」としてOSを見た時、「ユーザーがコンピュータを操作するための機能」を提供するのはあくまでアプリケーションであって、OSの機能ではない、つまりOSの本質ではない、と私は思います。

 

皆さんはどうでしょうか?もしかすると「いや、ユーザーがコンピュータを操作する機能をOSが持つべきだ」と思う人もいるかもしれませんね。

もう少しその議論も続けたい所ではありますが、終わらなくなってしまいそうなので、ひとまずこの話はこれくらいにして先に進ませてください。

 

 

 

さて、全てのソフトウェアは何らかの機能を持っています。

例えばそれは計算をして計算結果を返す事かもしれないし、ユーザーとのインタラクションかもしれないし、はたまたネットワーク通信によって他のコンピュータと協調する事かもしれません。

 

結局、OSの機能って何なのでしょう?

ユーザーに対して機能を提供しないならば、OSは誰のために存在するのでしょう?

では次はこれを考えてみましょうか。

 

Q. OSは誰に対して機能を提供しているのか?

 

どうですか、頭の中に答えが浮かんできましたか?

浮かんでこない人のために、少しだけ脇道に入らせてください。

 

皆さんはC言語UNIXプログラムを書いた事がありますか?書いた事がある人は、ファイルを読み書きする際にfread()やfwrite()といった関数を呼んだ事があるのではないでしょうか。

fread()やfwrite()といった関数を呼び出すと、ライブラリ(libc)の中でread()やwrite()が呼ばれます。これは関数ではなくシステムコールと呼ばれるもので、OSに対して処理の実行を依頼しています。

 

つまり、OSはアプリケーションに対してシステムコールを提供しています。

 

他にもOSが提供している機能はいろいろあります。

例えばファイルシステムはOSが提供している機能ですよね。アプリケーションがファイルシステムについて何も考えずとも、とにかくファイルパスさえ渡せばOSの方で良しなに処理してくれて、ストレージの適切な場所を読み書きする事ができます。

これもまたOSがアプリケーションに対して提供している機能です。

 

おっと、「ファイルシステムはユーザーに対してもファイル操作機能を提供しているから、ファイルシステムはユーザーに対しても提供されているじゃないか!」という声が聞こえてきそうです。でもよく考えてみてください。ユーザーは「シェルやファイルマネージャを通して」ファイル操作をしているわけで、ユーザーにファイル操作機能を提供しているのはシェルやファイルマネージャといったアプリケーションです。そしてこれらのアプリケーションもまた、裏でOSを呼んでファイル操作を肩代わりしてもらっています。なので、OSはあくまでアプリケーションに機能を提供しているわけです。

 

他にはデバイスの制御もOSの重要な役目でしょう。

TCP通信をしたいと思った時、NIC(ネットワークカード)を直接制御してプログラムを書く必要はありません。C言語UNIXプログラミングであれば、ソケットを開いて、read()/write()すれば良いわけです。

これも、各々のデバイスが自分でハードウェアを制御しなくて良いよう、アプリケーションに対してOSが提供している機能ですね。

 

このように考えると、「OSはアプリケーションに対して機能を提供するソフトウェアだ」と言う事ができるでしょう。

 

では次に、OSはどのような機能を提供すれば良いのか考えてみましょう。

これまでの話の中で、幾つかOSが持つべき重要な機能が登場しましたが、これをもっと一般化して、「◯◯こそがOSの提供する機能だ」と言えると良いですよね。

 

Q. OSが提供している機能とは何か?マルチタスクを例にして考えてみよう。

 

最近のOSはマルチタスクをサポートしています。これもまたOSが提供する重要な機能です。

マルチタスクは、複数のプロセスを同時に動かせる仕組み、とでも言えば多くの方に納得して頂けるでしょうか。・・・残念ながらこの説明は正確ではないのですが。

 

折角なのできちんと説明しましょう。(既にご存知の方は読み飛ばしてください)

実は厳密に言うと、マルチタスクはプロセスを「同時に動かす」ための物ではありません。最近のCPUはマルチコア化が進み、複数のCPUコア上でプログラムを実行する事ができます。

皆さんのパソコンは何コア入っていますか?2コア?4コア?もしかしたら「16コアです!」なんていうお金持ちの方もいらっしゃるかもしれません。

しかし、プロセスはCPUのコア数以上に動いています。それら全てのプロセスを限られたコアの上で同時に動かす事は不可能です。

 

マルチタスクがやっている事とは、プロセスAを少し(10ミリ秒程度)実行して、プロセスBを実行して、またプロセスAを少し実行して・・・というものです。

これによって、人間の目から見れば「あたかも複数のプロセスが同時に実行されているように」見えるわけです。

 

さて、今度はこれをアプリケーションの視点から見てみたいと思います。

皆さんがプログラムを書く時、プロセスの切り替えを意識してプログラムを書いた事はないですよね。「このタイミングでプロセスが切り替わる事を想定して、切り替えコードを書いておこう」なんて事はしません。(ノンプリエンプティブマルチタスクの時代はそうだったわけですが、その話は今は割愛させてください)つまりアプリケーションは、CPU上でずっと稼働できるという前提で書かれるわけです。

 

でも既に皆さんはご存知の通り、アプリケーションはCPU上でずっと走れるわけではありません。裏でOSがこっそりアプリケーションを止め、他のアプリケーション(プロセス)に切り替えます。アプリケーションがそれに気づく事は殆どありません。アプリケーションにしてみれば、「あたかも自分が自由に使えるCPUが存在している」のです。もちろん実際には自由に使えるCPUなんてものは存在しません。それはOSによって作り出された、ある種の幻想です。OSはアプリケーションに対して仮想CPUを提供している、と言っても良いでしょう。

 

このようにしてOSが裏でこっそりプロセスを切り替える事には幾つかのメリットがあります。まず、アプリケーションがマルチタスク(プロセスの切り替え)を意識する必要がなく、プログラミングコストが下がります。次にもっと大切な事として、どのプロセスがどれだけの時間実行できるか(プロセスあたりのCPU使用時間)をOSが制御する事ができます。これによって、あるプロセスは重要なので沢山CPU時間を割り当ててあげる事もできるようになりますし、悪意のあるプロセスがCPUを占領してしまい他のプロセスが実行できない、という状況を回避する事もできるわけです。

 

 

さて、これをまとめると、「OSとは仲裁者である」つまり「仲裁こそがOSの提供する機能だ」と言う事は出来ないでしょうか?

「OSはCPUの実行時間を仲裁し、プロセスの実行を保証したり、ある特定のプロセスに意図的に実行時間を割り当てるできる存在である」と説明すると、今の話が綺麗に説明できそうですよね。

 

先程のファイルシステムの話も考えてみましょう。「ストレージとアプリケーションの間を仲介するファイルシステムを定義し、アプリケーションが簡単にストレージにアクセスできるようにする」と考え、OSの機能を「仲介」と考える事もできるでしょう。NICについても、OSが間に入って仲介する事により、アプリケーションがNICの事を良く分からなくても大丈夫なようにしています。

 

ここで頭の良い方はお気づきだと思いますが、仲介と仲裁は意味が異なります。とはいえ、複数のソフトウェアの間に入って良しなにしてあげたり、ハードウェアとソフトウェアの間に入って良しなにしてあげる、という意味では似ているように思えませんか?「仲介や仲裁こそがOSの提供する機能だ」と言えば、(少しすっきりしないかもしれませんが)なんとなくそんな気がしてきません?

 

 

 

 

良い感じに「OSとは何か」が描けてきた所で、オペレーティング・システムの定義を調べてみましょう。

Wikipediaを開いてみると(Wikipediaを参考文献に使うのはあまり良くないので、皆さんは書籍などで定義を調べてみてくださいね)、以下のように記述があります。

 

OSの主な目的は、ハードウェアの抽象化、リソースの管理、そしてコンピュータ利用効率の向上である

 

難しい用語が出てきました。でも大丈夫です。我々が今まで考えてきた事と大きく違う事は言っていません。


Q. ハードウェアの抽象化って何だろう?

Wikipediaにも説明があるので、それも同時に読んでもらいたいのですが、つまり「どんなNICであっても、ソケットとread()/write()というインターフェースでTCPパケットを送れるよ!」という事です。

OSがソフトウェアとハードウェアを仲介する時に、ソフトウェアとOSとの間でハードウェア処理に関する対話の共通窓口が必要で、この窓口こそが抽象化されたハードウェアインターフェース、という事になります。

抽象化とはなんぞや、というのをきちんと理解するのは難しいですが(これまた長くなりそうなので、今回は割愛)、これなら皆さんにもイメージがつきますよね?

 

Q. リソースの管理ってなんだろう?

マルチタスクの話で出てきましたが、あるプロセスがCPUを専有しようとしても、OSが良しなに仲裁して、他のプロセスの処理が中断されないように管理する、という話です。

 

Q. コンピュータの利用効率の向上ってなんだろう?

 もう一度マルチタスクの話を引用すると、あるプロセスは大事だからCPUを沢山使わせてあげられるように調停しよう、という事ですね。

 

どうですか?これまで考えてきた事とだいぶ近いと思いませんか?

 

 

 

 

ここまで結構長かったですが、皆さんどうでしたか?楽しんで頂けたでしょうか?

まあ、「長すぎて疲れちゃったよ」という感想を抱いている人が大半かもしれませんが。

でも、こうやって1つ1つ考えていく事で、「OSの本質が何か」という話のかなり近い所に皆さんと一緒にたどり着く事ができました。そして、これまでの流れが無ければ難しく感じるようなWikipediaの文面も、今にしてみれば「ああなんだ、それだけの事しか言ってないのか」という気持ちになりますよね?

皆さんも、難しい問いに直面した時は、こんな感じで考えてみるのは如何でしょうか?

もちろん皆さんが自分で考える時は、小さな問題を出すのも皆さん自身です。とはいえ、自分で自分に問題を出すのって難しそうですよね。

ご安心ください。キャンプ当日はこのようなお喋りを沢山する予定です。何回か練習すれば皆さんもきっとできるようになるはずですよ。

 

 

 

最後に、皆さんに説明しておかなければならない事があります。

実は、「OSの定義」は、大学のコンピュータサイエンス系学科で「オペレーティングシステム」の授業の最初に、およそ1分程で説明される事です。恐らくこれを読んでいる大学生の中には、「これ、授業で学んだよ!」と思った方もいらっしゃるでしょう。

もちろん、これを読んでいる方の多くは、恐らく中高生、あるいは大学の学部1,2年生だと思うので、この内容に始めて触れた方の方が多いと思います。でも、「OSの定義」は「知っていれば凄い事」「周りに自慢できる事」ではありません。むしろ「知っていて当たり前」と言われてもおかしくないような内容です。

知らない事は悪い事ではありません。人間最初は皆何も知らなかったわけですから。これから勉強していけば良いのです。

でも、「OSの定義」を始めて学んだ皆さんは、天狗になる事なく、これからも謙虚な気持ちで、様々な事を学び続けてください。皆さんが知らない事はこの世界にまだまだ沢山ありますよ。

一方で、「OSの定義」なんてもう習ったから知ってたよ、という皆さん。胸に手を当てて、「あなたが本当にそれを理解しているか」確認してみてください。少なくとも、今この場で、初学者に上手く説明できるでしょうか?(もしそうなら、是非参加者としてではなく、講師としてセキュリティ・キャンプに参加してください。私の代わりに笑)

 

あともう1つ。

最後に私の方から皆さんに宿題を出しておきましょう。

先程の禅問答では、ハイパーバイザ上でOSが動いているケースには敢えて触れずにいました。(ハイパーバイザという言葉が難しければ、VirtualBoxに読み替えてみてください)

ハイパーバイザも、I/Oデバイスを抽象化しています(仮想的なI/OデバイスをゲストOSに見せている)し、複数のVMがリソース(CPU時間やストレージ、メモリ等)を譲り合って使えるように管理しています。もちろん、コンピュータの利用効率を上げるためにハイパーバイザの改良も常に行われています。

 

 では、「ハイパーバイザとOSは『本質的に』 何が違うのでしょうか?」

この問いを面白いと思えたら、是非私のテーマに応募してみてください。