はじめに
本記事はこれから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のソースを使用しています。
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
というターゲットを実行すると、以下の様な様な画面が出力されます。
このターゲットはカテゴライズされた設定項目毎に、メニュー形式でビルド設定を行うことができます。
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
無事にカーネルのバージョンが上がっていれば成功です。
- 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は最適化されていますが、カーネルの世界を覗いてみるのも面白いと思います。