La uname
utilidad obtiene su información de la uname()
llamada del sistema. Rellena una estructura como esta (ver 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
};
Esto viene directamente del núcleo en ejecución. Yo asumiría toda la información está codificada en él, excepto tal vez domainname
(y como resulta, también nodename
, machine
y release
, ver comentarios). La cadena de lanzamiento, desde uname -r
, se puede establecer a través de la configuración en tiempo de compilación, pero dudo mucho que el campo sysname pueda: es el kernel de Linux y no hay ninguna razón concebible para que use otra cosa.
Sin embargo, dado que es de código abierto, puede cambiar el código fuente y volver a compilar el núcleo para usar el nombre de sistema que desee.
domainname
campo lo establece eldomainname
comando, usando lasetdomainname
llamada al sistema. Del mismo modo, elnodename
campo lo establece elhostname
comando, utilizando lasethostname
llamada al sistema. (El valornodename
/hostname
puede almacenarse en/etc/nodename
.)uname
comando obtiene su información de una llamada al sistema. ¿Y de dónde obtiene su información la llamada del sistema? (Respuesta, proporcionada por otros carteles aquí: está codificado en el núcleo en el momento de la compilación.)machine
alguna vez cambiaría? Es posible que no esté codificado en el núcleo porque podría adaptarse al hardware, pero seguramente se establecería en el momento del arranque y no cambiaría después de eso. Pero no: se puede configurar por proceso (por ejemplo, para informari686
a 32 bits procesados en x86_64). Por cierto,release
también se puede personalizar por proceso hasta cierto punto (pruebasetarch i686 --uname-2.6 uname -a
).machine
,nodename
yrelease
en la pregunta con una referencia a los comentarios. Nuevamente, la pregunta no era realmente sobre todos esos campos.Los datos se almacenan en init / version.c:
Las cadenas en sí están en include / generate / compile.h:
y en incluir / generado / utsrelease.h:
UTS_SYSNAME puede definirse en include / linux / uts.h
o como un #define en makefiles
Finalmente, el nombre de host y el nombre de dominio pueden ser controlados por / proc / sys / kernel / {hostname, domainname}. Estos son por espacio de nombres UTS:
fuente
unshare
. De alguna manera me las arreglé para perder este comando hasta hoy. ¡Gracias!include/generated/compile.h
es generado porscripts/mkcompile_h
: unix.stackexchange.com/a/485962/32558Con la ayuda de una referencia cruzada de Linux y su mención de
/proc/sys/kernel/ostype
, rastreéostype
para incluir / linux / sysctl.h , donde un comentario dice que los nombres se agregan al llamarregister_sysctl_table
.Entonces, ¿de dónde se llama eso ? Un lugar es kernel / utsname_sysctl.c , que incluye include / linux / uts.h , donde encontramos:
Entonces, como dice la documentación del kernel :
:-)
fuente
Como se comentó en otra parte, la información viene con
uname
syscall, que está codificada en el núcleo en ejecución.La parte de la versión normalmente se establece cuando el Makefile compila un nuevo núcleo :
cuando tenía tiempo para jugar a compilar mis núcleos, solía agregar cosas allí en EXTRAVERSIÓN; que dio
uname -r
con cosas como3.4.1-mytestkernel
.No lo entiendo completamente, pero creo que el resto de la información está configurada
Makefile
también en la línea 944:Para el resto de los datos, la
sys_uname
llamada al sistema se genera utilizando macros (de una manera bastante complicada), puede comenzar desde aquí si se siente aventurero.Probablemente la mejor manera de cambiar dicha información es escribir un módulo del núcleo para anular la
uname
llamada al sistema; Nunca hice eso, pero puedes encontrar información en esta página en la sección 4.2 (lo siento, no hay enlace directo). Sin embargo, tenga en cuenta que ese código se refiere a un kernel bastante antiguo (ahora el kernel de Linux tieneuts
espacios de nombres, lo que sea que signifiquen), por lo que probablemente tendrá que cambiarlo mucho.fuente
Si bien no pude encontrar nada en la fuente para indicar esto, creo que utiliza el syscall de uname.
man 2 uname
debería contarte más al respecto. Si ese es el caso, es obtener la información directamente del núcleo y cambiarla probablemente requerirá una nueva recopilación.
Sin embargo, puede cambiar el binario para que usted no haga lo que quiera, simplemente escriba sobre él con el programa que desee. La desventaja es que algunos scripts dependen de esa salida.
fuente
strace uname
, confirmará queuname
se utiliza la llamada al sistema.La forma correcta de cambiar uname sería cambiar los encabezados de compilación y volver a compilar como otros sugirieron. Pero no estoy seguro de por qué querrías pasar por tantos problemas cuando puedes hacer algo como,
o incluso
fuente
La respuesta de Rmano me llevó a la mitad, pero la verdadera magia se descubre más fácilmente al pasar la
Q=
opción en sumake
línea de comandos en el directorio de origen del núcleo. que le permite ver los detalles, uno de los cuales es una llamada a un script:echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)"
. la ejecución de ese mismo fragmento da el número de versión del kernel,4.4.19-00010-ge5dddbf
. Si observa el script, determina el número del sistema de versiones y al ejecutarlo sebash -x
muestra el proceso exacto:lo que esto me muestra es que si quiero construir un módulo de kernel para que funcione con mi kernel en ejecución, estoy en la versión etiquetada y la confirmación incorrecta. Necesito arreglar eso y construir al menos los DTB (
make dtbs
) para crear los archivos generados con el número de versión correcto.Resulta que incluso eso no fue suficiente. Tuve que reemplazar
scripts/setlocalversion
a uno que simplemente hace:luego reconstruya los archivos autogenerados:
entonces pude construir el controlador de muestra de Derek Molloy y pude
insmod
hacerlo con éxito. aparentemente la advertencia deModule.symvers
no estar presente no importó. todo Linux estaba usando para determinar si el módulo funcionaría era esa cadena de versión local.fuente
scripts/mkcompile_h
En v4.19, este es el archivo que genera
include/generated/compile.h
y contiene varias partes interesantes de/proc/version
: https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_hla
#<version>
parte proviene del.version
archivo en el árbol de compilación, que se incrementa cada vez que ocurre el enlace (requiere cambios de archivo / configuración)scripts/link-vmlinux.sh
.Puede ser anulado por la
KBUILD_BUILD_VERSION
variable de entorno:la fecha es solo una
date
llamada cruda :y de manera similar, el nombre de usuario proviene de
whoami
(KBUILD_BUILD_USER
) y el nombre de host dehostname
(KBUILD_BUILD_HOST
)La versión del compilador proviene de
gcc -v
, y parece que no se puede controlar.Aquí hay una forma de cambiar la versión de la pregunta: https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot
fuente