La unameutilidad 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, machiney 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.
domainnamecampo lo establece eldomainnamecomando, usando lasetdomainnamellamada al sistema. Del mismo modo, elnodenamecampo lo establece elhostnamecomando, utilizando lasethostnamellamada al sistema. (El valornodename/hostnamepuede almacenarse en/etc/nodename.)unamecomando 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.)machinealguna 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 informari686a 32 bits procesados en x86_64). Por cierto,releasetambién se puede personalizar por proceso hasta cierto punto (pruebasetarch i686 --uname-2.6 uname -a).machine,nodenameyreleaseen 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.hes 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éostypepara 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
unamesyscall, 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 -rcon cosas como3.4.1-mytestkernel.No lo entiendo completamente, pero creo que el resto de la información está configurada
Makefiletambién en la línea 944:Para el resto de los datos, la
sys_unamellamada 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
unamellamada 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 tieneutsespacios 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 unamedeberí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á queunamese 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 sumakelí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 -xmuestra 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/setlocalversiona uno que simplemente hace:luego reconstruya los archivos autogenerados:
entonces pude construir el controlador de muestra de Derek Molloy y pude
insmodhacerlo con éxito. aparentemente la advertencia deModule.symversno 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_hEn v4.19, este es el archivo que genera
include/generated/compile.hy contiene varias partes interesantes de/proc/version: https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_hla
#<version>parte proviene del.versionarchivo 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_VERSIONvariable de entorno:la fecha es solo una
datellamada 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