Linux Kernelをビルドしてインストールするまで

# はじめに

Linuxを扱えることはITエンジニアの教養といっても過言ではありません。
Linux上でアプリケーションの開発や実行ができるエンジニアの方でもKernelまで踏み込んで学んだことがある人は少ないのではないでしょうか。
もちろんすべてのエンジニアがKernelを学ぶ必要があるとは思いません。しかし、近年では当たり前になっているDockerやKubernetesなどのコンテナ技術を深く学ぶにはKernelまで踏み込む必要があります。
私自身、インフラエンジニアではありませんが業務でコンテナ技術を扱うことが多いため、Kernelを学ぶ第一歩としてKernelをソースコードからビルドしてインストールしてみました。


以下は、Kernelをビルドした時の覚書になります。
ミニマムスタートで進めてますので、随時内容はアップデートしていきたいと思います。

# CentOSでKernelビルド

## 前提環境
ここでは[CentOS 7.9.2009](https://ftp.riken.jp/Linux/centos/7.9.2009/isos/x86_64/)を用いてLinuxのKernelをビルドをします。今回は`CentOS-7-x86_64-Minimal-2009.iso`イメージを使用しています。
また、CentOSは[VirtualBox](https://www.oracle.com/jp/virtualization/technologies/vm/downloads/virtualbox-downloads.html)で起動し、仮想マシン内からインターネット接続ができることを前提としています。

:::note warn
Windows環境の場合、Hyper-Vが有効になっているとVirtualBoxで正常に仮想マシンを動作できないことがあるようです。
OSをインストールできたとしてもKernelのコンパイル中にエラーとなることもあるため、Hyper-Vは無効化することをおすすめします。
:::

**CentOS7 isoイメージ**

https://ftp.riken.jp/Linux/centos/

なお、CentOSにはrootユーザとして`root`、一般ユーザとして`centos`を作成しており、一般ユーザでsudoが利用できるように`/etc/sudoers`に以下の行を追加しています。
今回はカーネルをビルドするだけの環境なのでセキュリティは気にしません。一般ユーザはrootユーザと同じコマンドが使えるようになります。

```:/etc/sudoersに追記
centos    ALL=(ALL)    ALL
```

## 事前準備

まずはyum updateを実行しておきます。

```bash
$ sudo yum update -y
```

sshでVMに接続できるようにする場合は、sshをインストールします。

```bash:sshのインストール
$ sudo yum -y install openssh-server
```

```bash:sshの確認(activeが表示されているとOK)
$ systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since 火 2022-09-27 20:30:40 JST; 11min ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 9161 (sshd)
   CGroup: /system.slice/sshd.service
           └─9161 /usr/sbin/sshd -D
```

SSHするためにIPアドレスを確認したいので、`ifconfig`コマンドをインストールします。

```bash:ifconfigコマンドのインストール
$ sudo yum install net-tools
```

なお、`net-tools`をインスト―スしなくても以下のコマンドでIPアドレスが確認できます。

```bash:IPアドレスの確認コマンド
$ ip addr show
```

## ビルドツールのインストール

Kernelをビルドするためのビルドツールをインストールします。
Kernelのバージョンによって、gccのバージョンXX以上のように決まっていますので必要なバージョンをインストールします。
今回はgcc11をインストールします。

```bash:ビルドツールのインストール
$ sudo yum groupinstall 'Development Tools'
$ sudo yum install centos-release-scl
$ sudo yum install scl-utils
$ sudo yum install devtoolset-11
```

なお、インストールしただけではgcc11は使えるようになりません。
以下のコマンドでgcc11を使えるようにします。

```bash:gcc11の有効化
$ scl enable devtoolset-11 bash
$ gcc -v #gccバージョン確認
```

その他、ビルドに必要なパッケージのインストール

```bash
$ sudo yum install openssl-devel
$ sudo yum install elfutils-libelf-devel
```

Kernelのソースコードは以下から入手できます
※Linux KernelはそれぞれのLinuxディストリビューションで提供されているものがありますので、利用できれば

- [https://github.com/torvalds/linux](https://github.com/torvalds/linux)
- [The Linux Kernel Archives](https://www.kernel.org/)
- [mirrors.edge.kernel.org](https://mirrors.edge.kernel.org/pub/linux/kernel/)

今回は`5.19.11`をビルドします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705474/53dc2ad9-cc3a-0f04-a1b2-cd00510261a8.png)

ソースコードを取得してダウンロードします。
ソースコードは`.tar.xz`で圧縮されてますので解凍します。

```bash:ソースコードのダウンロードと解凍
$ curl -OL https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.19.11.tar.xz
$ tar Jxf linux-5.19.11.tar.xz
```

Kernelのビルドではまずconfgiファイルを用意する必要があります。
ここでは現在起動しているKernelのconfigをコピーして使用することtにします。

```bash:configファイルのコピー
$ cd linux-5.19.11
$ cp /boot/config-$(uname -r) .config
```

```bash:config設定とKernelのビルド
$ make oldconfig
$ make
```

`make oldconfig`コマンドを実行すると設定の有効/無効を聞かれますので設定します。とりあえずビルドできれば良いのであれば全てデフォルトのままで問題ありません。
なお、カーネルのビルドには時間がかかります。私の環境だとビルド完了までに2時間半ほどかかりました。

## kernelインストール

kernelのビルドが完了したところで続いてはインストールを行います。
以下のコマンドによりkernelモジュールとkernelのインストールができます。

```bash:Kernelのインストール
$ sudo make modules_install
$ sudo make install
```

インストール完了後にOSを再起動します。
起動時の画面で先ほどインストールしたKernelが選択できるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705474/3ef52709-96f1-c0d1-9219-9c5d469a6c45.png)

# UbuntuでKernelビルド

追ってUbuntuでのKernelビルド手順も追加する予定です。

# 参考
- [Linuxカーネルのコンフィグレーション手順](https://atmarkit.itmedia.co.jp/ait/articles/0808/28/news129.html)
- [Linuxカーネルビルド大全](https://qiita.com/progrunner/items/d2ab0a85b3881a4b7ed8)
- [独学Linux　カーネルビルドをやってみよう](https://qiita.com/Brutus/items/3ca1237efdf1711a6428)
- [Linux関連のソースコードはどこにある？](https://kazuhira-r.hatenablog.com/entry/2019/07/27/203930)
- [CentOS 7でLinuxカーネルをコンパイルする方法](https://ja.linux-console.net/?p=236)
- [Compile Linux Kernel on CentOS7](https://linuxhint.com/compile-linux-kernel-centos7/)
- [Building Linux Kernel on CentOS 7](https://hackmd.io/@UNPDP47UTWOdXah-3yiSSQ/B1m35AiEO)
- [初心者向けKernelのビルド手順](https://mongonta.com/f258-howto-build-linux-kernel/)