[LINUX] What kind of Kernel is this Kernel?

Introduction

This article is the 8th day of Linux Advent Calendar 2019 --Qiita.

In this article, I will show you how to check what kind of kernel your Linux Kernel is and what settings it is running on. The Linux Kernel is used for various purposes. Therefore, even if you say Linux Kernel in a nutshell, the operation is completely different depending on the system. We hope that knowing how to understand the current situation will help you to efficiently read the kernel code and find better settings.

Also, comments are welcome, so please feel free to contact us if you have any questions.

--What to write in this article --How to check the identity of the Linux Kernel --How to check the Linux Kernel settings

--What not to write in this article --Settings for each process, each user, etc. (ʻulimit, nice, quotal, etc.) --User space settings (such as sysconf and pathconf`) --Settings for the driver (parameters at the time of insmod, etc.) --Explanation of each setting item

The following 6 items are introduced. Each item is independent, so please see from where you are interested.

  1. Kernel Version
  2. CPU Architecture
  3. Kernel Build Config
  4. Command-line Parameters
  5. sysctl
  6. Device Tree

Kernel Version

First, let's see which version of the kernel is used. By knowing the version, you can use it as a basis for investigating whether a specific function or modification is included.

How to check Kernel Version ʻuname -r`

You can get the running Kernel Version by running the ʻuname -r` command. Below are the results when using a plain Linux Kernel 5.3.10.

$ uname -r
5.3.10

Depending on your environment, running ʻuname -r` may have a lot of sticking behind the three numbers above. For example, the following is the execution result on Ubuntu 19.10.

$ uname  -r
5.3.0-19-generic

In this case, it is a kernel modified for Ubuntu 19.10 based on the version 5.3.0 Linux kernel. What kind of corrections have been made should be published somewhere. For Ubuntu, source code package and diff /primary/+sourcefiles/linux/5.3.0-19.20/linux_5.3.0-19.20.diff.gz) is distributed.

The meaning of the string (19-generic) after version is different for each distribution. For Ubuntu, it is explained in here.

There are many other ways to check the version, and there is a detailed article in here, so please take a look. Also, the contents of the ʻuname` command are explained in detail in Linux Advent Calendar 2019 Day 1. Please take a look there as well.

Reference page about Kernel Version

CPU Architecture

Next, let's check which CPU the kernel was built for.

In the context of the Linux Kernel, "which CPU is for" is often expressed as Architecture or arch. Architecture is used in many ways, but here it is the ISA (Instruction Set Architecture) of the CPU. For example, x86_64 and ʻarm`.

There may not be many cases where you do not know the CPU Architecture when you are aware of the Kernel. However, in fact, there are times when a kernel for Architecture is working. Let's check it just in case.

How to check CPU Architecture ʻuname -m or ʻarch

Commands for checking the CPU Architecture include ʻuname -m and ʻarch. Both of the two commands are provided in a package called coreutils, and the implementation is common, so you can use whichever you like.

For PC (Ubuntu 18.04), it should be displayed as x86_64.

$ uname -m
x86_64

When I try it on Raspberry Pi 3 Model B + (Raspbian), it says ʻarmv7l`.

$ uname -m
armv7l

In fact, the Raspberry Pi 3 Model B + is equipped with a 64-bit ARM CPU called Cortex-A53. If so, I think that the kernel for 64bit is working, but in that case it should be displayed as ʻaarch64`. In other words, in Raspbian, the kernel built for 32bit is running in 32bit compatibility mode. (I guess, probably because it is shared with 32-bit CPU models such as RasPi 2 and RasPi zero)

Kernel ʻarch` directory

Now that I have confirmed the CPU Architecture, the processing of the CPU Architecture I am using this time Let's see where it is located in the Kernel source code.

Looking at the Kernel source code, under the ʻarch / `directory You can see that there is a directory for each 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/

The directory name is a slight replacement of the result of the ʻuname -mcommand introduced earlier. The replacement is done in a Makefile calledscripts / subarch.include. For example, when building a kernel for x86_64, the x86 / directory is used. Similarly, for Raspbian's ʻarmv7l, the ʻarm /` directory is used.

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 reference page

-Instruction set-Wikipedia

Kernel Build Config

Next is Kernel Build Config. Depending on the person, it may be more appropriate to say a compile switch or # ifdef. When we simply say Kernel Config, we often refer to this.

As mentioned earlier, the Linux kernel is used for a wide range of purposes, but if you create a universal kernel that can do anything, the image size will grow unnecessarily. Therefore, we save size by excluding unused features from compilation.

Since the debug function is often turned off / on with the kernel build config, you can also know what kind of debug function can be used.

How to check Kernel Build Config 1. /boot/config-X.Y.Z

Depending on the Linux distribution, it is left under / boot with the kernel image. For example, in Ubuntu 19.10, it is stored in a file called /boot/config-5.3.0-19-generic. There are equivalent files on CentOS 8 and Debian 10.

$ 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

How to check Kernel Build Config 2. /proc/config.gz

For kernels with CONFIG_IKCONFIG_PROC enabled You can check the Kernel Build Config in /proc/config.gz.

Unfortunately, there is not much usable environment. However, it is a more reliable confirmation method because it will be taught by the running kernel. Let's use it positively in an environment where it can be used.

For example, the Linux Kernel used on Android often works with this method. The following is the result when confirmed with the Android 10 Emulator. (Note that you are using the zcat command as it is gzipped) The /proc/config.gz was also enabled on the Samsung Galaxy Note8 (Android 9).

$ 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"

What are the items in Kernel Build Config?

It is defined in a file called Kconfig included in the Kernel source code. Dependencies and explanations of each item are also described there.

Also, if you execute make xconfig, you can see the list while looking at the explanation of each setting item, so it is recommended.

Screenshot from 2019-12-06 12-07-55.png

You can also search with Ctrl-f.

Screenshot from 2019-12-06 12-10-53.png

Here are just a few of the most frequently used items.

How to change Kernel Build Config

To change the Kernel Build Config, you need to rebuild the Kernel.

The general change method is to edit the current .config obtained by the above method with make menuconfig or make xconfig and rebuild the Kernel.

However, .config is a build-generated file and should be excluded from source code control. Once you have created the desired .config with make menuconfig, commit the defconfig output with make saved efconfig. make savedefconfig will output the minimum config to regenerate the current .config.

For example, if you commit defconfig to ʻarch / x86 / configs / mytest_defconfig, then you can use make mytest_defconfigto generate the edited.config` for all development members. I can do it.


$ 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 reference page

Command-line Parameters

Next, I will introduce Command-line Parameters. Command-line Parameters are options specified as arguments when starting the Kernel. Therefore, it is generally specified by the bootloader.

The Kernel Version, CPU architecture, and Kernel Build Config introduced so far were all decided at the time of kernel compilation. On the other hand, what we will introduce from here is a mechanism to change the operation without changing the Kernel itself.

How to check Command-line Parameters 1. / proc / cmdline

You can check the Command-line Parameters in / proc / cmdline.

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

How to check Command-line Parameters 2. dmesg

Since it is also output to dmesg, you can check it even if only the log remains.

$ 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

What kind of items are there in Command-line Parameters?

There is Documentation for the setting items of Command-line Parameters.

Although it is a very small part, I will introduce some for reference. There are many others, so be sure to read the documentation as well.

Command-line Parameters reference page

sysctl

The following sysctl is a mechanism to change the Kernel Parameter during execution. You can change it at any time, not just at startup like Command-line parameters.

How to check sysctl 1. sysctl

You can check the current values of all parameters by running sysctl -a. You need root privileges to see some parameters.

$ 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:	

How to check sysctl 2. / proc / sys /

All parameters that can be set with sysctl are published as files under / proc / sys. You can check the paramter value by reading this file, and you can change it by writing. In fact, the sysctl command is also internally checked and changed via / proc / sys.

$ 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

If you want to know in advance whether it is a parameter that can be changed or if you need root privileges, You can check it by looking at the permissions of the files under / proc / sys.

Looking at the following, fs.file-max is writable, You can see that fs.file-nr is not writable. You can also see that you need root privileges to modify fs.file-max.

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

What are the items in sysctl?

There is also a Documentation for items that can be set with sysctl.

This is also a very small part, but I will introduce what kind of items there are for reference.

How long is the value set in sysctl valid?

Basically, the sysctl settings are only saved in the kernel's global variables and will be forgotten when the system is rebooted.

The mechanism for setting it persistently depends on the distribution, but many distributions load /etc/sysctl.conf as the default value at startup. This is achieved by running sysctl --system from the init script at system startup.

For Android, write to / proc / sys directly from the initrc script that describes the startup process.

/init.rc


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

Reference page of sysctl

Device Tree

Finally, let's check the Device Tree.

Device Tree is hardware configuration information. It is often used in embedded systems that use ARM CPUs.

In embedded systems, the memory address and interrupt number of the device differ from system to system. Embedding them in the device driver source code makes them hard to read and maintain. Therefore, it is common to write these hardware configuration information in a Device Tree Source (.dts file) that is independent of the source code.

If you look at the ranking of the number of .dts files by arch in 5.3.10, arm is by far the best. Next is powerpc. It seems that Device Tree was originally developed for powerpc, so that's probably why.

$ 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

Then, what is happening in the PC world? It seems that UEFI BIOS receives hardware information according to the ACPI standard, but I'm not sure. sorry.

How to check Device Tree / sys / firmware / fdt

For systems that use Device Tree There is a Device Tree converted to FDT format in / sys / firmware / fdt. FDT is an abbreviation for Flattend Device Tree and is also called DTB (Device Tree Blob). You can convert FDT to a .dts file with the command dtc (Device Tree Compiler).

For embedded systems, it is also possible to transfer / sys / firmware / fdt to a PC and then convert it to .dts on the PC. Under / proc / device-tree, there is also a Device Tree expanded to the file system, but I think / sys / firmware / fdt is more convenient because it is easier to handle.

The following is the confirmation result of Device Tree on Raspberry Pi 3 ModelB + (Raspbian).

$ 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 >;

What kind of items are there in the Device Tree?

The Device Tree specifications are available here [https://www.devicetree.org/specifications/).

However, what the actual settings written in the Device Tree mean depends largely on the target hardware specifications and device driver specifications. There are quite a few cases where it is used unexpectedly, so when you look at the Device Tree, check the implementation that uses that value as much as possible.

Device Tree reference page

in conclusion

Thank you for reading to the end.

The settings can directly change the behavior of the Kernel, so I think it is a very good starting point for Kernel code reading. You can find the related implementation as soon as you grep with the setting item name, and above all, it is easy to change the setting value and see the operation.

I would be very happy if this article was helpful to anyone.

Recommended Posts

What kind of Kernel is this Kernel?
What kind of programming language is Python?
What is the Linux kernel?
What is the cause of the following error?
What is namespace
What is Django? .. ..
What is dotenv?
What is POSIX?
What is Linux
What is klass?
What is SALOME?
What is Linux?
What is python
What kind of book is the best-selling "Python Crash Course" in the world?
What is hyperopt?
What is Linux
What is pyvenv
What is __call__
What is Linux
What is Python
This is the only basic review of Python ~ 1 ~
This is the only basic review of Python ~ 2 ~
This is the only basic review of Python ~ 3 ~
What is equal repayment of principal and interest and equal repayment of principal and interest?
This is a sample of function application in dataframe.
[Python] What is Pipeline ...
What is Calmar Ratio?
What is a terminal?
[PyTorch Tutorial ①] What is PyTorch?
What is hyperparameter tuning?
What is a hacker?
What is the true identity of Python's sort method "sort"? ??
What is JSON? .. [Note]
Basics of Python learning ~ What is a string literal? ~
What is Linux for?
What is a pointer?
What is ensemble learning?
What is TCP / IP?
What is a recommend engine? Summary of the types
What is Python's __init__.py?
What is an iterator?
What is UNIT-V Linux?
[Python] What is virtualenv
What is machine learning?
What is the default TLS version of the python requests module?
I stumbled on TensorFlow (What is Out of GPU Memory)
What is Minisum or Minimax?
What is Linux? [Command list]
A memorandum of kernel compilation
2017.3.6 ~ 3.12 Summary of what we did
What is Logistic Regression Analysis?
What is the activation function?
Is this string a decimal?
What is an instance variable?
Is this a system trade?
What is a decision tree?
What is a Context Switch?
What is Google Cloud Dataflow?
[DL] What is weight decay?
[Python] Python and security-① What is Python?
What is a super user?