L' uname
utilitaire tire ses informations de l' uname()
appel système. Il remplit une structure comme celle-ci (voir 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
};
Cela vient directement du noyau en cours d'exécution. Je suppose que toutes les informations sont codées en dur en elle, sauf peut - être domainname
(et il se trouve, aussi nodename
, machine
et release
, voir les commentaires). La chaîne de publication, à partir de uname -r
, peut être définie via la configuration lors de la compilation, mais je doute fort que le champ sysname le puisse - il s’agit du noyau Linux et il n’ya aucune raison concevable d’utiliser autre chose.
Cependant, comme il est open source, vous pouvez changer le code source et recompiler le noyau pour utiliser le sysname de votre choix.
domainname
champ est défini par ladomainname
commande, à l'aide de l'setdomainname
appel système. De même, lenodename
champ est défini par lahostname
commande, à l'aide de l'sethostname
appel système. (Lanodename
/hostname
valeur peut être stockée dans/etc/nodename
.)uname
commande tire ses informations d'un appel système. Et où l'appel système obtient-il ses informations? (Réponse, fournie par d'autres affiches ici: c'est codé en dur dans le noyau au moment de la compilation.)machine
jamais? Il se peut qu'il ne soit pas codé en dur dans le noyau, car il s'adapte au matériel, mais il sera sûrement défini au moment du démarrage et ne changera pas par la suite. Mais non: il peut être défini par processus (par exemple, pour générer un rapporti686
sur 32 bits traité sur x86_64). Par ailleurs,release
peut également être personnalisé par processus dans une certaine mesure (essayersetarch i686 --uname-2.6 uname -a
).machine
,nodename
etrelease
dans la question avec une référence aux commentaires. Encore une fois, la question ne concernait pas tous ces domaines.Les données sont stockées dans init / version.c:
Les chaînes elles-mêmes sont dans include / created / compile.h:
et dans include / généré / utsrelease.h:
UTS_SYSNAME peut être défini dans include / linux / uts.h
ou en tant que #define dans les makefiles
Enfin, le nom d’hôte et le nom de domaine peuvent être contrôlés par / proc / sys / kernel / {nom d’hôte, nom de domaine}. Ce sont par espace de noms UTS:
la source
unshare
. D'une manière ou d'une autre, j'ai réussi à rater cette commande jusqu'à aujourd'hui. Merci!include/generated/compile.h
est généré parscripts/mkcompile_h
: unix.stackexchange.com/a/485962/32558Avec l’aide d’une référence croisée Linux et de votre mention
/proc/sys/kernel/ostype
, j’ai choisiostype
d’ inclure / linux / sysctl.h , où un commentaire indique que les noms sont ajoutés par appelregister_sysctl_table
.Alors, d'où est-ce que cela s'appelle ? Le noyau / utsname_sysctl.c , qui inclut include / linux / uts.h , est l’un des emplacements suivants:
Ainsi, comme l' indique la documentation du noyau :
:-)
la source
Comme indiqué ailleurs, les informations sont fournies avec l'
uname
appel système, lequel est codé en dur dans le noyau en cours d'exécution.La partie version est normalement définie lors de la compilation d’un nouveau noyau par le Makefile :
quand j'avais le temps de jouer à la compilation de mes noyaux, j'y ajoutais des choses là-bas dans EXTRAVERSION; cela vous a donné des
uname -r
choses comme3.4.1-mytestkernel
.Je ne comprends pas tout à fait cela, mais je pense que le reste de l’information se trouve
Makefile
également dans la ligne 944:Pour le reste des données, l'
sys_uname
appel système est généré à l'aide de macros (d'une manière assez compliquée), vous pouvez commencer à partir d' ici si vous vous sentez aventureux.Le meilleur moyen de modifier de telles informations consiste probablement à écrire un module de noyau pour remplacer le
uname
syscall. Je n'ai jamais fait cela, mais vous pouvez trouver des informations sur cette page à la section 4.2 (désolé, pas de lien direct). Notez cependant que ce code fait référence à un noyau assez ancien (maintenant le noyau Linux a desuts
espaces de noms, peu importe leur signification), vous devrez donc probablement le modifier beaucoup.la source
Bien que je n’aie rien trouvé dans la source qui indique cela, je pense qu’il utilise le syscall uname.
man 2 uname
devrait vous en dire plus à ce sujet. Si tel est le cas, obtenir les informations directement du noyau et les modifier nécessiteraient probablement une recompilation.
Vous pouvez changer le fichier binaire pour que vous puissiez faire ce que vous voulez, écrivez dessus avec le programme qui vous convient. L'inconvénient étant que certains scripts reposent sur cette sortie.
la source
strace uname
, cela confirmera que l'uname
appel système est utilisé.Une façon correcte de changer uname serait de changer les en-têtes de compilation et de les recompiler comme le suggèrent les autres. Mais je ne suis pas sûr de savoir pourquoi vous voudriez traverser autant de problèmes quand vous pouvez faire quelque chose comme:
ou même
la source
La réponse de Rmano m'a convaincu, mais la vraie magie est plus facile à découvrir en passant l'
Q=
option dans votremake
ligne de commande dans le répertoire source du noyau. il vous permet de voir les détails, dont l'un est un appel à un script:echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)"
. l' exécution de ce même extrait donne le numéro de version du noyau,4.4.19-00010-ge5dddbf
. si vous regardez le script, il détermine le numéro à partir du système de gestion de versions, et son exécution avecbash -x
indique le processus exact:Cela me montre que si je veux construire un module de noyau pour fonctionner avec mon noyau en cours d’exécution, je ne suis pas sur la bonne version étiquetée ni sur la validation. Je dois résoudre ce problème et créer au moins les DTB (
make dtbs
) afin de créer les fichiers générés avec le bon numéro de version.s'avère que même cela ne suffisait pas. Je devais remplacer
scripts/setlocalversion
à celui qui fait simplement:puis reconstruisez les fichiers générés automatiquement:
alors je pouvais construire le pilote exemple de Derek Molloy et je pouvais le faire
insmod
avec succès. apparemment, l'avertissement deModule.symvers
ne pas être présent importait peu. tout ce que Linux utilisait pour déterminer si le module fonctionnerait était cette chaîne de version locale.la source
scripts/mkcompile_h
Dans la v4.19, il s’agit du fichier qui génère
include/generated/compile.h
et contient plusieurs parties intéressantes de/proc/version
: https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_hla
#<version>
partie provient du.version
fichier sur l'arbre de construction, qui est incrémenté chaque fois qu'un lien se produit (nécessite des modifications de fichier / config) descripts/link-vmlinux.sh
.Il peut être remplacé par la
KBUILD_BUILD_VERSION
variable d'environnement:la date est juste un
date
appel brut :et de même le nom d'utilisateur vient de
whoami
(KBUILD_BUILD_USER
) et le nom d'hôte dehostname
(KBUILD_BUILD_HOST
)La version du compilateur provient de
gcc -v
, et ne semble pas pouvoir être contrôlée.Voici comment changer la version de la question: https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot
la source