Linux Kernel(Linux カーネル)を学びたいという話

## はじめに

パソコンを触ってきて、Linux Kernelという単語を知ったのはいつのことだったでしょう。

私のパソコン歴は、かなり一般的で特別なところは何もありませんでした。

自分用としての最初のパソコンは確かMacBook Air(Mid 2011)だったと思います。

それ以前は生まれた頃から家にあるパソコン(多分、XPだったと思う)を触らせてもらっていた程度でした。そして、私がLinuxという単語を知ったのは無料OSのUbuntuがきっかけだったと思います。

学校かどこかでWindows以外にも無料のOSというものがあり、その一つにUbuntuというものがあると聞いた時、私はそれをネットで調べたことがありました。

私は、今までパソコンを自作したこともなく(現在もないのですが)、当該分野の本を読んできたわけでもないので、Ubuntuについてもその頃、あまり良く分かりませんでした。しかし、調べてみてOSにも色々あるんだなあという認識で強化されました。そして、これらがきっかけで、LinuxとかKernelという単語(キーワード)があることを知りました。

自分の知識はあまりに稚拙で、不完全ですが、それだけに、OSやUbuntuよりも曖昧でよくわからないLinuxやLinux Kernelという単語は「なんかすごそう」とか「コンピュータに詳しそう」なイメージを持ちました。

そこで私はLinuxに興味を持ちますが、Linux Kernelについても、現在進行形で全くと言っていいほど無知であると言わざるを得ません。

それを学びたいと思っているものの、そもそもコンピュータのことをまるでわかっていないので、コンピュータのことをまるでわかっていない人間が、一体どうやってLinux Kernelについて学んでいけばいいのか、それすらも具体的な道筋が見えないままでいます。それが私の現在です。

そんなこともあり、ここでは、Linux Kernelを学んでみたいと考えている者として、今現在のコンピュータに対して自分が抱いている認識を記録、共有していけたらなあと考えています。

正直、私のコンピュータ関連に対しての知識はあまりに不完全、かつ曖昧だと思います。間違いも多く含んでいるでしょう。

よって、コメントにて指摘してもらったり、または、「私はこういう認識だよ」というのを書いてもらえると助かります。

長文になりそうですが、よろしくお願いします。

## Linux Kernelとの接点

私は、Arch Linuxを愛用しているため、そこら辺でLinux Kernelとは少しだけ接点というか、そのあたりの情報に触れることが稀にあります。

しかし、それらによってLinux Kernelの知識が完全になったかというと、全くもってそんなことはありませんでした。

今現在もわからないものは、わからないままという感じです。

では、どういった接点があったのかというと、具体的には、Custom Kernelをインストールしたりとか、または、Applicationを作成する際に、Kernelから出される値を取得する処理を書いたりだとか、Linux KernelをUpdateする際、Kernel Moduleを独自に読み込んだりだとか、そういったところでたまに Linux Kernel関連の情報に触れる機会がありました。

では、Linux Kernelとは一体何なのでしょうか。また、コンピュータって何なんでしょう?

## 私がぼんやりと認識しているコンピュータ像

### Kernelについて

Kernelについては、核のイメージで認識しています。Linux Kernelというのは、Linuxという名のソフトウェアの核を意味します。Kernelには、多分、そのデバイス分だけ核が存在し、Linux以外のものも当然にあると思います。

もちろん、これらは最初に書いたとおり間違った認識である可能性が十分にあります。しかし、以降はいちいち「これは間違った認識かもしれない」という注釈は書きません。そこは省略していきます。この記事では、間違った認識であろうと、正しい認識であろうと、あくまで現在の自分の認識を書いていきたいと考えています。

さて、話を戻しますが、では核と言うのは一体何なのかというと、これはハードウェアとソフトウェアの中心にあって、それらを繋ぎ合わせる役目を負うといった感じのものでしょうか。

これは、OSに近いイメージですが、OSというのも一部に、ハードウェア、つまりパソコンの各部品であり、パーツですね。それらのパーツをソフトウェア上で認識し、接続して機能するよう調整する役割を果たすものなんじゃないかなと考えています。

そして、このような広いOSの概念の中に包括されたKernelという核が存在します。それをKernelと言うんじゃないかなと、そんな感じで認識しています。

## CPUについて

CPUと言うのは、ハードウェアの一つとして存在するパソコンのパーツのことだと考えています。そして、CPUは特にコンピュータの処理能力に直接的な影響を及ぼす重要なパーツです。

パソコンにはパーツが色々あります。

これは人間の体をイメージしてもらえれば分かりやすいですが、CPUは脳のイメージです。

そして、脳というのは、人間の体のうちでもっとも重要なパーツの一つと考えられています。

なぜなら、様々なことを認識し、または処理するのはこの脳というパーツがあるからに他ならないからです。脳がなければ、人間は手足を動かすこともできなければ、頭で何かを考えたり、または実際に体を使って何かを表現したりすることができません。すべての命令は脳から送られてくるものであり、各パーツはその脳の命令を受け取って初めて、各々に動き出すのです。

ということで、人間の脳に例えられるCPUはとても重要なパーツの一つです。

では、CPUは一体何を行っているのでしょう。

これは、計算を行っているのだと思っています。計算というのは、演算と表現することもできますが、分かりやすく計算と表現します。

コンピュータの処理はすべてが計算によって処理、実行されます。

例えば、画像を表示するのも、ファイルを移動させるのも全て計算です。

ここで、画像ファイルが意味しているのは、本来的には、全て数字の羅列にすぎません。

しかし、ただの数字ではありません。ある規格に沿った数字の羅列です。

例えば、001122という数字の並び方を一つの意味として設定する場合、それは特定のアプリケーションを通して表示できる画像になりえます。

少し細かい話になりますが、画像ファイルは四角く区切ったマス目に広がる一つ一つの色によって出来上がっています。それを縮小すると、特定の絵になるというわけですね。しかし、個別に見ていくと、「黒」「白」「青」「青」「赤」などの色の付いた四角い箱の配列なのです。それらをたくさん並べて絵にしているイメージです。

そして、このような絵を表示するにしても、コンピュータ上の処理である限り、そこには計算が必要になります。どの色がついた箱がどれだけ必要なのかとか、まあ色々でしょう。

私がCPU、その他の要素に抱いている認識としては、こんな感じです。

## コンパイラについて

次に、コンパイラの話をしていきたいと思います。

ここで、コンパイラについても私の認識はかなり曖昧であり、適当です。

人間がコンピュータに命令を伝える際、通常は人間が書きやすく、そして読みやすいプログラミング言語と言うものを利用します。

このプログラミング言語は様々なものが存在するものの、その役割は共通しています。

具体的には、「人間がコンピュータに命令を伝える際、通常は人間が書きやすく、そして読みやすいものにすること」です。

さて、このプログラミング言語は一体、どのようにしてコンピュータに命令を伝えるのかというと、それは変換することによって、コンピュータに命令を伝えます。

この変換をするツールのことをコンパイラ、変換処理自体をコンパイルと表現するのだと思っています。

## Shellについて

次はApplicationの一つであるシェル(Shell)についての認識です。

私がShellについて抱いている認識は、アプリの一つであること、及び単なるアプリと一線を画して重要なアプリの一つであるということです。

では、重要なアプリというのは、一体何を持って重要だと判断するのでしょうか。

ここでは、特に、Kernelのようなコンピュータの中核を担うソフトウェア(?のようなもの)とやり取りする上で、それを重要だと判断し、そのように表現しています。

通常のApplicationは、このようなハード関連に近いKernelのようなものと直接やり取りする権限を与えられていません。なぜなら、そのような権限を通常のアプリに与えることは、混乱を招き、そして、危険なことだからです。もちろん、例外はありますし、基本的にはという意味ですが。

よって、特別な権限を与えられ、かつ包括的にアプリを管理するため多くの人はShellという類のアプリを用います。

このShellは、言語としても動作し(ここで言う言語とは単なるスクリプト言語のはなしであり、かつShell Scriptの本質は単なるコマンドの羅列に過ぎない)、また、様々なアプリを実行、管理するためにも動作します。

このように動作する理由としては、大抵のOSにそういった処理に必要なだけの権限と、そして動作環境を与えられていることが多いからです。

Shellは通常、そのPATH(ここでは主にディレクトリ配置のこと)を通してアプリを管理します。ここで言う管理とは主に実行権限や動作環境の付与を意味します。そして、大抵の場合、パッケージマネージャーというソフトウェア(アプリをインストールするためのアプリ)は、このPATHにインストールしたバイナリなどを置くことによって、動作環境を維持、保証します。

また、Shellを通して基本的な処理を実行するために各コマンドと言う名の一般的かつ普遍的な各アプリが用意されています。例えば、現在ユーザーが滞在しているディレクトリを表示する`pwd`やディレクトリ内のファイルを表示する`ls`など。ただし、ここでのアプリは通常のアプリとは多少イメージが異なり、一つのことをシンプルにうまくやる非常に簡素なアプリ(コマンド)を指します。

これらのツール群は一つのパッケージとして提供されていることが多く、具体的には、`busybox`などが有名です。

## Linuxについて

Linuxというのは大抵がLinux Kernelの意味で用いられることが多いですが、OSとしての意味も一般的に存在します。

なぜなら、両者に違いはあれど、広い意味でそれらの違いは比較的小さなものだからです。主に一般認識的な意味で。

ここで、Linuxディストリビューションという単語があります。

これは、Linux Kernelを利用して作成された各種OSのことを言います。

では、なぜこれらの各Linuxディストリビューションは、Linux Kernelを利用するのでしょう。

その理由の一つはLinux Kernelの利用が無料であり、かつ改変が可能であるからだと思います。

さらに特に、Linux Kernelのような役割を担う分野は、非常に地味な、しかし根本的に重要な役割を担っているだけに、独自に作成するにしても、あまり面白くないことなのでしょう。ほとんどの技術者にとって、そこは既存のものに任せて、できれば他のことをやりたいと思う人が多いのだと思います。多くの技術者は、より新しく、そして、より革新的なことをやりたがる人が多く、そして、それは間違ったことではありません。

もちろん、Linux Kernelが新しく、革新的ではないとまでは言いませんが、しかし、Linux Kernelは、ハードとソフトを適切につなぎ合わせ動作させることを目的にしている以上、そういった役割を担っているだけに、それは非常に地味というか、一般的に人々の目に触れる分野ではありません。

それは、一番下の方にあり、そして、人々が意識せず、認識もしない形で、しかし、コンピュータの動作処理において根本的であり、非常に重要な、例えば、人間で言うところの空気や酸素のような役割を担っていると私は考えています。

そして、普段、空気が大切なことを意識している人は多くはない。しかし、無くては困るものなのです。

通常、人々から脚光を浴び、注目を浴びるものというのは、上の方にあるものです。

ここで、ハードは下のほうであり、ソフトは上のイメージです。また、ソフトの中でもOSよりも更に上にあるもののほうが、多くの人の目に触れるという理由からも、一般的に人々が認識しやすく、かつ意識されやすい領域の話だと思います。

つまり、Linux Kernelよりも各種Linuxディストリビューション、OSのほうがより一般的であるといえるでしょう。また、OSよりもその上で動作する各種ソフトウェアのほうが、より多くの人がイメージしやすいし、それが普段人が触れている部分にあたります。ここで言う、より広く共通する概念というのは、通常、根本的であり、重要でありながらも、空気のように動作する自然さというものが求められている気がします。

よって、Linux Kernelを学びたいという人は、普段、あまり意識もされず、認識されることも少ないけれど、しかし、根本的であり中核的な役割を担う部分に対する興味があるのかもしれません。そんなふうに感じます。

より深くコンピュータのことを理解しようとする場合、Linux Kernelを学ぶことは重要であり、効率的なのではないかなと現時点ではそう考えます。

## ファイルについて

話は変わって少し上の方に話になりますが、次はファイルについての認識について書いていこうかなと思います。

ここで、ファイルというのは一体何なのでしょう。

ファイルとは直接関係がない前提の話ですが、ファイルを含めて全ては単なるデータであり数字です。人がある特定の意味に置き換えるからそれは意味を持つのであって、本来的にはやはり意味のない単なる数字であり、データです。

しかし、ファイルへの認識はそれに似たところがあって、私はOS上で扱われるものは全てファイルだという認識を持っています。もちろん、ディレクトリもファイルの一つです。

以上を前提にすると、ファイルとは単位のことだと思います。OSが共通して認識できる形の一つの単位をファイルというのだと私は思います。

ファイルには基本的に、書き込み、読み込み、実行があります。が、ここでは実行は省略してもいいかもしれません。よって、単純に読み書きの2つがあります。

通常、ファイルを削除するという命令を実行しても、ファイルは削除されず、単にファイルが削除されたという記録が残ります。そして、これらの痕跡を蓄積し、記憶するのがHDDと呼ばれるパーツになり、HDDはファイルの読み書きを記録します。

HDDは計算された数字としてのファイルを書き込み、そして、書き込み続けます。それらをOSの処理によって一部再現、解釈し、読み込むという事が可能になるのだと思います。このような単位がファイルというものなんじゃないかなと思っています。

ここでブロックという言葉を思い浮かべましたが、省略することにします。(これについても全くよくわかってない)。

## Linux Kernelを学ぶにはどうすればいいのか

このように曖昧で不完全な現在の知識レベルで、一体どうすれば効率的にLinux Kernelを学べるか、それを考えてみたいと思います。

まず私が思いついたのは以下の様なことでした。

- Custom Kernelの変更点やコンセプトをソースコードなどから追ってみる

- Linux Kernel(本家)の最新機能を見てみる

- Linux Kernelの本を頑張って読んで見る(現時点では読んでも多分、意味不明であり、理解不能だと思われる)

- Linux Kernelに詳しい人をフォローしてみる

こんな感じのことが思い浮かびます。なかなか道は険しそうです...。

## さいごに

なんとなく私のコンピュータに関する認識を思いつく限りで書いてきましたが、私は、コンピュータのことをまるでわかっていない初心者で、かつ、その認識の稚拙さ、曖昧さはご覧の通りです。

色々と調べてみたり、本を読んでみたりしてみたいのですが、Linux Kernelについてもずっとそれをやらないできました。

今回は、このような自分の適当で曖昧な間違っているであろう認識を公開することによって、失敗談として、多くの人に安心と、そして、Kernelを学ぶ意欲が刺激されれば幸いに思います。(自分にとっても)

ここまで読んでくれて、ありがとうございました。