このKernel、どんなKernel？

# はじめに

この記事は、[Linux Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/linux)の8日目です。

この記事では、今使っているLinux Kernelがどんなkernelなのか、どんな設定で動いているのかを確認する方法を紹介します。
Linux Kernelは様々な用途に使われています。
そのため、ひとくちにLinux Kernelと言っても、動作はシステムによって全然違います。
現状を把握する手段を知ることで、効率的にKernelのコードリーディングやより良い設定を探す一助になれば幸いです。

また、コメント大歓迎ですので、なんでもお気づきのことがありましたらぜひお気軽にお願いします。

- この記事で書くこと
  - Linux Kernelの素性を確認する方法
  - Linux Kernelの設定値を確認する方法

- この記事で書かないこと
  - 各プロセスや各ユーザなどに対する設定（`ulimit`や`nice`や`quotactl`など）
  - ユーザ空間の設定(`sysconf`や`pathconf`など)
  - ドライバに対する設定（insmod時のparameterなど）
  - 各設定項目の説明


下記6つの項目を紹介しています。
各項目は独立していますので、気になるところからご覧ください。

1. [Kernel Version](#kernel-version)
2. [CPU Architecture](#cpu-architecture)
3. [Kernel Build Config](#kernel-build-config)
4. [Command-line Parameters](#command-line-parameters)
5. [sysctl](#sysctl)
6. [Device Tree](#device-tree)


# Kernel Version

まずはどのversionのkernelが使われているのかを見てみましょう。
versionを知ることで、特定の機能や修正が入っているかを調査の材料にできます。


## Kernel Versionの確認方法 `uname -r`

`uname -r`コマンドを実行することで、実行中のKernel Versionを取得できます。
以下は、素のLinux Kernel 5.3.10を使っているときの結果です。 

```shell-session
$ uname -r
5.3.10
```

環境によっては`uname -r`を実行すると、上記のような３つの数字の後ろにいろいろくっついてるかも知れません。
例えば、以下はUbuntu 19.10での実行結果です。

```shell-session
$ uname  -r
5.3.0-19-generic
```

この場合、version `5.3.0`のLinux kernelをベースに、Ubuntu 19.10用に修正したkernel、ということになります。
どのような修正がされているかは、どこかで公開されているはずです。
Ubuntuの場合は、[source codeのパッケージ](https://launchpad.net/ubuntu/+source/linux/5.3.0-19.20)および[diff](https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/linux/5.3.0-19.20/linux_5.3.0-19.20.diff.gz)が配布されています。

versionの後ろの文字列(`19-generic`)の意味は、distributionごとに違います。
Ubuntuの場合は[こちら](https://wiki.ubuntu.com/Kernel/FAQ#Kernel.2FFAQ.2FGeneralVersionMeaning.What_does_a_specific_Ubuntu_kernel_version_number_mean.3F)に説明があります。


なお、versionについては他にもたくさん確認方法があり、[ここ](https://qiita.com/rarul/items/ddf9d0d7d3d94b87dfba)に詳しい記事がありますので、ぜひこちらも見てみてください。
また`uname`コマンドの中身については、[Linux Advent Calendar 2019の1日目](https://kernhack.hatenablog.com/entry/2019/12/01/120907)で詳しく解説してくれているので、そちらもぜひご覧ください。


## Kernel Versionに関する参考ページ

- [The Linux Kernel Archives](https://www.kernel.org/)
- [unameコマンドから始めるデバッグ＆カーネルハック入門 - φ(・・*)ゞ ｳｰﾝ　カーネルとか弄ったりのメモ](https://kernhack.hatenablog.com/entry/2019/12/01/120907)
- [Linuxのバージョンを確認する方法 - Qiita](https://qiita.com/rarul/items/ddf9d0d7d3d94b87dfba)
- [Kernel/FAQ - Ubuntu Wiki](https://wiki.ubuntu.com/Kernel/FAQ#Kernel.2FFAQ.2FGeneralVersionMeaning.What_does_a_specific_Ubuntu_kernel_version_number_mean.3F)
- [5.3.0-19.20 : linux package : Ubuntu](https://launchpad.net/ubuntu/+source/linux/5.3.0-19.20)

# CPU Architecture

続いて、どのCPU向けにビルドされたkernelかを確認してみます。

Linux Kernelの文脈だと、「どのCPU向けか」というのをArchitectureとかarchとか表現することが多いです。
Architectureはいろいろな意味で使われますが、ここではCPUのISA(命令セットアーキテクチャ)のことですね。
例えば、`x86_64`や`arm`などがあります。

Kernelを意識するときにCPU Architectureがわかってないケースはあまりないかも知れません。
でも、実は意外なArchitecture向けのkernelが動作していることがあります。
念の為に確認しておきましょう。

## CPU Architectureの確認方法 `uname -m` or `arch`

CPU Architectureを確認するためのコマンドには、`uname -m`と`arch`があります。
２つのコマンドはどちらも`coreutils`というパッケージで提供されており、実装は共通なので好きな方を使えばいいです。

PC(Ubuntu 18.04)の場合は、だいたい`x86_64`と表示されると思います。

```shell-session
$ uname -m
x86_64
```

Raspberry Pi 3 ModelB+(Raspbian)で試してみると、`armv7l`と表示されます。

```shell-session
$ uname -m
armv7l
```

実はRaspberry Pi 3 ModelB+には、Cortex-A53という64bitのARM CPUが搭載されています。
だったら64bit用のkernelが動いていると思ってしまいますが、その場合は`aarch64`と表示されるはずです。
つまり、Raspbianでは32bit用にビルドしたkernelが32bit互換モードで動作している、ということですね。
(推測ですが、おそらくRasPi2やRasPi zeroなど32bit CPUのモデルと共通化するためでしょう)


## Kernelの`arch`ディレクトリ

CPU Architectureを確認できたので、今度は自分が使っているCPU Architectureの処理が、
Kernelソースコード上でどこに置かれているかを見てみましょう。

Kernelのソースコードを見てみると、`arch/`ディレクトリ以下に
CPU Architectureごとのディレクトリがあることがわかります。

```
$ ls -F arch/
Kconfig  arm/	 csky/	   ia64/	mips/	openrisc/  riscv/  sparc/      x86/
alpha/	 arm64/  h8300/    m68k/	nds32/	parisc/    s390/   um/	       xtensa/
arc/	 c6x/	 hexagon/  microblaze/	nios2/	powerpc/   sh/	   unicore32/
```

先程紹介した`uname -m`コマンドの結果をちょっとだけ置換したものがディレクトリ名になります。
置換は`scripts/subarch.include`というMakefileで行われます。
例えば、`x86_64`向けのkernelをビルドするときは、`x86/`ディレクトリが使われるわけですね。
同じように、Raspbianの`armv7l`の場合は、`arm/`ディレクトリが使われます。

```scripts/subarch.include
SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
				  -e s/sun4u/sparc64/ \
				  -e s/arm.*/arm/ -e s/sa110/arm/ \
				  -e s/s390x/s390/ -e s/parisc64/parisc/ \
				  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
				  -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
				  -e s/riscv.*/riscv/)
```

## CPU Architectureの参考ページ

- [命令セット - Wikipedia](https://ja.wikipedia.org/wiki/%E5%91%BD%E4%BB%A4%E3%82%BB%E3%83%83%E3%83%88)
- [Kbuild - The Linux Kernel documentation](https://www.kernel.org/doc/html/latest/kbuild/kbuild.html#arch)
- [Coreutils - GNU core utilities](https://www.gnu.org/software/coreutils/)


# Kernel Build Config

続いては、Kernel Build Configです。
人によってはコンパイルスイッチとか`#ifdef`とか言ったほうがしっくりくるかも知れません。
単にKernel Configとか言ったときは、これのことを指す場合が多いです。

先にも述べたようにLinux Kernelは幅広い用途で使われていますが、なんでもできる万能Kernelを作ると、イメージサイズがいたずらに大きくなってしまいます。
そのため、使わない機能をコンパイル対象外にすることで、サイズを節約しています。

デバッグ機能もkernel build configでOFF/ONする場合が多いので、どのようなデバッグ機能が使えるかを知ることもできます。

## Kernel Build Configの確認方法 1. `/boot/config-X.Y.Z`

Linux distributionによっては、`/boot`以下にkernel imageと一緒に残してくれています。
例えば、Ubuntu19.10では、`/boot/config-5.3.0-19-generic`というファイルに保存されています。
CentOS 8, Debian 10でも同等のファイルがあります。

```shell-session
$ head /boot/config-$(uname -r)
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 5.3.0-19-generic Kernel Configuration
#

#
# Compiler: gcc (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008
#
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=90201
```

## Kernel Build Configの確認方法 2. `/proc/config.gz`

`CONFIG_IKCONFIG_PROC`を有効にしているkernelでは、
Kernel Build Configを`/proc/config.gz`で確認することができます。

残念ながらあまり使える環境はないです。
ただ動作中のkernelに教えてもらうため、より確実な確認方法です。
使える環境では積極的に使いましょう。

例えば、Androidで使用されているLinux Kernelではこの方法が使えることが多いです。
以下は、Android 10のEmulatorで確認したときの結果です。
(gzip圧縮されているので`zcat`コマンドを使っていることに注意してください)
Samsung Galaxy Note8 (Android 9)でも、`/proc/config.gz`が有効になっていました。

```
$ zcat /proc/config.gz | head
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 4.14.112 Kernel Configuration
#
CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
```

## Kernel Build Configにはどんな項目があるの？

Kernelのソースコードに含まれる、`Kconfig`というファイルで定義されています。
依存関係や各項目の説明などもそこに記載されています。

また`make xconfig`を実行すると、各設定項目の説明を見ながら一覧できるので、おすすめです。

<img width="600" alt="Screenshot from 2019-12-06 12-07-55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37714/15fc4167-4ad4-e683-448e-7330c983dd2b.png">

`Ctrl-f`で検索もできます。

<img width="600" alt="Screenshot from 2019-12-06 12-10-53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37714/3f3973af-7320-2b93-04af-625b9ca9682c.png">

ごくごく一部ですが、いくつかよく使う項目を紹介します。

- `CONFIG_IKCONFIG_PROC`
  Kernel Build Configを`/proc/config.gz`経由で取得できるようにします。
  Kernel Build Configを色々いじるときにはまず有効にしておくとわかりやすいです。

- `CONFIG_DEBUG_INFO`
  デバッグシンボルを付与したカーネルイメージを生成するようになります。
  `gdb`を使ったKernelデバッグをするときに必要です。

- `CONFIG_FTRACE`
  FtraceというKernelの動作を解析するための機能を有効にします。
  [LinuxにFtraceを導入する - Qiita](https://qiita.com/mhiramat/items/c73edd8f9d3f15a6adca)に詳しく解説してくれています。

- `CONFIG_KPROBE`
  動作中のKernelにバイナリパッチを当てるための仕組みである、Kprobeを有効にします。
  Kprobeをもう少し使いやすくしたツール、SystemTapを使うためにも必要です。

## Kernel Build Configの変更方法

Kernel Build Configを変更するためには、Kernelの再ビルドが必要です。

上述の方法で取得した、現状の`.config`をベースに`make menuconfig`や`make xconfig`等で編集し、Kernelを再ビルドするのが一般的な変更方法です。

ただし、`.config`はビルド時に生成されるファイルなので、ソースコード管理の対象外にすべきです。
`make menuconfig`で目的の`.config`が作れたら、`make savedefconfig`で出力される`defconfig`をコミットするようにしましょう。
`make savedefconfig`は、その時点の`.config`を再生成するための最小限のconfigを出力してくれます。

例えば、`defconfig`を`arch/x86/configs/mytest_defconfig`にコミットしておけば、次からは`make mytest_defconfig`とすることで、開発メンバみんなが編集後の`.config`を生成することができます。


```shell-session

$ make savedefconfig
$ mv defconfig arch/x86/configs/mytest_defconfig
$ mv .config .config.back
$ make mytest_defconfig
#
# configuration written to .config
#
$ diff .config .config.back
```

## Kernel Build Configの参考ページ

- [Kconfig Language — The Linux Kernel documentation](https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html)
- [Kconfig make config — The Linux Kernel documentation](https://www.kernel.org/doc/html/latest/kbuild/kconfig.html)

# Command-line Parameters

続いて、Command-line Parametersを紹介します。
Command-line Parametersとは、Kernelの起動時に引数として指定するオプションのことです。
そのためbootloaderが指定するのが一般的です。

なお、ここまでに紹介した、Kernel Version・CPU architecture・Kernel Build Configは、３つともkernelコンパイル時に決定するものでした。
対してここから紹介するのは、Kernel自体を変更することなく動作を変える仕組みです。


## Command-line Parametersの確認方法 1. `/proc/cmdline`

`/proc/cmdline`でCommand-line Parametersを確認することができます。

```shell-session
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-5.3.7+ root=UUID=71b4dc0a-e498-41f4-9cd2-a81e8c03cda8 ro quiet splash vt.handoff=1
```

## Command-line Parametersの確認方法 2. `dmesg`

`dmesg`にも出力されるので、ログしか残っていない状況でも確認可能です。

```shell-session
$ dmesg | grep "Kernel command line"
[    0.104775] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.3.7+ root=UUID=71b4dc0a-e498-41f4-9cd2-a81e8c03cda8 ro quiet splash vt.handoff=1
```

## Command-line Parametersにはどんな項目があるの？

Command-line Parametersの設定項目については、[ドキュメント](https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html)があります。

ごくごく一部ですが、参考にいくつか紹介します。
他にもたくさんあるので、ぜひドキュメントも読んでみてください。

- `loglevel`
  コンソールに出力するkernel logのレベルを変更できます。
  起動直後の不具合解析時に変更することがよくあります。

- `log_buf_len`
  kernel logのリングバッファサイズを変更できます。
  ログが流れてしまうときに、サイズを大きく取ることでログを見ることができるようになります。
  デフォルト値は`CONFIG_LOG_CPU_MAX_BUF_SHIFT`で変更可能ですが、一時的に増やす場合はこちらを使います。

- `mem`
  kernelが使うメモリサイズを指定することができます。
  メモリが少ない状況をシミュレートするときや、メモリマップが怪しいときなどに使います。


- `ftrace`
  FtraceというKernelの動作を解析するための機能を、起動直後から有効にします。
  起動直後のkernelの振る舞いを解析するときに使います。


## Command-line Parametersの参考ページ

- [The kernel's command-line parameters - The Linux Kernel documentation](https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html)



# sysctl

次に紹介する`sysctl`は、Kernel Parameterを実行中に変更する仕組みです。
Command-line parametersのように起動時だけではなく、いつでも変更できます。

## sysctlの確認方法 1. `sysctl`

`sysctl -a`を実行することで、すべてのparameterの現在値を確認することができます。
いくつかparameterを参照するためにはroot権限が必要です。

```shell-session
$ sudo sysctl -a | head
abi.vsyscall32 = 1
debug.exception-trace = 1
debug.kprobes-optimization = 1
dev.cdrom.autoclose = 1
dev.cdrom.autoeject = 0
dev.cdrom.check_media = 0
dev.cdrom.debug = 0
dev.cdrom.info = CD-ROM information, Id: cdrom.c 3.20 2003/12/17
dev.cdrom.info = 
dev.cdrom.info = drive name:	
```

## sysctlの確認方法 2. `/proc/sys/`

`sysctl`で設定できるparameterは、全て`/proc/sys`以下にファイルとして公開されています。
このファイルを読み出すことでparamter値の確認が、書き込むことで変更ができます。
というか、`sysctl`コマンドも内部では、`/proc/sys`経由で確認・変更しています。

```shell-session
$ find /proc/sys -type f | head | xargs -I@ sh -c 'echo "@ = $(cat @ | head -1)"'
/proc/sys/abi/vsyscall32 = 1
/proc/sys/debug/exception-trace = 1
/proc/sys/debug/kprobes-optimization = 1
/proc/sys/dev/cdrom/autoclose = 1
/proc/sys/dev/cdrom/autoeject = 0
/proc/sys/dev/cdrom/check_media = 0
/proc/sys/dev/cdrom/debug = 0
/proc/sys/dev/cdrom/info = CD-ROM information, Id: cdrom.c 3.20 2003/12/17
/proc/sys/dev/cdrom/lock = 1
/proc/sys/dev/hpet/max-user-freq = 64
```

変更可能なparameterなのか、root権限は必要なのか、を事前に知りたいときは、
`/proc/sys`以下のファイルのパーミッションを見ることで確認できます。

下記を見ると、`fs.file-max`は書き込み可能だけど、
`fs.file-nr`は書き込み不可だということがわかります。
また、`fs.file-max`を変更するためにはroot権限が必要だ、ということもわかりますね。

```
$ ls -l /proc/sys/fs/file-*
-rw-r--r-- 1 root root 0 12月  6 14:01 /proc/sys/fs/file-max
-r--r--r-- 1 root root 0 12月  6 14:01 /proc/sys/fs/file-nr
```


## sysctlにはどんな項目があるの？

`sysctl`で設定できる項目についても、[ドキュメント](https://www.kernel.org/doc/html/latest/admin-guide/sysctl/index.html)があります。

こちらもごくごく一部ですが、参考にどんな項目があるか紹介します。

- `fs.file-max`
  システム全体で開くことのできるファイル数を、確認・変更することができます。

- `fs.file-nr`
  現在開いているファイル数と、システム全体で開くことのできるファイル数を確認することができます。
  先述のとおり、read-onlyです。
  例えば、`15840	0	3231322`となっていた場合は、
  現在開いているファイル数が`15840`で、システム全体で開くことのできるファイル数が`3231322`です。
  真ん中の`0`は、互換性のために残っているだけで常に0なので、気にしなくていいです。
  システムとしてfd leakが発生していないか確認するときなどに使います。

- `fs.nr_open`
  1プロセスあたりでopenできるファイル数です。
  ただし、実際にはプロセスごとに設定される`ulimit`でより厳しく制限されていることが多いです。
  `ulimit`による制限は、`/proc/${PID}/limits`で確認することができます。

- `kernel.print-fatal-signals`
  この値を1にすると、プロセスが異常終了したときにプロセス名とレジスタ値をkernel logに残します。

- `kernel.core_pattern`
  プロセスが異常終了したときのCoredumpを残す方法を設定できます。
  Coredumpのファイル名を変更するだけではなく、特定のプログラムにリダイレクトすることもできたりします。
  [Linux Effective Coredump - Qiita](https://qiita.com/rarul/items/d33b664c8414f065e65e)にて詳しく解説してくれています。

- `vm.drop_caches`
  値を書き込んだときにkernelのキャッシュを解放します。
  この項目がちょっと変わっているのは、読み出した値に意味はなく、書き込んだときに処理が走る点です。
  [Linuxのdrop_cachesにwriteした時の動きを追う - Qiita](https://qiita.com/rarul/items/a6688fd2a06d960cb5ea)にて詳しく解説してくれています。
  この項目のファイルパーミッションはread-writeになっていますが、本当はwrite-onlyであるべきですね。


## sysctlに設定した値はいつまで有効なの？

基本的に`sysctl`による設定は、kernelのグローバル変数に保存されるだけなので、システムを再起動したら忘れてしまいます。

永続的に設定するための仕組みはディストリビューションによって異なりますが、多くのディストリビューションでは、`/etc/sysctl.conf`を起動時にデフォルト値として読み込みます。
これは、システム起動時にinitスクリプトから`sysctl --system`を実行することで実現されています。

Androidの場合は、起動時の処理を記述するinitrcスクリプトから直接`/proc/sys`に書き込みます。

```/init.rc
on early-init
    # Disable sysrq from keyboard
    write /proc/sys/kernel/sysrq 0
```

## `sysctl`の参考ページ

- [Documentation for /proc/sys - The Linux Kernel documentation](https://www.kernel.org/doc/html/latest/admin-guide/sysctl/index.html)
- [Linux Effective Coredump - Qiita](https://qiita.com/rarul/items/d33b664c8414f065e65e)
- [Linuxのdrop_cachesにwriteした時の動きを追う - Qiita](https://qiita.com/rarul/items/a6688fd2a06d960cb5ea)
- [rootdir/init.rc - platform/system/core.git - Git at Google](https://android.googlesource.com/platform/system/core.git/+/refs/tags/android-10.0.0_r17/rootdir/init.rc)

# Device Tree

最後は、Device Treeを確認してみます。

Device Treeとは、ハードウェア構成情報です。
ARMのCPUを使った組込系のシステムでよく使われています。

組込みシステムではデバイスのメモリアドレスや割り込み番号などがシステムごとに異なります。
それらをデバイスドライバのソースコードに埋め込んでしまうと、読みにくくメンテナンスしにくくなってしまいます。
そのためこれらのハードウェア構成情報は、ソースコードから独立したDevice Tree Source(`.dts`ファイル)に記述する方法が一般的です。

試しに`5.3.10`で`.dts`ファイルの数のarchごとのランキングを見てみると、armがダントツですね。
次がpowerpcになっています。
Device Treeは、もともとpowerpc向けに開発されたらしいので、そのためでしょうね。

```shell-session
$ find arch/ -name *.dts | cut -d '/' -f 2 | uniq -c | sort -n -r
   1176 arm
    265 arm64
    200 powerpc
     50 mips
     17 arc
      7 xtensa
      5 c6x
      3 h8300
      2 openrisc
      2 nios2
      1 x86
      1 sh
      1 riscv
      1 nds32
      1 microblaze
```

ではPCの世界ではどうしているかというと、UEFI BIOSからACPI規格に従ってハードウェアの情報をもらうらしいですが、よく知りません。
ごめんなさい。

## Device Treeの確認方法 `/sys/firmware/fdt`

Device Treeを使うシステムの場合、
`/sys/firmware/fdt`にFDT形式に変換されたDevice Treeがあります。
FDTとは、Flattend Device Treeの略で、DTB(Device Tree Blob)とも言います。
`dtc`(Device Tree Compiler)というコマンドで、FDTを`.dts`ファイルに変換することができます。

組込みシステムの場合`/sys/firmware/fdt`をPCに転送してから、PCで`.dts`に変換することも可能です。
`/proc/device-tree`以下に、ファイルシステムに展開された状態のDevice Treeもありますが、私は`/sys/firmware/fdt`の方が取り回しやすいので便利だと思います。

以下は、Raspberry Pi 3 ModelB+ (Raspbian)でのDevice Treeの確認結果です。

```shell-session
$ sudo dtc /sys/firmware/fdt 2> /dev/null | head
/dts-v1/;

/memreserve/	0x0000000000000000 0x0000000000001000;
/ {
	memreserve = < 0x3b400000 0x4c00000 >;
	serial-number = "00000000c97f6276";
	compatible = "raspberrypi,3-model-b\0brcm,bcm2837";
	model = "Raspberry Pi 3 Model B Rev 1.2";
	interrupt-parent = < 0x01 >;
	#address-cells = < 0x01 >;
```

## Device Treeにはどんな項目があるの？

Device Treeの仕様書は[こちら](https://www.devicetree.org/specifications/)に公開されています。

ただし、実際Device Treeに書かれた設定値がどのような意味をもつかは、対象のハードウェア仕様およびデバイスドライバの仕様に大きく依存します。
意外な使われ方がされていることも結構あるので、Device Treeを見るときはできるだけその値を使う実装も確認しましょう。


## Device Treeの参考ページ

- [Specifications - DeviceTree](https://www.devicetree.org/specifications/)
- [Device Tree Reference - eLinux.org](https://elinux.org/Device_Tree_Reference)
- [[Linux][kernel] Device Tree についてのまとめ - Qiita](https://qiita.com/koara-local/items/ed99a7b96a0ca252fc4e)
- [ほんのり詳しいUEFI BIOS（PDF版） - 電脳律速 - BOOTH](https://booth.pm/ja/items/1310585)


# おわりに

最後まで読んでくださり、ありがとうございます。

設定は、直接的にKernelの振る舞いを変えることができるので、Kernelのコードリーディングの取っ掛かりとしてとても良いと思っています。
設定項目名で`grep`したらすぐに関連実装が見つかりますし、なにより設定値を変えて動作を見てみるのが簡単です。

この記事がどなたかの参考になれば、とてもうれしいです。