Das uname
Dienstprogramm bezieht seine Informationen aus dem uname()
Systemaufruf. Es füllt eine Struktur wie diese aus (siehe man 2 uname
):
struct utsname {
char sysname[]; /* Operating system name (e.g., "Linux") */
char nodename[]; /* Name within "some implementation-defined
network" */
char release[]; /* Operating system release (e.g., "2.6.28") */
char version[]; /* Operating system version */
char machine[]; /* Hardware identifier */
#ifdef _GNU_SOURCE
char domainname[]; /* NIS or YP domain name */
#endif
};
Dies kommt direkt aus dem laufenden Kernel. Ich würde davon ausgehen , alle Informationen , ist hartcodiert in sie, außer vielleicht domainname
(und wie sich herausstellt, auch nodename
, machine
und release
, siehe Kommentar). Der Release-String von uname -r
kann während der Kompilierung über die Konfiguration festgelegt werden, aber ich bezweifle sehr, dass das Feld sysname dies kann - es ist der Linux-Kernel und es gibt keinen vorstellbaren Grund, etwas anderes zu verwenden.
Da es sich jedoch um Open Source handelt, können Sie den Quellcode ändern und den Kernel neu kompilieren, um den gewünschten Systemnamen zu verwenden.
domainname
Feld wird vomdomainname
Befehl mithilfe dessetdomainname
Systemaufrufs festgelegt. In ähnlicher Weise wird dasnodename
Feld durch denhostname
Befehl unter Verwendung dessethostname
Systemaufrufs festgelegt. (Der Wertnodename
/hostname
kann in gespeichert werden/etc/nodename
.)uname
Befehl bezieht seine Informationen aus einem Systemaufruf. Und woher bezieht der Systemaufruf seine Informationen? (Antwort, bereitgestellt durch andere Poster hier: Es ist zur Kompilierungszeit im Kernel fest codiert.)machine
ändern? Es wird möglicherweise nicht fest in den Kernel codiert, da es sich möglicherweise an die Hardware anpasst. Dann wird es jedoch beim Booten festgelegt und wird sich danach nicht mehr ändern. Aber nein: Sie kann pro Prozess festgelegt werden (z. B. umi686
auf x86_64 verarbeitete 32-Bit-Daten zu melden ). Übrigensrelease
kann auch pro Prozess einigermaßen angepasst werden (trysetarch i686 --uname-2.6 uname -a
).machine
,nodename
undrelease
in die Frage mit einem Verweis auf die Kommentare. Auch hier ging es nicht wirklich um all diese Bereiche.Die Daten sind in init / version.c gespeichert:
Die Zeichenfolgen selbst befinden sich in include / generated / compile.h:
und in include / generated / utsrelease.h:
UTS_SYSNAME kann in include / linux / uts.h definiert werden
oder als #define in makefiles
Schließlich können der Hostname und der Domainname von / proc / sys / kernel / {Hostname, Domainname} gesteuert werden. Dies sind pro UTS-Namespace:
quelle
unshare
. Irgendwie habe ich diesen Befehl bis heute verpasst. Vielen Dank!include/generated/compile.h
wird generiert vonscripts/mkcompile_h
: unix.stackexchange.com/a/485962/32558Mithilfe eines Linux- Querverweises und Ihrer Erwähnung von habe
/proc/sys/kernel/ostype
ich nachverfolgtostype
, dass / linux / sysctl.h hinzugefügt wird , wobei in einem Kommentar angegeben wird, dass Namen durch Aufrufen hinzugefügt werdenregister_sysctl_table
.Also , wo ist die genannte aus ? Ein Ort ist kernel / utsname_sysctl.c , zu dem include / linux / uts.h gehört. Dort finden wir:
Also, wie die Kernel-Dokumentation besagt:
:-)
quelle
Wie an anderer Stelle erwähnt, werden die Informationen mit dem
uname
Syscall geliefert, der im laufenden Kernel fest codiert ist.Der Versionsteil wird normalerweise beim Kompilieren eines neuen Kernels durch das Makefile festgelegt :
Als ich Zeit zum Kompilieren meiner Kernel hatte, habe ich dort in EXTRAVERSION Dinge hinzugefügt. das gab dir
uname -r
mit dingen wie3.4.1-mytestkernel
.Ich verstehe es nicht ganz, aber ich denke, dass der Rest der Informationen in der
Makefile
ebenfalls umliegenden Zeile 944 eingerichtet ist:Für den Rest der Daten wird der
sys_uname
Systemaufruf mithilfe von Makros generiert (auf eine ziemlich verschlungene Weise). Wenn Sie sich abenteuerlustig fühlen , können Sie von hier aus beginnen.Der wahrscheinlich beste Weg, solche Informationen zu ändern, ist das Schreiben eines Kernel-Moduls, um den
uname
Syscall zu überschreiben . Ich habe das nie gemacht, aber Sie finden Informationen auf dieser Seite in Abschnitt 4.2 (Entschuldigung, kein direkter Link). Beachten Sie jedoch, dass sich dieser Code auf einen ziemlich alten Kernel bezieht (jetzt hat der Linux-Kerneluts
Namespaces, was auch immer sie bedeuten), so dass Sie ihn wahrscheinlich sehr oft ändern müssen.quelle
Obwohl ich nichts in der Quelle finden konnte, das dies anzeigt, glaube ich, dass der uname syscall verwendet wird.
man 2 uname
sollte dir mehr darüber erzählen. Wenn dies der Fall ist, werden die Informationen direkt vom Kernel abgerufen, und das Ändern erfordert wahrscheinlich eine Neukompilierung.
Sie können die Binärdatei ändern, damit Sie uname tun können, was Sie wollen. Schreiben Sie einfach mit einem Programm darüber, das Sie möchten. Der Nachteil einiger Skripte ist, dass sie von dieser Ausgabe abhängen.
quelle
strace uname
diesem Fall wird bestätigt, dass deruname
Systemaufruf verwendet wird.Die richtige Möglichkeit, uname zu ändern, besteht darin, die Compile-Header zu ändern und neu zu kompilieren, wie von anderen vorgeschlagen. Aber ich bin nicht sicher, warum Sie so viel Ärger machen wollen, wenn Sie etwas tun können,
oder auch
quelle
Rmano ‚s Antwort hat mich leicht an , aber die wirkliche Magie einfacher , indem man das entdeckt wird
Q=
Option in Ihremmake
Kommandozeile im Kernel - Quellverzeichnis. es können Sie die Details sehen, von denen ein Anruf an ein Skript ist:echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)"
. Wenn Sie dasselbe Snippet ausführen, erhalten Sie die Versionsnummer des Kernels4.4.19-00010-ge5dddbf
. Wenn Sie sich das Skript ansehen, ermittelt es die Nummer aus dem Versionsverwaltungssystem, und wenn Sie es mitbash -x
ausführen, wird der genaue Prozess angezeigt:Das zeigt mir, dass ich, wenn ich ein Kernelmodul für meinen laufenden Kernel erstellen möchte, die Version mit dem falschen Tag und das falsche Commit habe. Ich muss das beheben und mindestens die DTBs (
make dtbs
) erstellen, um die generierten Dateien mit der richtigen Versionsnummer zu erstellen.stellt sich heraus, auch das war nicht genug. Ich musste eine ersetzen
scripts/setlocalversion
, die einfach tut:Erstellen Sie dann die automatisch generierten Dateien neu:
dann konnte ich Derek Molloys Beispieltreiber bauen und konnte
insmod
es erfolgreich. anscheinend spielte die Warnung,Module.symvers
nicht anwesend zu sein, keine Rolle. Alles, was Linux benutzte, um festzustellen, ob das Modul funktionieren würde, war diese localversion-Zeichenfolge.quelle
scripts/mkcompile_h
In Version 4.19 ist dies die Datei, die Folgendes generiert
include/generated/compile.h
und enthält/proc/version
: https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_hDer
#<version>
Teil stammt aus der.version
Datei im Build-Baum, die bei jedem Verbindungsaufbau (erfordert Datei- / Konfigurationsänderungen) um erhöht wirdscripts/link-vmlinux.sh
.Sie kann von der
KBUILD_BUILD_VERSION
Umgebungsvariablen überschrieben werden :Das Datum ist nur ein kurzer
date
Anruf:und in ähnlicher Weise kommt der Benutzername von
whoami
(KBUILD_BUILD_USER
) und der Hostname vonhostname
(KBUILD_BUILD_HOST
)Die Compilerversion stammt von
gcc -v
und kann anscheinend nicht gesteuert werden.Hier ist eine Anleitung zum Ändern der Stuff-Version der Frage: https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot
quelle