Woher bezieht uname seine Informationen?

Woher bezieht uname seine Informationen?

Woher bezieht uname seine Informationen wirklich?

Ich denke, das sollte ganz unkompliziert sein. Leider kann ich keinen Header finden, der genau diese Informationen enthält.

unameAngenommen, jemand möchte die grundlegende Ausgabe von / uname -s in Linuxetwas anderes ändern (im Wesentlichen den Kernel umbenennen).

Wie würde er/sie das richtig machen (also die Quelle ändern)?

Antwort1

Die Daten werden in init/version.c gespeichert:

struct uts_namespace init_uts_ns = {
        .kref = {
                .refcount       = ATOMIC_INIT(2),
        },
        .name = {
                .sysname        = UTS_SYSNAME,
                .nodename       = UTS_NODENAME,
                .release        = UTS_RELEASE,
                .version        = UTS_VERSION,
                .machine        = UTS_MACHINE,
                .domainname     = UTS_DOMAINNAME,
        },
        .user_ns = &init_user_ns,
        .proc_inum = PROC_UTS_INIT_INO,
};
EXPORT_SYMBOL_GPL(init_uts_ns);

Die Strings selbst stehen in include/generated/compile.h:

#define UTS_MACHINE "x86_64"
#define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"

und in include/generated/utsrelease.h:

#define UTS_RELEASE "3.14.0-v2-v"

UTS_SYSNAME kann in include/linux/uts.h definiert werden.

#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif

oder als #define in Makefiles

Schließlich können der Hostname und der Domänenname über /proc/sys/kernel/{hostname,domainname} gesteuert werden. Diese sind pro UTS-Namespace:

# hostname
hell
# unshare --uts /bin/bash
# echo test > /proc/sys/kernel/hostname 
# hostname
test
# exit
# hostname
hell

Antwort2

Das unameDienstprogramm erhält seine Informationen aus dem uname()Systemaufruf. Es füllt eine Struktur wie diese (sieheman 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 vom laufenden Kernel. Ich würde annehmen, dass alle Informationen darin fest codiert sind, außer vielleicht domainname(und wie sich herausstellt, auch nodename, machine, und release, siehe Kommentare). Die Release-Zeichenfolge von uname -rkann 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, warum er etwas anderes verwenden sollte.

Da es sich jedoch um Open Source handelt, können Sie den Quellcode ändern und den Kernel neu kompilieren, um jeden gewünschten Systemnamen zu verwenden.

Antwort3

Mit Hilfe einesLinux-Querverweisund Ihre Erwähnung von /proc/sys/kernel/ostype, ich verfolgte ostypezuinclude/linux/sysctl.h, wobei ein Kommentar besagt, dass Namen durch den Aufruf hinzugefügt werden register_sysctl_table.

Also, wo ist dasangerufen von? Ein Ort istkernel/utsname_sysctl.c, welches beinhaltetinclude/linux/uts.h, wo wir finden:

/*
 * Defines for what uname() should return 
 */
#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif

Als dieKernel-DokumentationZustände:

Die einzige Möglichkeit, diese Werte anzupassen, besteht darin, den Kernel neu zu erstellen

:-)

Antwort4

scripts/mkcompile_h

In v4.19 ist dies die Datei include/generated/compile.h, die generiert und mehrere interessante Teile von enthält /proc/version:https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_h

  • Der #<version>Teil stammt aus der .versionDatei im Build-Baum, die bei jeder Verknüpfung (Datei-/Konfigurationsänderungen erforderlich) um erhöht wird scripts/link-vmlinux.sh.

    KBUILD_BUILD_VERSIONEs kann durch die Umgebungsvariable überschrieben werden :

    if [ -z "$KBUILD_BUILD_VERSION" ]; then
        VERSION=$(cat .version 2>/dev/null || echo 1)
    else
        VERSION=$KBUILD_BUILD_VERSION
    fi
    
  • das Datum ist nur eine grobe dateSchätzung:

    if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then
        TIMESTAMP=`date`
    else
        TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
    fi
    

    und ebenso kommt der Benutzername von whoami( KBUILD_BUILD_USER) und der Hostname von hostname( KBUILD_BUILD_HOST)

  • Die Compilerversion stammt von gcc -vund kann anscheinend nicht gesteuert werden.

Hier ist eine Version der Frage zum Ändern von Inhalten:https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot

verwandte Informationen