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.
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.
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.
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.
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)
arch
VerzeichnisNachdem 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 Verzeichnis
arm /` 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/)
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.
/ 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
/ 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"
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.
Sie können auch mit Strg-f
suchen.
Hier sind nur einige der am häufigsten verwendeten Artikel.
CONFIG_IKCONFIG_PROC
Ermöglicht es Ihnen, die Kernel Build Config über / proc / config.gz
abzurufen.
Es ist leicht zu verstehen, ob Sie Kernel Build Config zuerst aktivieren, wenn Sie damit herumspielen.
CONFIG_DEBUG_INFO
Es wird nun ein Kernel-Image mit Debug-Symbolen generiert.
Erforderlich beim Kernel-Debugging mit gdb
.
CONFIG_FTRACE
Aktiviert eine Funktion namens Ftrace zum Analysieren des Verhaltens des Kernels.
Einführung in Ftrace in Linux - Qiita wird ausführlich erläutert.
CONFIG_KPROBE
Aktivieren Sie Kprobe, einen Mechanismus zum Anwenden von Binär-Patches auf einen laufenden Kernel.
Sie benötigen es auch, um SystemTap zu verwenden, ein Tool, mit dem Kprobe etwas einfacher zu verwenden ist.
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
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.
/ 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
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
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.
loglevel
Sie können die Ebene der Kernel-Protokollausgabe an die Konsole ändern.
Sie wird häufig geändert, wenn Fehler unmittelbar nach dem Start analysiert werden.
log_buf_len
Sie können die Ringpuffergröße des Kernelprotokolls ändern.
Wenn das Protokoll fließt, können Sie das Protokoll anzeigen, indem Sie die Größe erhöhen.
Der Standardwert kann mit "CONFIG_LOG_CPU_MAX_BUF_SHIFT" geändert werden. Wenn Sie ihn jedoch vorübergehend erhöhen möchten, verwenden Sie diesen Wert.
mem
Sie können die vom Kernel verwendete Speichergröße angeben.
Es wird verwendet, wenn eine Situation simuliert wird, in der der Speicher knapp ist oder wenn die Speicherzuordnung verdächtig ist.
ftrace
Aktivieren Sie die Funktion Ftrace, um den Betrieb des Kernels unmittelbar nach dem Start zu analysieren.
Es wird verwendet, um das Verhalten des Kernels unmittelbar nach dem Start zu analysieren.
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.
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:
/ 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
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.
fs.file-max
Sie können die Anzahl der Dateien überprüfen und ändern, die auf dem gesamten System geöffnet werden können.
fs.file-nr
Sie können sehen, wie viele Dateien derzeit geöffnet sind und wie viele Dateien systemweit geöffnet werden können.
Wie bereits erwähnt, ist es schreibgeschützt.
Wenn es beispielsweise "15840 0 3231322" war,
Die Anzahl der aktuell geöffneten Dateien beträgt "15840", und die Anzahl der Dateien, die systemweit geöffnet werden können, beträgt "3231322".
Die "0" in der Mitte ist immer 0, nur aus Kompatibilitätsgründen übrig, also keine Sorge.
Es wird verwendet, um zu überprüfen, ob als System ein fd-Leck aufgetreten ist.
fs.nr_open
Die Anzahl der Dateien, die pro Prozess geöffnet werden können.
In der Realität ist das für jeden Prozess festgelegte "Ulimit" jedoch häufig strenger.
Limits von ulimit
finden Sie in / proc / $ {PID} / limit
.
kernel.print-fatal-signals
Der Wert 1 belässt den Prozessnamen und den Registerwert im Kernelprotokoll, wenn der Prozess abnormal beendet wird.
kernel.core_pattern
Sie können festlegen, wie Coredump verlassen wird, wenn ein Prozess abnormal beendet wird.
Neben dem Umbenennen von Coredump-Dateien können Sie auch zu bestimmten Programmen umleiten.
Linux Effective Coredump --Qiita wird ausführlich erläutert.
vm.drop_caches
Gibt den Kernel-Cache frei, wenn Sie einen Wert schreiben.
Die einzige Änderung an diesem Element besteht darin, dass der gelesene Wert bedeutungslos ist und der Prozess ausgeführt wird, wenn er geschrieben wird.
Befolgen des Verhaltens beim Schreiben in Linux drop_caches --Qiita wird ausführlich erläutert.
Die Dateiberechtigung für dieses Element lautet Lese- / Schreibzugriff, sollte jedoch nur schreibgeschützt sein.
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
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.
/ 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 >;
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.
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