Linuxカーネルの操作まとめ

##カーネルバージョンの確認

方法1.unameコマンド

```
$ uname -r
3.10.0-957.12.2.el7.x86_64
```

方法2.`/proc/version`を参照

```
$ cat /proc/version 
Linux version 3.10.0-957.12.2.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Tue May 14 21:24:32 UTC 2019
```

方法3.カーネルソースのMakefileを参照

```
$ head /usr/src/kernels/3.10.0-957.27.2.el7.x86_64.debug/Makefile
VERSION = 3
PATCHLEVEL = 10
SUBLEVEL = 0
EXTRAVERSION = -957.27.2.el7.x86_64.debug
```
##カーネルイメージ（本体）の場所

```
$ ls /boot/vmlinuz*
/boot/vmlinuz-3.10.0-957.12.2.el7.x86_64
```

##カーネルモジュール
###場所

```
$ ls /lib/modules/3.10.0-957.12.2.el7.x86_64/
build   modules.alias      modules.builtin      modules.dep.bin  modules.modesetting  modules.softdep      source   weak-updates
extra   modules.alias.bin  modules.builtin.bin  modules.devname  modules.networking   modules.symbols      updates
kernel  modules.block      modules.dep          modules.drm      modules.order        modules.symbols.bin  vdso
```

###ロード済みモジュールの確認
####lsmodコマンド
モジュール名, サイズ, 参照回数, そのモジュールに依存しているモッジュール名を表示

```
$ lsmod
Module                  Size  Used by
binfmt_misc            17468  1 
tcp_diag               12591  0 
inet_diag              18949  1 tcp_diag
ip6t_rpfilter          12595  1 
ipt_REJECT             12541  2 
nf_reject_ipv4         13373  1 ipt_REJECT
ip6t_REJECT            12625  2 
(以下省略)
```

####`/proc/modules`を参照

```
$ cat /proc/modules 
binfmt_misc 17468 1 - Live 0xffffffffc053b000
tcp_diag 12591 0 - Live 0xffffffffc0536000
inet_diag 18949 1 tcp_diag, Live 0xffffffffc052c000
ip6t_rpfilter 12595 1 - Live 0xffffffffc0527000
ipt_REJECT 12541 2 - Live 0xffffffffc0522000
```

###モジュールの情報確認
####modinfoコマンド

```
$ modinfo ip_tables
filename:       /lib/modules/3.10.0-957.12.2.el7.x86_64/kernel/net/ipv4/netfilter/ip_tables.ko.xz
description:    IPv4 packet filter
author:         Netfilter Core Team <coreteam@netfilter.org>
license:        GPL
retpoline:      Y
rhelversion:    7.6
srcversion:     F96FABBB9428467441111B5
depends:        
intree:         Y
vermagic:       3.10.0-957.12.2.el7.x86_64 SMP mod_unload modversions 
signer:         CentOS Linux kernel signing key
sig_key:        8D:E6:4F:B5:96:9B:55:7E:DC:7F:03:2E:EA:BC:BE:4F:37:17:7F:4E
sig_hashalgo:   sha256
```

###モジュールのロード/アンロード
ロード
`insmod モジュールのパス`

アンロード
`rmmod モジュール名`
`modprobe -r モジュール名`

依存関係を考慮してロード
`modprobe モジュール名`

###モジュールの依存関係

モジュールの依存関係を表示
`modprobe --show-depends モジュール名`

モジュールの依存関係（modules.dep）の確認
ablk_helper.ko.xzはcryptd.ko.xzを必要としている

```
$ head /usr/lib/modules/3.10.0-957.12.2.el7.x86_64/modules.dep
kernel/arch/x86/crypto/ablk_helper.ko.xz: kernel/crypto/cryptd.ko.xz
kernel/arch/x86/crypto/glue_helper.ko.xz:
kernel/arch/x86/crypto/camellia-x86_64.ko.xz: kernel/crypto/xts.ko.xz 
```

##カーネルのコンパイル

カーネルソースのtarballをダウンロード＆展開

```
$ wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.16.73.tar.xz
$ xz -dc linux-3.16.73.tar.xz |tar xvf -
$ cd linux-3.16.73/
```

#####カーネルの設定ファイル.configの作成

方法1.コンソール上でカーネルオプション毎に対話的に設定

```
$ make oldconfig
scripts/kconfig/conf --oldconfig Kconfig
#
# using defaults found in /boot/config-3.10.0-957.12.2.el7.x86_64
#
/boot/config-3.10.0-957.12.2.el7.x86_64:909:warning: symbol value 'm' invalid for BRIDGE_NETFILTER
/boot/config-3.10.0-957.12.2.el7.x86_64:1391:warning: symbol value 'm' invalid for OPENVSWITCH_GRE
/boot/config-3.10.0-957.12.2.el7.x86_64:1392:warning: symbol value 'm' invalid for OPENVSWITCH_VXLAN
/boot/config-3.10.0-957.12.2.el7.x86_64:4351:warning: symbol value 'm' invalid for SND_SEQUENCER_OSS
*
* Restart config...
*
*
* General setup
*
Cross-compiler tool prefix (CROSS_COMPILE) [] 
Compile also drivers which will not load (COMPILE_TEST) [N/y/?] (NEW) 
Local version - append to kernel release (LOCALVERSION) [] 
Automatically append version information to the version string (LOCALVERSION_AUTO) [N/y/?] n
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)
choice[1-6?]: 
Default hostname (DEFAULT_HOSTNAME) [(none)] (none)
(以下省略)
```


方法2.メニュー形式でオプションを選択して設定
`make menuconfig`

方法3.X(KDE)上で設定
`make xconfig`

方法4.X(GNOME)上で設定
`make gconfig`

#####カーネル・カーネルモジュールのコンパイル
```
$ make
scripts/kconfig/conf --silentoldconfig Kconfig
  SYSTBL  arch/x86/syscalls/../include/generated/asm/syscalls_32.h
  SYSHDR  arch/x86/syscalls/../include/generated/asm/unistd_32_ia32.h
  SYSHDR  arch/x86/syscalls/../include/generated/asm/unistd_64_x32.h
  SYSTBL  arch/x86/syscalls/../include/generated/asm/syscalls_64.h
  SYSHDR  arch/x86/syscalls/../include/generated/uapi/asm/unistd_32.h
(省略)
  IHEX2FW firmware/whiteheat.fw
  IHEX2FW firmware/keyspan_pda/keyspan_pda.fw
  IHEX2FW firmware/keyspan_pda/xircom_pgs.fw
```

#####カーネル・カーネルモジュールのインストール
カーネルモジュールのインストール

```
$ sudo make modules_install
  INSTALL arch/x86/crypto/aesni-intel.ko
  INSTALL arch/x86/crypto/blowfish-x86_64.ko
  INSTALL arch/x86/crypto/camellia-aesni-avx-x86_64.ko
(省略)
  INSTALL /lib/firmware/keyspan_pda/keyspan_pda.fw
  INSTALL /lib/firmware/keyspan_pda/xircom_pgs.fw
  DEPMOD  3.16.73
```

カーネルのインストール

```
$ sudo make install
sh ./arch/x86/boot/install.sh 3.16.73 arch/x86/boot/bzImage \
	System.map "/boot"

```
カーネルのインストールにより以下が行われる

- /boot以下にカーネル作成

```
$ ll /boot/vmlinuz-3.16.73 
-rw-r--r-- 1 root root 5714928  9月 11 23:30 /boot/vmlinuz-3.16.73
```

- 初期RAMを必要に応じて作成

```
$ ll /boot/initramfs-3.16.73.img 
-rw------- 1 root root 23569011  9月 11 23:31 /boot/initramfs-3.16.73.img
```

- ブートローダの設定ファイルに新しいカーネル用のエントリを追加

```
ブートローダの設定ファイルに登録されているカーネルを確認
# grep "^menuentry" /boot/grub2/grub.cfg 
menuentry 'CentOS Linux (3.16.73) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-957.12.2.el7.x86_64-advanced-8ac075e3-1124-4bb6-bef7-a6811bf8b870' {
menuentry 'CentOS Linux (3.10.0-957.12.2.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-957.12.2.el7.x86_64-advanced-8ac075e3-1124-4bb6-bef7-a6811bf8b870' {
```

```
コンパイルした3.16が０番目（一番上のため）なので、↓の通りデフォルトのカーネルを変更
# grub2-set-default 0

設定ファイルの更新
# grub2-mkconfig -o /boot/grub2/grub.cfg 
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.16.73
Found initrd image: /boot/initramfs-3.16.73.img
Found linux image: /boot/vmlinuz-3.10.0-957.12.2.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-957.12.2.el7.x86_64.img
done

# diff /boot/grub2/grub.cfg ~/grub.cfg.org 
88c88
< menuentry 'CentOS Linux (3.16.73) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.16.73-advanced-8ac075e3-1124-4bb6-bef7-a6811bf8b870' {
---
> menuentry 'CentOS Linux (3.16.73) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-957.12.2.el7.x86_64-advanced-8ac075e3-1124-4bb6-bef7-a6811bf8b870' {
89a90
> 	set gfxpayload=keep
95c96
< 	  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  8ac075e3-1124-4bb6-bef7-a6811bf8b870
---
> 	  search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1'  8ac075e3-1124-4bb6-bef7-a6811bf8b870
99c100
< 	linux16 /boot/vmlinuz-3.16.73 root=UUID=8ac075e3-1124-4bb6-bef7-a6811bf8b870 ro no_timer_check console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 elevator=noop crashkernel=auto 
---
> 	linux16 /boot/vmlinuz-3.16.73 root=UUID=8ac075e3-1124-4bb6-bef7-a6811bf8b870 ro no_timer_check console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 elevator=noop crashkernel=auto LANG=en_US.UTF-8
110c111
< 	  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  8ac075e3-1124-4bb6-bef7-a6811bf8b870
---
> 	  search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1'  8ac075e3-1124-4bb6-bef7-a6811bf8b870
114c115
< 	linux16 /boot/vmlinuz-3.10.0-957.12.2.el7.x86_64 root=UUID=8ac075e3-1124-4bb6-bef7-a6811bf8b870 ro no_timer_check console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 elevator=noop crashkernel=auto 
---
> 	linux16 /boot/vmlinuz-3.10.0-957.12.2.el7.x86_64 root=UUID=8ac075e3-1124-4bb6-bef7-a6811bf8b870 ro no_timer_check console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 elevator=noop crashkernel=auto LANG=en_US.UTF-8

再起動後、カーネルバージョンの確認
$ uname -r
3.16.73
```

##カーネルパラメータ 
#####カーネルパラメータの確認

方法1.sysctlコマンドで確認

```
$ sysctl kernel.hostname 
kernel.hostname = webapp1
$ sysctl -a
abi.vsyscall32 = 1
crypto.fips_enabled = 0
debug.exception-trace = 1
debug.kprobes-optimization = 1
debug.panic_on_rcu_stall = 0
dev.hpet.max-user-freq = 64
dev.mac_hid.mouse_button2_keycode = 97
dev.mac_hid.mouse_button3_keycode = 100
(以下省略)
```

方法2`/proc/sys`ディレクトリ配下を確認

```
$ ls /proc/sys
abi  crypto  debug  dev  fs  kernel  net  sunrpc  user  vm
# cat /proc/sys/kernel/shmmax 
18446744073692774399
```

#####カーネルパラメータの設定
方法1.sysctlコマンドで設定
※再起動すると元に戻る

```
# cat /proc/sys/kernel/hostname 
webapp2
# sysctl -w kernel/hostname="hogehoge"
kernel.hostname = hogehoge
cat /proc/sys/kernel/hostname 
hogehoge
```

方法2.`/etc/sysctl.conf`に記述する

##初期RAMディスク
####初期RAMとは？
RAMディスク：　メモリ上に作成されたファイルシステム
ループバックマウント：　ファイルをファイルシステムとしてマウントする機能

Linuxの起動時、ファイルをメモリに展開（これがRAMディスク）して、このRAMディスクを暫定的なルートファイルシステムとしてカーネルを起動する。（その後、本来のルートファイルシステムを起動する）
この起動用のRAMディスクを初期RAMディスクという。

本来のルートファイルシステムのロードに必要なドライバなどを初期RAMディスク（元となるファイル）に含めておいたりする。
初期RAMディスクの元となるファイルには`initr`と`initramfs`がある。
例えば以下の通り、/boot配下にイメージファイルとしてある。

```
# ls /boot/initramfs-3.10.0-957.12.2.el7.x86_64.img 
```

#####initramfsイメージファイルの作成
`mkinitramfs -o RAMディスクイメージファイル カーネルバージョン`