2.1 カーネルの構成要素
2.1.1 カーネルバージョン
確認方法
unameコマンドで確認できる
-r
, --kernel-release
uname -r
3.10.0-1127.19.1.el7.x86_64
-v
, --kernel-version
ではない
uname -v
#1 SMP Tue Aug 25 17:23:54 UTC 2020
/proc/version
でも確認できる
cat /proc/version
Linux version 3.10.0-1127.19.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ) #1 SMP Tue Aug 25 17:23:54 UTC 2020
uname -a
と比較
uname -a
Linux lpic2-study-1 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
/proc/version | uname -a (-m) | |
---|---|---|
ビルド情報 | o | x |
ハードウェアアーキテクチャ情報 | x | o |
自分でビルドした場合はカーネルソースのMakefileからも読み取れる (後述)
読み方
昔
3桁
2.x.y
- xが偶数: 安定版
- xが奇数: 開発版
2.6以降 2.6.39まで
4桁になった
2.6.x
2.6.x.y
2.6.x-rcN
偶数奇数による安定/開発の区別は無くなった
- y: xへの修正リリース番号
-
-rcN: release candidate N
- これが開発版
3系以降
ふたたび3桁に
3.x
3.x.y
3.x-rcN
- y: xへの修正リリース番号
-
-rcN: release candidate N
- これが開発版
uname -r
3.10.0-1127.19.1.el7.x86_64
今回は3.10.0
なので
- メジャーバージョン3
- マイナーバージョン10
- 修正リリース0
2.1.2 カーネルイメージ
ls /boot/vmlinuz*
/boot/vmlinuz-0-rescue-cd7c85585b483d2656ce72740e5b59f7
/boot/vmlinuz-3.10.0-1127.19.1.el7.x86_64
/boot/vmlinuz-3.10.0-1127.el7.x86_64
zImage/bzImage
- カーネルビルド時にmake zImageかmake bzImageかを選択できる
- 自己解凍機能つきの圧縮機構
- zImageにはメモリ制限があるので巨大なカーネルはbzImageを使う
2.2 カーネルモジュール
2.2.1 カーネルモジュール
-
一部機能をモジュールしてカーネル本体から切り離す
- デバイスドライバ等
- 起動時間短縮、メモリ節約
- ホットプラグ対応(USBなど)
ls -F /lib/modules/
3.10.0-1127.19.1.el7.x86_64/ 3.10.0-1127.el7.x86_64/
lsmod
現在ロードされているすべてのモジュールを一覧表示する
lsmod
Module Size Used by
ip6t_rpfilter 12595 1
ip6t_REJECT 12625 2
nf_reject_ipv6 13717 1 ip6t_REJECT
ipt_REJECT 12541 2
nf_reject_ipv4 13373 1 ipt_REJECT
xt_conntrack 12760 8
...
DESCRIPTION
lsmod is a trivial program which nicely formats the contents of the
/proc/modules, showing what kernel modules are currently loaded.
/proc/modules のラッパ
cat /proc/modules
ip6t_rpfilter 12595 1 - Live 0xffffffffc04a5000
ip6t_REJECT 12625 2 - Live 0xffffffffc04a0000
nf_reject_ipv6 13717 1 ip6t_REJECT, Live 0xffffffffc049b000
ipt_REJECT 12541 2 - Live 0xffffffffc0496000
nf_reject_ipv4 13373 1 ipt_REJECT, Live 0xffffffffc0491000
xt_conntrack 12760 8 - Live 0xffffffffc0485000
modinfo
モジュールの情報表示
オプション省略で全情報出力
modinfo ip6t_rpfilter
filename: /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/net/ipv6/netfilter/ip6t_rpfilter.ko.xz
description: Xtables: IPv6 reverse path filter match
author: Florian Westphal <fw@strlen.de>
license: GPL
retpoline: Y
rhelversion: 7.8
srcversion: 14236A8ADBEB9E1BA72CD4D
depends:
intree: Y
vermagic: 3.10.0-1127.19.1.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: B1:6A:91:CA:C9:D6:51:46:4A:CB:7A:D9:B8:DE:D5:57:CF:1A:CA:27
sig_hashalgo: sha256
-a: author
modinfo -a ip6t_rpfilter
Florian Westphal <fw@strlen.de>
-d: description
modinfo -d ip6t_rpfilter
Xtables: IPv6 reverse path filter match
-l: license
modinfo -l ip6t_rpfilter
GPL
-n: name
modinfo -n ip6t_rpfilter
/lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/net/ipv6/netfilter/ip6t_rpfilter.ko.xz
rmmod/insmod
疲れていないカーネルモジュールとして乱数生成器を見繕ってみる
lsmod | grep rng
virtio_rng 13029 0
...
modinfo virtio_rng
filename: /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/drivers/char/hw_random/virtio-rng.ko.xz
license: GPL
description: Virtio random number driver
retpoline: Y
rhelversion: 7.8
srcversion: 1D236D98CE131093B1EB6FF
alias: virtio:d00000004v*
depends: virtio,virtio_ring
intree: Y
vermagic: 3.10.0-1127.19.1.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: B1:6A:91:CA:C9:D6:51:46:4A:CB:7A:D9:B8:DE:D5:57:CF:1A:CA:27
sig_hashalgo: sha256
rmmod
ロードされているモジュールをアンロード
- remove a module から
- 使用中、依存関係にあるものは不可能
$ rmmod virtio_rng
rmmod: ERROR: could not remove 'virtio_rng': Operation not permitted
rmmod: ERROR: could not remove module virtio_rng: Operation not permitted
# rmmod virtio_rng
(とくに出力なし)
insmod
insert a moduleから
cat /proc/modules | grep rng
(出力なし)
insmodではモジュール名ではなくモジュールファイル名を指定する
insmod -v /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/drivers/char/hw_random/virtio-rng.ko.xz
書籍で紹介されていた -v (verbose)は無かった。ディストリ依存?
insmod: invalid option -- 'v'
管理者権限必要
$ insmod /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/drivers/char/hw_random/virtio-rng.ko.xz
insmod: ERROR: could not insert module /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/drivers/char/hw_random/virtio-rng.ko.xz: Operation not permitted
# insmod /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/drivers/char/hw_random/virtio-rng.ko.xz
(出力なし)
インストール確認
cat /proc/modules | grep rng
virtio_rng 13029 0 - Live 0xffffffffc04aa000
virtio_ring 22952 5 virtio_rng,virtio_net,virtio_balloon,virtio_scsi,virtio_pci, Live 0xffffffffc016a000
virtio 14959 5 virtio_rng,virtio_net,virtio_balloon,virtio_scsi,virtio_pci, Live 0xffffffffc0162000
modprobe
NAME
modprobe - Add and remove modules from the Linux Kernel
rmmod/insmodの賢いやつ
-
依存関係を考慮して、必要なものも自動的にロードしてくれる
- cf. insmodは依存関係を自分で管理する
- 依存関係表示
modprobe --show-depends virtio_rng
insmod /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/drivers/virtio/virtio.ko.xz
insmod /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/drivers/virtio/virtio_ring.ko.xz
insmod /lib/modules/3.10.0-1127.19.1.el7.x86_64/kernel/drivers/char/hw_random/virtio-rng.ko.xz
used by側から順に書かれている
modprobeではremove/installともにカーネルモジュール名を指定する
modprobe -r virtio_rng
modprobe: ERROR: could not remove 'virtio_rng': Operation not permitted
# modprobe -r virtio_rng
(出力なし)
$ modprobe virtio_rng
modprobe: ERROR: could not insert 'virtio_rng': Operation not permitted
# modprobe virtio_rng
(出力なし)
-n
, --dry-run
, --show
: 実際には何もしない
module.depファイル
モジュールの依存関係は /lib/modules/$(uname -r)/modules.dep
に記述されている
cat /lib/modules/$(uname -r)/modules.dep | grep rng
kernel/crypto/ansi_cprng.ko.xz:
kernel/crypto/jitterentropy_rng.ko.xz:
kernel/crypto/algif_rng.ko.xz:
kernel/drivers/char/hw_random/timeriomem-rng.ko.xz:
kernel/drivers/char/hw_random/intel-rng.ko.xz:
kernel/drivers/char/hw_random/amd-rng.ko.xz:
kernel/drivers/char/hw_random/via-rng.ko.xz:
kernel/drivers/char/hw_random/virtio-rng.ko.xz: kernel/drivers/virtio/virtio_ring.ko.xz kernel/drivers/virtio/virtio.ko.xz
抜粋
kernel/drivers/char/hw_random/virtio-rng.ko.xz: kernel/drivers/virtio/virtio_ring.ko.xz kernel/drivers/virtio/virtio.ko.xz
kernel/drivers/char/hw_random/virtio-rng.ko.xz
depends on .../virtio_ring.ko.xz
and .../virtio.ko.xz
の意
modules.depファイルはdepmodコマンドで生成
depmod - Generate modules.dep and map files.
/etc/modprobe.conf, /etc/modprobe.d/
モジュールロード時のパラメータ指定等の設定ファイル
ls /etc/modprobe.d/
blacklist-floppy.conf firewalld-sysctls.conf tuned.conf
dccp-blacklist.conf gce-blacklist.conf
cat /etc/modprobe.d/gce-blacklist.conf
# nouveau does not work with GCE GPU's.
blacklist nouveau
# GCE does not have a floppy device.
blacklist floppy
手元のPCのやつ
cat /etc/modprobe.d/mdadm.conf
# mdadm module configuration file
# set start_ro=1 to make newly assembled arrays read-only initially,
# to prevent metadata writes. This is needed in order to allow
# resume-from-disk to work - new boot should not perform writes
# because it will be done behind the back of the system being
# resumed. See http://bugs.debian.org/415441 for details.
options md_mod start_ro=1
cat /etc/modprobe.d/iwlwifi.conf
# /etc/modprobe.d/iwlwifi.conf
# iwlwifi will dyamically load either iwldvm or iwlmvm depending on the
# microcode file installed on the system. When removing iwlwifi, first
# remove the iwl?vm module and then iwlwifi.
remove iwlwifi \
(/sbin/lsmod | grep -o -e ^iwlmvm -e ^iwldvm -e ^iwlwifi | xargs /sbin/rmmod) \
&& /sbin/modprobe -r mac80211
書式
-
alias
- モジュールのエイリアス名定義
-
options
- モジュールのオプション指定
-
install/remove
- modprobe/modprobe -r 実効時にシェルコマンド実行
2.3 カーネルのコンパイル
こんなときにカーネルの再構築を行う
- 必要なデバイスドライバが入ってない
- H/W最適化したい
- カーネルバージョンアップしたい
2.3.1 カーネルのコンパイルとインストール
カーネルソースの準備
-
/usr/src/
,/usr/src/kernels/
(RHEL, CentOS)等に格納するよう想定されている- LPIC的には
/usr/src/linux/
symlinkが置かれていることを想定している
- LPIC的には
- 今回はホームディレクトリ以下で作業することにする
mkdir ~/kernels
cd ~/kernels
kernel.orgからtarballを拾ってきて展開
curl https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.9.12.tar.xz -o linux-5.9.12.tar.xz
tar xvJf linux-5.9.12.tar.xz
カーネルのバージョンは uname -r
, /proc/version
のほか、Makefileからも読み取れる
head -n 5 Makefile
# SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 9
SUBLEVEL = 12
EXTRAVERSION =
カーネルコンフィギュレーションの反映
ソースコードの .config
ファイルで記述
- ゼロから設定するのは大変 & 古いバージョンの設定ファイルは新しいカーネルでそのままは使えない
- 移行のために
make oldconfig
が用意されている
cd linux-5.9.12
ls
COPYING Kbuild MAINTAINERS arch crypto include kernel net security usr
CREDITS Kconfig Makefile block drivers init lib samples sound virt
Documentation LICENSES README certs fs ipc mm scripts tools
現在のカーネルのオプションを引き継ぐ場合、/boot/のコンフィグをコピーしてmake oldconfig
する
cp /boot/config-$(uname -r) .config
make oldconfig
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
/bin/sh: flex: command not found
make[2]: *** [scripts/kconfig/lexer.lex.c] Error 127
make[1]: *** [oldconfig] Error 2
make: *** [__sub-make] Error 2
flex, bisonが無いと言われるのでインストールして再度
sudo yum install -y flex bison
make oldconfig
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
HOSTCC scripts/kconfig/util.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf --oldconfig Kconfig
.config:697:warning: symbol value 'm' invalid for CPU_FREQ_STAT
.config:941:warning: symbol value 'm' invalid for NF_CT_PROTO_GRE
.config:969:warning: symbol value 'm' invalid for NF_NAT_REDIRECT
.config:972:warning: symbol value 'm' invalid for NF_TABLES_INET
.config:1139:warning: symbol value 'm' invalid for NF_TABLES_IPV4
.config:1143:warning: symbol value 'm' invalid for NF_TABLES_ARP
.config:1184:warning: symbol value 'm' invalid for NF_TABLES_IPV6
.config:1559:warning: symbol value 'm' invalid for NET_DEVLINK
.config:2719:warning: symbol value 'm' invalid for ISDN_CAPI
.config:3664:warning: symbol value 'm' invalid for LIRC
*
* Restart config...
*
*
* General setup
*
*
* General setup
*
Compile also drivers which will not load (COMPILE_TEST) [N/y/?] (NEW) y
Local version - append to kernel release (LOCALVERSION) []
Build ID Salt (BUILD_SALT) [] (NEW)
Kernel compression mode
> 1. Gzip (KERNEL_GZIP)
2. Bzip2 (KERNEL_BZIP2)
3. LZMA (KERNEL_LZMA)
4. XZ (KERNEL_XZ)
5. LZO (KERNEL_LZO)
6. LZ4 (KERNEL_LZ4) (NEW)
7. ZSTD (KERNEL_ZSTD) (NEW)
choice[1-7?]: 4
...
現在の設定ファイルの設定が反映され、新設のものについて果てしなく質問攻めされる
カーネルの設定
make config: 対話形式
- make oldconfigと同じ
make config
scripts/kconfig/conf --oldaskconfig Kconfig
.config:697:warning: symbol value 'm' invalid for CPU_FREQ_STAT
.config:941:warning: symbol value 'm' invalid for NF_CT_PROTO_GRE
.config:969:warning: symbol value 'm' invalid for NF_NAT_REDIRECT
.config:972:warning: symbol value 'm' invalid for NF_TABLES_INET
.config:1139:warning: symbol value 'm' invalid for NF_TABLES_IPV4
.config:1143:warning: symbol value 'm' invalid for NF_TABLES_ARP
.config:1184:warning: symbol value 'm' invalid for NF_TABLES_IPV6
.config:1559:warning: symbol value 'm' invalid for NET_DEVLINK
.config:2719:warning: symbol value 'm' invalid for ISDN_CAPI
.config:3664:warning: symbol value 'm' invalid for LIRC
*
* Linux/x86 5.9.12 Kernel Configuration
*
*
* General setup
*
Compile also drivers which will not load (COMPILE_TEST) [N/y/?] (NEW)
...
メニュー形式で設定
-
make menuconfig
- ncurses
-
make xconfig
- X(KDE)
-
make gconfig
- X(GNOME)
カーネルとカーネルモジュールのコンパイル
コンパイラアップデート
クソ古で怒られるので新しくする
参考: https://thr3a.hatenablog.com/entry/20180308/1520506543
gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
sudo yum install -y centos-release-scl
sudo yum install -y scl-utils
sudo yum install -y devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-binutils
「新しいの使うよ」とコマンド
sudo scl enable devtoolset-7 bash
gcc --version
gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ビルド・インストール
make
...
scripts/sign-file.c:25:30: fatal error: openssl/opensslv.h: No such file or directory
#include <openssl/opensslv.h>
^
compilation terminated.
足りないもの入れる
sudo yum install -y openssl-devel bc elfutils-libelf-devel
make
めっちゃ時間かかる
カーネルモジュールとカーネルのインストール
TODO: 手を動かす (ビルドが終わらなすぎるので試せてない)
# make modules_install
# make install
下記が実行される
- カーネルを/boot以下にコピー (
/boot/vmlinuz-${バージョン}
) - (必要ならば)初期RAMディスク作成
- ブートローダの設定ファイルに新しいカーネル用のエントリ追加
ブートローダの設定ファイルに新しいカーネル用のエントリ追加
sudo grep "^menuentry" /boot/grub2/grub.cfg | cut -d "'" -f 2
CentOS Linux (3.10.0-1127.19.1.el7.x86_64) 7 (Core)
CentOS Linux (3.10.0-1127.el7.x86_64) 7 (Core)
CentOS Linux (0-rescue-cd7c85585b483d2656ce72740e5b59f7) 7 (Core)
grub2-set-default で0番目をデフォルトに設定
# grub2-set-default 0
設定ファイル更新
# grub2-mkconfig -o /boot/grub2/grub.cfg
システムを再起動すると新しいデフォルトになっている
DKMS: Dynamic Kernel Module Support
https://wiki.archlinux.jp/index.php/Dynamic_Kernel_Module_Support
カーネルのアップグレード時、カーネルソースツリー外のサードパーティ製カーネルモジュールを自動でリビルドしてくれる