[LINUX] Was für ein Kernel ist dieser Kernel?

Einführung

Dieser Artikel ist der 8. Tag von Linux Adventskalender 2019 - Qiita.

In diesem Artikel werde ich Ihnen zeigen, wie Sie überprüfen, welche Art von Kernel der von Ihnen verwendete Linux-Kernel ist und auf welchen Einstellungen er ausgeführt wird. Der Linux-Kernel wird für verschiedene Zwecke verwendet. Selbst wenn Sie den Linux-Kernel auf den Punkt bringen, ist der Vorgang daher je nach System völlig unterschiedlich. Wir hoffen, dass Sie durch das Wissen, wie Sie die aktuelle Situation verstehen, den Code des Kernels effizient lesen und bessere Einstellungen finden können.

Kommentare sind ebenfalls willkommen. Bei Fragen können Sie sich gerne an uns wenden.

--Was in diesem Artikel zu schreiben

--Was nicht in diesem Artikel zu schreiben --Einstellungen für jeden Prozess, jeden Benutzer usw. (ulimit, nice, quotactl usw.) --Benutzerplatzeinstellungen (wie "sysconf" und "pathconf") --Einstellungen für den Treiber (Parameter zum Zeitpunkt des Insmods usw.)

Die folgenden 6 Punkte werden vorgestellt. Jeder Artikel ist unabhängig. Bitte sehen Sie, von wo aus Sie interessiert sind.

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

Kernel Version

Lassen Sie uns zunächst sehen, welche Version des Kernels verwendet wird. Wenn Sie die Version kennen, können Sie sie als Grundlage für die Untersuchung verwenden, ob eine bestimmte Funktion oder Änderung enthalten ist.

So überprüfen Sie die Kernel-Version uname -r

Sie können die laufende Kernel-Version erhalten, indem Sie den Befehl uname -r ausführen. Nachfolgend finden Sie die Ergebnisse bei Verwendung eines einfachen Linux-Kernels 5.3.10.

$ uname -r
5.3.10

Je nach Umgebung kann es vorkommen, dass beim Ausführen von "uname -r" nach den oben genannten drei Zahlen stecken bleibt. Das folgende ist beispielsweise das Ausführungsergebnis unter Ubuntu 19.10.

$ uname  -r
5.3.0-19-generic

In diesem Fall handelt es sich um einen Kernel, der für Ubuntu 19.10 basierend auf dem Linux-Kernel der Version 5.3.0 modifiziert wurde. Welche Art von Korrekturen vorgenommen wurden, sollte irgendwo veröffentlicht werden. Für Ubuntu Quellcode-Paket und diff /primary/+sourcefiles/linux/5.3.0-19.20/linux_5.3.0-19.20.diff.gz) wird verteilt.

Die Bedeutung der Zeichenfolge (19-generic) nach der Version ist für jede Distribution unterschiedlich. Für Ubuntu wird es in [hier] erklärt (https://wiki.ubuntu.com/Kernel/FAQ#Kernel.2FFAQ.2FGeneralVersionMeaning.What_does_a_specific_Ubuntu_kernel_version_number_mean.3F).

Es gibt viele andere Möglichkeiten, die Version zu überprüfen, und es gibt einen ausführlichen Artikel in hier. Der Inhalt des Befehls "uname" wird in Tag 1 des Linux-Adventskalenders 2019 ausführlich erläutert. Bitte schauen Sie auch dort nach.

Referenzseite zur Kernel-Version

CPU Architecture

Als nächstes überprüfen wir, für welche CPU der Kernel gebaut wurde.

Im Kontext des Linux-Kernels wird "für welche CPU" häufig als Architektur oder Bogen ausgedrückt. Architektur wird auf viele Arten verwendet, aber hier ist es die ISA (Befehlssatzarchitektur) der CPU. Zum Beispiel "x86_64" und "Arm".

Es gibt möglicherweise nicht viele Fälle, in denen Sie die CPU-Architektur nicht kennen, wenn Sie den Kernel kennen. Tatsächlich gibt es jedoch Zeiten, in denen ein überraschender Kernel für Architektur funktioniert. Lassen Sie es uns für alle Fälle überprüfen.

So überprüfen Sie die CPU-Architektur uname -m oder arch

Zu den Befehlen zum Überprüfen der CPU-Architektur gehören "uname -m" und "arch". Beide Befehle werden in einem Paket namens "coreutils" bereitgestellt. Die Implementierung ist üblich, sodass Sie verwenden können, was Sie möchten.

Im Falle eines PCs (Ubuntu 18.04) wird es als "x86_64" angezeigt.

$ uname -m
x86_64

Wenn ich es mit Raspberry Pi 3 Model B + (Raspbian) versuche, steht dort "armv7l".

$ uname -m
armv7l

Tatsächlich ist der Raspberry Pi 3 Model B + mit einer 64-Bit-ARM-CPU namens Cortex-A53 ausgestattet. Wenn ja, denke ich, dass der Kernel für 64bit funktioniert, aber in diesem Fall sollte er als "aarch64" angezeigt werden. Mit anderen Worten, in Raspbian arbeitet der für 32-Bit erstellte Kernel im 32-Bit-kompatiblen Modus. (Ich denke, wahrscheinlich, weil es mit 32-Bit-CPU-Modellen wie RasPi2 und RasPi Zero geteilt wird)

Kernel arch Verzeichnis

Nachdem ich die CPU-Architektur bestätigt habe, verwende ich diesmal die Verarbeitung der CPU-Architektur Mal sehen, wo es sich im Kernel-Quellcode befindet.

Betrachten Sie den Kernel-Quellcode im Verzeichnis arch / Sie können sehen, dass es für jede CPU-Architektur ein Verzeichnis gibt.

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

Der Verzeichnisname ist eine geringfügige Ersetzung des Ergebnisses des zuvor eingeführten Befehls "uname -m". Das Ersetzen erfolgt in einem Makefile namens "scripts / subarch.include". Wenn Sie beispielsweise einen Kernel für "x86_64" erstellen, wird das Verzeichnis "x86 /" verwendet. In ähnlicher Weise wird für Raspbian'armv7ldas Verzeichnisarm /` verwendet.

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/)

Referenzseite zur CPU-Architektur

Kernel Build Config

Als nächstes kommt die Kernel Build Config. Je nach Person kann es sinnvoller sein, einen Kompilierungsschalter oder "# ifdef" zu sagen. Wenn wir einfach Kernel Config sagen, beziehen wir uns oft darauf.

Wie bereits erwähnt, wird der Linux-Kernel für eine Vielzahl von Zwecken verwendet. Wenn Sie jedoch einen universellen Kernel erstellen, der alles kann, wird die Image-Größe unnötig groß. Daher sparen wir Größe, indem wir nicht verwendete Features von der Kompilierung ausschließen.

Da die Debug-Funktion mit der Kernel-Build-Konfiguration häufig ein- und ausgeschaltet wird, können Sie auch wissen, welche Art von Debug-Funktion verwendet werden kann.

So überprüfen Sie die Kernel Build-Konfiguration 1. / boot / config-X.Y.Z

Abhängig von der Linux-Distribution bleibt es mit dem Kernel-Image unter / boot. In Ubuntu 19.10 wird es beispielsweise in einer Datei namens "/ boot / config-5.3.0-19-generic" gespeichert. Es gibt äquivalente Dateien in CentOS 8 und 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

So überprüfen Sie die Kernel Build-Konfiguration 2. / proc / config.gz

Für Kernel mit aktiviertem CONFIG_IKCONFIG_PROC Sie können die Kernel Build Config in / proc / config.gz überprüfen.

Leider gibt es nicht viel nutzbare Umgebung. Dies ist jedoch eine zuverlässigere Bestätigungsmethode, da der laufende Kernel dies Ihnen mitteilt. Verwenden wir es positiv in einer Umgebung, in der es verwendet werden kann.

Beispielsweise funktioniert der unter Android verwendete Linux-Kernel häufig mit dieser Methode. Das Folgende ist das Ergebnis, wenn es mit dem Emulator von Android 10 bestätigt wird. (Beachten Sie, dass Sie den Befehl zcat verwenden, da er komprimiert ist.) Das / proc / config.gz wurde auch auf dem Samsung Galaxy Note8 (Android 9) aktiviert.

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

Was sind die Elemente in Kernel Build Config?

Es ist in einer Datei namens "Kconfig" definiert, die im Kernel-Quellcode enthalten ist. Dort werden auch Abhängigkeiten und Erläuterungen zu den einzelnen Elementen beschrieben.

Wenn Sie make xconfig ausführen, können Sie die Liste sehen, während Sie sich die Erläuterungen zu den einzelnen Einstellungselementen ansehen. Daher wird dies empfohlen.

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

Sie können auch mit Strg-f suchen.

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

Hier sind nur einige der am häufigsten verwendeten Artikel.

So ändern Sie die Kernel Build-Konfiguration

Um die Kernel Build Config zu ändern, müssen Sie den Kernel neu erstellen.

Die allgemeine Änderungsmethode besteht darin, den Kernel durch Bearbeiten mit "make menuconfig" oder "make xconfig" basierend auf der aktuellen ".config", die mit der obigen Methode erhalten wurde, neu zu erstellen.

.Config ist jedoch eine vom Build generierte Datei und sollte von der Quellcodeverwaltung ausgeschlossen werden. Nachdem Sie die gewünschte ".config" mit "make menu config" erstellt haben, stellen Sie sicher, dass Sie die "defconfig" -Ausgabe mit "make saved efconfig" festschreiben. make savedefconfig gibt die minimale Konfiguration aus, um die aktuelle .config neu zu generieren.

Wenn Sie beispielsweise "defconfig" für "arch / x86 / configs / mytest_defconfig" festlegen, können Sie von nun an "make mytest_defconfig" verwenden, damit alle Entwicklungsmitglieder die bearbeitete ".config" generieren können. Ich kann es schaffen


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

Referenzseite von Kernel Build Config

Command-line Parameters

Als nächstes werde ich Befehlszeilenparameter einführen. Befehlszeilenparameter sind Optionen, die beim Starten des Kernels als Argumente angegeben werden. Daher wird es im Allgemeinen vom Bootloader angegeben.

Die bisher eingeführte Kernel-Version, CPU-Architektur und Kernel-Build-Konfiguration wurden zum Zeitpunkt der Kernel-Kompilierung festgelegt. Auf der anderen Seite werden wir hier einen Mechanismus einführen, um die Operation zu ändern, ohne den Kernel selbst zu ändern.

So überprüfen Sie Befehlszeilenparameter 1. / proc / cmdline

Sie können die Befehlszeilenparameter in / proc / cmdline überprüfen.

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

So überprüfen Sie die Befehlszeilenparameter 2. dmesg

Da es auch an "dmesg" ausgegeben wird, kann es auch in der Situation bestätigt werden, in der nur das Protokoll übrig bleibt.

$ 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

Welche Elemente sind in den Befehlszeilenparametern enthalten?

Es gibt Dokumentation für die Einstellungselemente der Befehlszeilenparameter.

Obwohl es ein sehr kleiner Teil ist, werde ich einige als Referenz vorstellen. Es gibt viele andere, lesen Sie also auch die Dokumentation.

Referenzseite für Befehlszeilenparameter

sysctl

Das folgende sysctl ist ein Mechanismus zum Ändern des Kernel-Parameters während der Ausführung. Sie können es jederzeit ändern, nicht nur beim Start wie bei Befehlszeilenparametern.

So überprüfen Sie sysctl 1. sysctl

Sie können die aktuellen Werte aller Parameter überprüfen, indem Sie sysctl -a ausführen. Sie benötigen Root-Rechte, um einige Parameter anzuzeigen.

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

So überprüfen Sie sysctl 2. / proc / sys /

Alle Parameter, die mit sysctl eingestellt werden können, werden als Dateien unter / proc / sys veröffentlicht. Sie können den Parameterwert durch Lesen dieser Datei überprüfen und durch Schreiben ändern. Tatsächlich wird der Befehl sysctl auch intern über / proc / sys überprüft und geändert.

$ 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

Wenn Sie im Voraus wissen möchten, ob es sich um einen änderbaren Parameter handelt oder ob Sie Root-Rechte benötigen, Sie können dies überprüfen, indem Sie die Berechtigungen der Dateien unter "/ proc / sys" überprüfen.

Im Folgenden ist fs.file-max beschreibbar: Sie können sehen, dass fs.file-nr nicht beschreibbar ist. Sie können auch sehen, dass Sie Root-Rechte benötigen, um fs.file-max zu ändern.

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

Welche Art von Gegenständen hat sysctl?

Es gibt auch Dokumentation für Elemente, die mit sysctl festgelegt werden können.

Dies ist auch ein sehr kleiner Teil, aber ich werde vorstellen, welche Art von Gegenständen es als Referenz gibt.

Wie lange ist der in sysctl festgelegte Wert gültig?

Grundsätzlich werden die von sysctl vorgenommenen Einstellungen nur in der globalen Variablen des Kernels gespeichert, sodass sie beim Neustart des Systems vergessen werden.

Der Mechanismus zum dauerhaften Festlegen hängt von der Distribution ab, aber viele Distributionen laden beim Start / etc / sysctl.conf als Standardwert. Dies wird erreicht, indem sysctl --system beim Systemstart über das Init-Skript ausgeführt wird.

Schreiben Sie für Android direkt aus dem initrc-Skript, das den Startvorgang beschreibt, in / proc / sys.

/init.rc


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

Referenzseite von sysctl

Device Tree

Lassen Sie uns abschließend den Gerätebaum überprüfen.

Der Gerätebaum enthält Informationen zur Hardwarekonfiguration. Es wird häufig in eingebetteten Systemen verwendet, die ARM-CPUs verwenden.

In eingebetteten Systemen unterscheiden sich Gerätespeicheradressen, Interruptnummern usw. von System zu System. Durch das Einbetten in den Quellcode des Gerätetreibers sind sie schwer zu lesen und zu warten. Daher ist es üblich, diese Hardwarekonfigurationsinformationen in eine Gerätebaumquelle (".dts" -Datei) zu schreiben, die vom Quellcode unabhängig ist.

Wenn Sie sich die Rangfolge der Anzahl der ".dts" -Dateien nach Bogen in "5.3.10" ansehen, ist arm bei weitem die beste. Als nächstes kommt PowerPC. Es scheint, dass Device Tree ursprünglich für PowerPC entwickelt wurde, daher ist dies wahrscheinlich der Grund.

$ 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

Was passiert dann in der PC-Welt? Es scheint, dass das UEFI-BIOS Hardwareinformationen gemäß dem ACPI-Standard empfängt, aber ich bin mir nicht sicher. Es tut uns leid.

So überprüfen Sie den Gerätebaum / sys / firmware / fdt

Für Systeme, die den Gerätebaum verwenden Es gibt einen Gerätebaum, der in / sys / firmware / fdt in das FDT-Format konvertiert wurde. FDT ist eine Abkürzung für Flattend Device Tree und wird auch als DTB (Device Tree Blob) bezeichnet. Sie können das FDT mit dem Befehl "dtc" (Device Tree Compiler) in eine ".dts" -Datei konvertieren.

Bei eingebetteten Systemen ist es auch möglich, "/ sys / firmware / fdt" auf einen PC zu übertragen und dann auf dem PC in ".dts" zu konvertieren. Unter / proc / device-tree gibt es auch einen Gerätebaum, der auf das Dateisystem erweitert wurde, aber ich denke`` / sys / firmware / fdt` ist bequemer, weil es einfacher zu handhaben ist.

Das Folgende ist das Bestätigungsergebnis von Device Tree auf 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 >;

Welche Art von Gegenständen gibt es im Gerätebaum?

Die Gerätebaumspezifikationen werden hier veröffentlicht [https://www.devicetree.org/specifications/].

Was die tatsächlichen Einstellungen im Gerätebaum bedeuten, hängt jedoch weitgehend von den Zielhardwarespezifikationen und Gerätetreiberspezifikationen ab. Es gibt einige Fälle, in denen es unerwartet verwendet wird. Wenn Sie sich also den Gerätebaum ansehen, überprüfen Sie die Implementierung, die diesen Wert so oft wie möglich verwendet.

Gerätebaum-Referenzseite

abschließend

Vielen Dank für das Lesen bis zum Ende.

Die Einstellungen können das Verhalten des Kernels direkt ändern, daher denke ich, dass dies ein sehr guter Ausgangspunkt für das Lesen des Kernel-Codes ist. Sobald Sie den Namen des Einstellungselements "grep" haben, können Sie die zugehörige Implementierung finden. Vor allem ist es einfach, den Einstellungswert zu ändern und den Vorgang anzuzeigen.

Ich würde mich sehr freuen, wenn dieser Artikel für jemanden hilfreich wäre.

Recommended Posts

Was für ein Kernel ist dieser Kernel?
Was für eine Programmiersprache ist Python?
Was ist die Ursache für den folgenden Fehler?
Was ist ein Namespace?
Was ist Django? .. ..
Was ist dotenv?
Was ist POSIX?
Was ist Linux?
Was ist klass?
Was ist SALOME?
Was ist Linux?
Was ist Python?
Was für ein Buch ist der meistverkaufte "Python Crash Course" der Welt?
Was ist Hyperopt?
Was ist Linux?
Was ist Pyvenv?
Was ist __call__?
Was ist Linux?
Was ist Python?
Dies ist die einzige grundlegende Überprüfung von Python ~ 1 ~
Dies ist die einzige grundlegende Überprüfung von Python ~ 2 ~
Dies ist die einzige grundlegende Überprüfung von Python ~ 3 ~
Was ist die gleiche Rückzahlung von Kapital und Zinsen und die gleiche Rückzahlung von Kapital und Zinsen?
Dies ist ein Beispiel für eine Funktionsanwendung im Datenrahmen.
[Python] Was ist Pipeline ...
Was ist das Calmar-Verhältnis?
Was ist ein Terminal?
[PyTorch Tutorial ①] Was ist PyTorch?
Was ist Hyperparameter-Tuning?
Was ist ein Hacker?
Was ist JSON? .. [Hinweis]
Wofür ist Linux?
Was ist ein Zeiger?
Was ist Ensemble-Lernen?
Was ist TCP / IP?
Was ist ein empfohlener Motor? Zusammenfassung der Typen
Was ist Pythons __init__.py?
Was ist ein Iterator?
Was ist UNIT-V Linux?
[Python] Was ist virtualenv?
Was ist maschinelles Lernen?
Was ist die Standard-TLS-Version des Python-Anforderungsmoduls?
Ich bin auf TensorFlow gestoßen (Was ist außerhalb des GPU-Speichers)?
Was ist Mini Sam oder Mini Max?
Hinweis zur Kernel-Kompilierung
2017.3.6 ~ 3.12 Zusammenfassung unserer Aktivitäten
Was ist eine logistische Regressionsanalyse?
Was ist die Aktivierungsfunktion?
Ist diese Zeichenfolge ein Bruchteil?
Was ist eine Instanzvariable?
Ist das ein Systemhandel?
Was ist ein Entscheidungsbaum?
Was ist ein Kontextwechsel?
Was ist Google Cloud Dataflow?
[DL] Was ist Gewichtsverlust?
[Python] Python und Sicherheit - is Was ist Python?
Was ist ein Superuser?