【初心者向け】Linuxカーネルって一体なんだ？

# **Linuxカーネルについて**

　Linuxカーネルについて勉強する機会があったので、自分のためにまとめのメモ。今後追記していきます。
補足、修正等あればお待ちしております。

## **そもそもLinuxってなんだっけ？**

　Linuxは、リーナス・トーバルズが開発した**UNIXライクな「OS」**のことです。大きな特徴はオープンソースであることで、無料で利用することができるのでサーバーとして用いられる機会が多いです。

「Linux」は、厳密には二つの意味で分けられます。
・広義のLinux：**Linuxディストリビューション**のこと。
・狭義のLinux：**Linuxカーネル**のこと。

　基本的にLinuxと呼ばれた時は広義の意味である「Linuxディストリビューション」のことを指していますが、
今回の記事では狭義のLinuxであるLinuxカーネルについて説明します。


Linuxについての細かいメモは、詳しくは下記参照。

【初心者向け】Linuxについての簡単なまとめメモ
https://qiita.com/uguis410/items/f9e82350d5d49a300491

## **Linuxカーネルについて**

　ズバリ、ハードウェアとソフトウェアの仲立ちをしてくれる、**OSの根幹**となるものです。
↓図にするとこんな感じです。カーネルはOSの中に位置しています。

![スクリーンショット 2018-06-17 12.25.19.png](https://qiita-image-store.s3.amazonaws.com/0/258471/07e1888d-b8cd-b8db-6fb8-c01b19ab81d2.png)

　それでは、そもそものOSってのは一体何者でしょうか？

> ### **OS（Operating System）**
オペレーティングシステム（英語: Operating System、OS、オーエス）とは、コンピュータのオペレーション（操作・運用・運転）のために、ソフトウェアの中でも基本的、中核的位置づけのシステムソフトウェアである。
https://ja.wikipedia.org/wiki/オペレーティングシステム

要するに、**ハードウェアとソフトウェアの仲立ちをしてくれるもの**がOSです。
LinuxカーネルはそんなOSの基幹部分の機能である、

**「アプリケーションが動作するための基本環境」**

を提供しています。

具体的には例えば、
　・メモリのどの場所にデータを保存すればいいか
　・CPUのリソースをどの程度それぞれのアプリケーションに割り振ればいいか
　・ハードウェアからの処理の依頼をどんな順番で行うか

など、普段コンピュータを操作する時に意識しない、後ろ側で動いているたくさんの基本的な機能をLinuxカーネルは提供してくれています。


また、大きく分けて役割は、

　**・アプリケーションからの要求に応えること。**
　**・ハードウェアからの応答をアプリケーションに伝えること。**

の2つに大別することができます。

そしてカーネルはアプリケーションからの要求に対して、
**システムコール**を介することで処理しています。


## **システムコール**

**「非特権モードで動作しているプログラム」が「特権モードで動作しているカーネル」に処理を依頼すること**です。

![スクリーンショット 2018-06-17 15.47.53.png](https://qiita-image-store.s3.amazonaws.com/0/258471/94664461-dcbc-4849-728d-c63f872a1b8c.png)

　カーネルはどのようなアプリケーションを動作させるためにも必要となる、共通の処理を担っているため、その性質上PC上の全てのリソースにアクセスできる特別な存在です。ただ、もし仮に他のそれぞれのプログラムが、カーネルと同じように好き勝手にPC上の全てのリソースをいじることができたら、一体どうなるでしょうか？

　プログラムごとにメモリの値を書き換えてしまい、予期しない動作をするかもしれません。まして、PCが動くための基本的な情報や、カーネルを動かしているプログラムも、PC上のリソースのどこかに存在しているわけです。もしそれらの部分までいじられて影響を及ぼしてしまったら、重大なエラーが発生するだけでなく、最悪PCが停止する可能性があり、非常にリスキーです。

　そこでLinuxカーネルではプログラムの実行環境を、

　・全てのリソースを扱うことができる、**「カーネルモード」**
　・一部のリソースしか扱うことができない、**「ユーザーモード」**

の二つの世界に分けています。
ユーザーモードでは原則、他のプログラムに対して影響を与えるような動作をすることができません。したがって、他のプログラムに対して影響を与える心配がないので、安心してプログラムを動かすことができます。


　他のプログラムに対して影響を与えるような操作を、普通のプログラムが行いたい場合は、システムコールを発行することで、カーネルに対して処理を依頼します。

カーネルに対しての窓口をシステムコールに絞ることで、プロセスに対する管理能力と安全性を高めています。
・全ての処理をカーネルが統括することができるので、プログラム同士で処理のバッティングが起こらない。
・不用意にプログラムが他のプログラムの内容を書き換えない。
などです。

## **カーネルの基本性能**
Linuxカーネルが提供する代表的な機能を一部紹介します。


####**プロセス管理**
　Linuxカーネルでは、**プログラムの実行状態をプロセスという単位で管理**しています。また、カーネルはプロセス一つ一つに対して、**task_struct構造体**というデータ構造を準備しています。
　task_struct構造体には、そのプロセスが動作するための様々な情報（PIDやプロセスが動作しているメモリアドレス 等）が記憶されており、Linuxカーネルがプロセスを操作する際は、このtask_struct構造体に対して操作を行います。

【初心者向け】プロセスについて【Linux】
https://qiita.com/uguis410/items/b568b28786516a105f34

####**プロセススケジューラ**
　実行可能状態で待機しているプロセスを、**どの順番で実行させるのが最適かを判断するものです**。基本的にCPU数以上の数のプロセスを動かすことはできないため、いかに効率よくプロセスを稼働させていくかが重要です。
　プロセススケジューラは、プロセススケジューリング方針に従って**実行優先度**と**タイムスライス**を割り振り、スケジュールに従ってプロセスを実行していきます。また、実際にプロセスの切り替えを行う機能を**プロセスディスパッチ**と呼びます。

####**メモリ管理**
　Linuxカーネルでは、**物理メモリ**と**仮想メモリ**を用いてデータを管理しています。プロセス一つ一つに対して、実際に物理メモリのアドレスをそのまま割り当てるのではなく、物理メモリに対応した仮想アドレスを割り当てることで、実際の物理メモリの容量よりもはるかに大きな容量のメモリを利用可能にしています。また、各プロセスに対して固有の仮想アドレスを割り振っているため、それぞれのプロセスのメモリ空間は独立し、他のプロセスのメモリを犯さないようになっています。

####**ファイルシステム**
　**保存されているデータに対してのアクセス手段をファイルという形で提供しているものです**。全てのデータをファイルと言う形で管理しています。/ディレクトリ（ルートディレクトリ）を頂点としたツリー状の構造をしており、カーネル自体もファイル、ディレクトリの集合体として存在しています。

等。 (他にもたくさんあります)
図で表すとこんな感じみたいです。

![スクリーンショット 2018-06-17 16.51.42.png](https://qiita-image-store.s3.amazonaws.com/0/258471/e25f3048-145f-b2d4-65df-bb8e906e03dc.png)



## **引用**
【Linux Kernerl Documets】
https://ja.osdn.net/projects/linux-kernel-docs/

【物理アドレス空間と仮想アドレス空間の違いとその基礎知識】
http://128bit.blog41.fc2.com/blog-entry-32.html

【Linuxのプロセスって何だろう？】
http://www.atmarkit.co.jp/ait/articles/1706/23/news010.html