LoginSignup
49
42

More than 1 year has passed since last update.

独学Linux カーネルビルドをやってみよう

Last updated at Posted at 2021-04-22

はじめに

本記事はこれからLinuxカーネルをビルドするするための入門記事になります。

Linuxカーネルを学ぶことにより得られる恩恵は大きいものです。
Linuxカーネルをビルドすることで以下のようなことが実現できます。

  • 不要なモジュールを外すことでメモリの消費を抑えてシステムを最適化
  • デフォルトではカーネルに組み込まれていない機能や最新機能を有効化
  • カーネルがサポートしていないデバイスが利用可能
  • ソースコードを変更してカスタマイズも自由自在

LinuxカーネルのビルドはVirtualBoxなど仮想環境を使用することで、簡単に検証することができます。

本記事ではVirtualBoxを使用してカーネルのバージョンをアップ手順について記載しています。

環境

本記事の環境について以下に記載します。

前提としてVirtualBoxで仮想マシンを作成し、Ubuntuをインストールします。
仮想マシンの作成やUbuntuのインストールについては割愛します。

  • ホストOS:macOS Big Sur 11.2.3
  • 仮想環境:VirtualBox 6.1.18
  • ゲストOS:Ubuntu 20.04.2 LTS

留意事項
ホストの環境やビルド設定により、makeの時間に影響します。
また、仮想マシンのディスク容量が少なくて、取り込むモジュールが多い場合、容量不足によりビルドが止まってしまうことがあります。検証する場合は以下について考慮すると良いと思います。

  • ビルド実行時はホストOSをスリープしない設定にする
  • 仮想マシンのディスクはlvmなど拡張しやすい設計にする

もし、ビルド実行時にディスク容量が不足した場合、lvm環境であればディスクを拡張することでビルドの継続ができます。

  • lvextendコマンドで論理ボリュームを追加(例:20GB)
    # lvextend -L +20g /dev/ubuntu-vg/ubuntu-lv
Size of logical volume ubuntu-vg/ubuntu-lv changed from 28.00 GiB (7168 extents) to 48.00 GiB (12288 extents).
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.
  • ファイルシステムの再作成
    # resize2fs /dev/ubuntu-vg/ubuntu-lv
Filesystem at /dev/ubuntu-vg/ubuntu-lv is mounted on /; on-line resizing required
old_desc_blocks = 4, new_desc_blocks = 6
The filesystem on /dev/ubuntu-vg/ubuntu-lv is now 12582912 (4k) blocks long.

カーネルビルド手順

本記事ではカーネルのソースアーカイブから最新のソースを取得してビルドします。

コマンドの実行はrootユーザーで行っています。

カーネルビルド実行前のバージョンは以下になります。

  • バージョン確認
    # uname -r
5.4.0-72-generic

パッケージのインストール

はじめにカーネルビルドに必要なパッケージをインストールします。
LinuxカーネルのソースコードはC言語でほとんど書かれているため、Cコンパイラが必要です。

  • パッケージのインストール
    # apt-get update && apt install -y build-essential bc bison flex libelf-dev libssl-dev libncurses5-dev

build-essentialはカーネルビルドに必要なパッケージ一式がインストールされます。build-essentialをインストールすることでgccなどのコンパイラがインストールされます。

また、カーネルのビルドに必要なパッケージの要件については、ダウンロードしたソースアーカイブのDocumentation/process/changes.rstに記載があります。

カーネルのダウンロード

The Linux Kernel Archivesより、最新のLinuxカーネルをダウンロードします。

本記事時ではlongtermの5.4.109のソースを使用しています。

スクリーンショット 2021-04-10 22.55.52.png

longtermはUpstreamで取り込まれたバグフィックスや、コミュニティによるメンテナンスが行われています。カーネルリリースのカテゴリの説明については、Active kernel releasesを参照。

Linuxカーネルをダウンロード後、scpなどを使用して作成した仮想マシンに資材を転送します。
資材転送後、仮想マシンにログインを行い資材を展開します。

  • 資材の転送
    # scp linux-5.4.109.tar.xz ubuntu@<IPアドレス>:/tmp
  • 資材の展開
    # cd /usr/local/src/
    # mv /tmp/linux-5.4.109.tar.xz ./
    # tar xvf linux-5.4.109.tar.xz && cd linux-5.4.109/

tarballをダウンロードすると、拡張子はxzになっています。xz はLZMA/LZMA2圧縮アルゴリズムを利用していて、gzipなどと比べると圧縮率が高いです。

ビルド設定

カーネル機能の有効化や、モジュールの取り込みについては、makeコマンドでビルドの設定を行います。

ビルド設定には.configファイルが必要です。
本記事ではビルドを簡単に行うために、/boot配下のconfigファイルをコピーして作成します。

  • configファイルの作成
    # cp /boot/config-5.4.0-72-generic .config

  • config設定
    CONFIG_SYSTEM_TRUSTED_KEYSの値が入っているとエラーでmakeが失敗するため、値を削除します。

# vi .config

# 変更前
CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"

# 変更後
CONFIG_SYSTEM_TRUSTED_KEYS=""
  • 参考
    CONFIG_SYSTEM_TRUSTED_KEYSに値が入っている場合、エラーでmakeが止まり以下の様なメッセージが出力されます。
make[1]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'.  Stop.
make: *** [Makefile:1810: certs] Error 2

makeコマンドのビルド設定には他にもやり方があります。
例えば、make menuconfigというターゲットを実行すると、以下の様な様な画面が出力されます。

スクリーンショット 2021-04-18 19.15.43.png

このターゲットはカテゴライズされた設定項目毎に、メニュー形式でビルド設定を行うことができます。

make

makeコマンドはLinuxのソフトウェアなどをインストールするために必要なコマンドです。

makeコマンドを実行するとソースコードファイルをコンパイルし、オブジェクトファイルに変換します。コンパイルしたオブジェクトファイルとライブラリを、リンカでリンクすることで実行形式ファイルに変換します。

makeを使用する準備をするには、プログラム内のファイル間の関係と状態を記述したMakefileというファイルを作成する必要があります。ダウンロードしたLinuxカーネルのソースには、最初からMakefileが存在するため、新規の作成は不要です。

はじめにmakeを実行するためのコンパイル設定を行います。
本記事では簡単に設定を行うために、現在ロードしているモジュールをベースにするためにmake localmodconfigを指定します。make localmodconfigを指定すると、ロード済みのモジュールに不要なオプションは無効にします。よって、ロードされていないモジュールを取り込まない様にするため、カーネル自体が小さくなりコンパイル時間を短縮できます。

  • コンパイル設定
    # make localmodconfig

コマンドを実行すると、一部について対話的に入力が求められます。デフォルト設定の場合はEnterを押します。

 HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.[ch]
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTLD  scripts/kconfig/conf
using config: '.config'
module vboxguest did not have configs CONFIG_VBOXGUEST
*
* Restart config...
*
*
* PCI support
*
PCI support (PCI) [Y/n/?] y
  PCI Express Port Bus support (PCIEPORTBUS) [Y/n/?] y
    PCI Express Hotplug driver (HOTPLUG_PCI_PCIE) [Y/n/?] y
    PCI Express Advanced Error Reporting support (PCIEAER) [Y/n/?] y
      PCI Express error injection support (PCIEAER_INJECT) [N/m/y/?] n
      PCI Express ECRC settings control (PCIE_ECRC) [N/y/?] n
    PCI Express ASPM control (PCIEASPM) [Y/n/?] y
      Debug PCI Express ASPM (PCIEASPM_DEBUG) [N/y/?] (NEW) 
      Default ASPM policy
      > 1. BIOS default (PCIEASPM_DEFAULT)
        2. Powersave (PCIEASPM_POWERSAVE)
        3. Power Supersave (PCIEASPM_POWER_SUPERSAVE)
        4. Performance (PCIEASPM_PERFORMANCE)
      choice[1-4?]: 1
    PCI Express Downstream Port Containment support (PCIE_DPC) [Y/n/?] y
    PCI Express Precision Time Measurement support (PCIE_PTM) [Y/n/?] y
    PCI Express Bandwidth Change Notification (PCIE_BW) [N/y/?] n
  Message Signaled Interrupts (MSI and MSI-X) (PCI_MSI) [Y/?] y
  Enable PCI quirk workarounds (PCI_QUIRKS) [Y/n/?] y
  PCI Debugging (PCI_DEBUG) [N/y/?] n
  Enable PCI resource re-allocation detection (PCI_REALLOC_ENABLE_AUTO) [Y/n/?] y
  PCI Stub driver (PCI_STUB) [N/m/y/?] n
  PCI PF Stub driver (PCI_PF_STUB) [N/m/y/?] n
  Xen PCI Frontend (XEN_PCIDEV_FRONTEND) [N/m/y/?] n
  PCI IOV support (PCI_IOV) [Y/n/?] y
  PCI PRI support (PCI_PRI) [Y/?] y
  PCI PASID support (PCI_PASID) [Y/?] y
  PCI peer-to-peer transfer support (PCI_P2PDMA) [N/y/?] n
*
* PCI GPIO expanders
*
AMD 8111 GPIO driver (GPIO_AMD8111) [N/m/y/?] n
BT8XX GPIO abuser (GPIO_BT8XX) [N/m/y/?] (NEW) 
OKI SEMICONDUCTOR ML7213 IOH GPIO support (GPIO_ML_IOH) [N/m/y/?] n
ACCES PCI-IDIO-16 GPIO support (GPIO_PCI_IDIO_16) [N/m/y/?] n
ACCES PCIe-IDIO-24 GPIO support (GPIO_PCIE_IDIO_24) [N/m/y/?] n
RDC R-321x GPIO support (GPIO_RDC321X) [N/m/y/?] n
*
* PCI sound devices
*
PCI sound devices (SND_PCI) [Y/n/?] y
  Analog Devices AD1889 (SND_AD1889) [N/m/?] n
  Avance Logic ALS300/ALS300+ (SND_ALS300) [N/m/?] n
  Avance Logic ALS4000 (SND_ALS4000) [N/m/?] n
  ALi M5451 PCI Audio Controller (SND_ALI5451) [N/m/?] n
  AudioScience ASIxxxx (SND_ASIHPI) [N/m/?] n
  ATI IXP AC97 Controller (SND_ATIIXP) [N/m/?] n
  ATI IXP Modem (SND_ATIIXP_MODEM) [N/m/?] n
  Aureal Advantage (SND_AU8810) [N/m/?] n
  Aureal Vortex (SND_AU8820) [N/m/?] n
  Aureal Vortex 2 (SND_AU8830) [N/m/?] n
  Emagic Audiowerk 2 (SND_AW2) [N/m/?] n
  Aztech AZF3328 / PCI168 (SND_AZT3328) [N/m/?] n
  Bt87x Audio Capture (SND_BT87X) [N/m/?] n
  SB Audigy LS / Live 24bit (SND_CA0106) [N/m/?] n
  C-Media 8338, 8738, 8768, 8770 (SND_CMIPCI) [N/m/?] n
  C-Media 8786, 8787, 8788 (Oxygen) (SND_OXYGEN) [N/m/?] n
  Cirrus Logic (Sound Fusion) CS4281 (SND_CS4281) [N/m/?] n
  Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x (SND_CS46XX) [N/m/?] n
  Creative Sound Blaster X-Fi (SND_CTXFI) [N/m/?] n
  (Echoaudio) Darla20 (SND_DARLA20) [N/m/?] n
  (Echoaudio) Gina20 (SND_GINA20) [N/m/?] n
  (Echoaudio) Layla20 (SND_LAYLA20) [N/m/?] n
  (Echoaudio) Darla24 (SND_DARLA24) [N/m/?] n
  (Echoaudio) Gina24 (SND_GINA24) [N/m/?] n
  (Echoaudio) Layla24 (SND_LAYLA24) [N/m/?] n
  (Echoaudio) Mona (SND_MONA) [N/m/?] n
  (Echoaudio) Mia (SND_MIA) [N/m/?] n
  (Echoaudio) 3G cards (SND_ECHO3G) [N/m/?] n
  (Echoaudio) Indigo (SND_INDIGO) [N/m/?] n
  (Echoaudio) Indigo IO (SND_INDIGOIO) [N/m/?] n
  (Echoaudio) Indigo DJ (SND_INDIGODJ) [N/m/?] n
  (Echoaudio) Indigo IOx (SND_INDIGOIOX) [N/m/?] n
  (Echoaudio) Indigo DJx (SND_INDIGODJX) [N/m/?] n
  Emu10k1 (SB Live!, Audigy, E-mu APS) (SND_EMU10K1) [N/m/?] n
  Emu10k1X (Dell OEM Version) (SND_EMU10K1X) [N/m/?] n
  (Creative) Ensoniq AudioPCI 1370 (SND_ENS1370) [N/m/?] n
  (Creative) Ensoniq AudioPCI 1371/1373 (SND_ENS1371) [N/m/?] n
  ESS ES1938/1946/1969 (Solo-1) (SND_ES1938) [N/m/?] n
  ESS ES1968/1978 (Maestro-1/2/2E) (SND_ES1968) [N/m/?] n
  ForteMedia FM801 (SND_FM801) [N/m/?] n
  RME Hammerfall DSP Audio (SND_HDSP) [N/m/?] n
  RME Hammerfall DSP MADI/RayDAT/AIO (SND_HDSPM) [N/m/?] n
  ICEnsemble ICE1712 (Envy24) (SND_ICE1712) [N/m/?] n
  ICE/VT1724/1720 (Envy24HT/PT) (SND_ICE1724) [N/m/?] n
  Intel/SiS/nVidia/AMD/ALi AC97 Controller (SND_INTEL8X0) [M/n/?] m
  Intel/SiS/nVidia/AMD MC97 Modem (SND_INTEL8X0M) [N/m/?] n
  Korg 1212 IO (SND_KORG1212) [N/m/?] n
  Digigram Lola (SND_LOLA) [N/m/?] n
  Digigram LX6464ES (SND_LX6464ES) [N/m/?] n
  ESS Allegro/Maestro3 (SND_MAESTRO3) [N/m/?] n
  Digigram miXart (SND_MIXART) [N/m/?] n
  NeoMagic NM256AV/ZX (SND_NM256) [N/m/?] n
  Digigram PCXHR (SND_PCXHR) [N/m/?] n
  Conexant Riptide (SND_RIPTIDE) [N/m/?] n
  RME Digi32, 32/8, 32 PRO (SND_RME32) [N/m/?] n
  RME Digi96, 96/8, 96/8 PRO (SND_RME96) [N/m/?] n
  RME Digi9652 (Hammerfall) (SND_RME9652) [N/m/?] n
  Studio Evolution SE6X (SND_SE6X) [N/m/?] (NEW) 
  S3 SonicVibes (SND_SONICVIBES) [N/m/?] n
  Trident 4D-Wave DX/NX; SiS 7018 (SND_TRIDENT) [N/m/?] n
  VIA 82C686A/B, 8233/8235 AC97 Controller (SND_VIA82XX) [N/m/?] n
  VIA 82C686A/B, 8233 based Modems (SND_VIA82XX_MODEM) [N/m/?] n
  Asus Virtuoso 66/100/200 (Xonar) (SND_VIRTUOSO) [N/m/?] n
  Digigram VX222 (SND_VX222) [N/m/?] n
  Yamaha YMF724/740/744/754 (SND_YMFPCI) [N/m/?] n
#
# configuration written to .config
#

コンパイル設定が正常終了したら次にコンパイルを実行し、モジュールなどのインストールを行います。

  • コンパイル
    # make
    # make modules_install
    # make install

動作確認

OS再起動後、以下のコマンドを実行して、カーネルのバージョンが上がったことを確認します。

  • カーネルのバージョン確認
    # uname -r
5.4.109

無事にカーネルのバージョンが上がっていれば成功です。:penguin:

  • vmlinuzの確認
    # ls -l /boot/
total 170432
drwxr-xr-x  4 root root     4096 Apr 17 15:16 ./
drwxr-xr-x 20 root root     4096 Apr 17 13:59 ../
-rw-r--r--  1 root root   237851 Apr 12 15:12 config-5.4.0-72-generic
-rw-r--r--  1 root root   148982 Apr 17 15:16 config-5.4.109
drwxr-xr-x  4 root root     4096 Apr 17 15:16 grub/
lrwxrwxrwx  1 root root       27 Apr 17 13:59 initrd.img -> initrd.img-5.4.0-72-generic
-rw-r--r--  1 root root 82810789 Apr 17 14:00 initrd.img-5.4.0-72-generic
-rw-r--r--  1 root root 58762340 Apr 17 15:16 initrd.img-5.4.109
lrwxrwxrwx  1 root root       27 Apr 17 13:59 initrd.img.old -> initrd.img-5.4.0-72-generic
drwx------  2 root root    16384 Apr 17 13:57 lost+found/
-rw-------  1 root root  4750202 Apr 12 15:12 System.map-5.4.0-72-generic
-rw-r--r--  1 root root  4565739 Apr 17 15:16 System.map-5.4.109
lrwxrwxrwx  1 root root       15 Apr 17 15:16 vmlinuz -> vmlinuz-5.4.109
-rw-------  1 root root 11760384 Apr 12 16:56 vmlinuz-5.4.0-72-generic
-rw-r--r--  1 root root 11438976 Apr 17 15:16 vmlinuz-5.4.109
lrwxrwxrwx  1 root root       24 Apr 17 13:59 vmlinuz.old -> vmlinuz-5.4.0-72-generic

vmlinuzのシンボリックリンクのリンク先が、vmlinuz-5.4.109に変わったことも確認できます。

おわりに

Linuxはエンジニアとして市場価値を高めるために必要なスキルです。
現在のOSは最適化されていますが、カーネルの世界を覗いてみるのも面白いと思います。

参考

49
42
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49
42