O uname
utilitário obtém suas informações da uname()
chamada do sistema. Ele preenche uma estrutura como esta (consulte 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
};
Isso vem diretamente do kernel em execução. Eu diria que toda a informação é codificado para ele, exceto, talvez domainname
(e como se vê, também nodename
, machine
e release
, veja comentários). A string de lançamento, from uname -r
, pode ser definida via configuração em tempo de compilação, mas duvido muito que o campo sysname possa - é o kernel do Linux e não há razão concebível para usar qualquer outra coisa.
No entanto, como é de código aberto, você pode alterar o código-fonte e recompilar o kernel para usar o nome de sistema que desejar.
domainname
campo é definido pelodomainname
comando, usando asetdomainname
chamada do sistema. Da mesma forma, onodename
campo é definido pelohostname
comando, usando asethostname
chamada do sistema. (Anodename
/hostname
valor pode ser armazenado no/etc/nodename
.)uname
comando obtém suas informações de uma chamada do sistema. E de onde a chamada do sistema obtém suas informações? (Resposta, fornecida por outros pôsteres aqui: ela é codificada no kernel em tempo de compilação.)machine
alguma vez mudaria? Pode não ser codificado no kernel porque pode se adaptar ao hardware, mas certamente será definido no momento da inicialização e não será alterado depois disso. Mas não: pode ser definido por processo (por exemplo, para reportari686
para 32 bits processados em x86_64). A propósito,release
também pode ser personalizado por processo até certo ponto (tentativasetarch i686 --uname-2.6 uname -a
).machine
,nodename
erelease
na pergunta com uma referência aos comentários. Novamente, a questão não era realmente sobre todos esses campos.Os dados são armazenados em init / version.c:
As próprias seqüências de caracteres estão em include / generate / compile.h:
e em incluir / gerado / utsrelease.h:
UTS_SYSNAME pode ser definido em include / linux / uts.h
ou como #define em makefiles
Finalmente, o nome do host e o nome do domínio podem ser controlados por / proc / sys / kernel / {hostname, domainname}. Estes são por espaço de nome UTS:
fonte
unshare
. De alguma forma eu consegui perder esse comando até hoje. Obrigado!include/generated/compile.h
é gerado porscripts/mkcompile_h
: unix.stackexchange.com/a/485962/32558Com a ajuda de uma referência cruzada do Linux e sua menção
/proc/sys/kernel/ostype
, rastreieiostype
para incluir / linux / sysctl.h , onde um comentário diz que os nomes são adicionados por chamadaregister_sysctl_table
.Então, de onde é que isso é chamado ? Um lugar é o kernel / utsname_sysctl.c , que inclui include / linux / uts.h , onde encontramos:
Portanto, como a documentação do kernel afirma:
:-)
fonte
Como comentado em outro lugar, as informações vêm com o
uname
syscall, que é codificado no kernel em execução.A parte da versão é normalmente definida ao compilar um novo kernel pelo Makefile :
quando eu tinha tempo para jogar compilando meus kernels, costumava adicionar coisas lá em EXTRAVERSION; que te deu
uname -r
coisas do tipo3.4.1-mytestkernel
.Eu não o entendo completamente, mas acho que o restante das informações está configurado na
Makefile
linha 944 também:Para o restante dos dados, o
sys_uname
syscall é gerado usando macros (de uma maneira bastante complicada). Você pode começar daqui se sentir aventureiro.Provavelmente, a melhor maneira de alterar essas informações é escrever um módulo do kernel para substituir o
uname
syscall; Eu nunca fiz isso, mas você pode encontrar informações nesta página na seção 4.2 (desculpe, não há link direto). Observe, no entanto, que esse código está se referindo a um kernel bastante antigo (agora o kernel do Linux temuts
espaços de nomes, o que quer que eles significem), portanto você precisará alterá-lo muito provavelmente.fonte
Embora eu não tenha encontrado nada na fonte para indicar isso, acredito que ele use o syscall uname.
man 2 uname
deveria lhe contar mais sobre isso. Se for esse o caso, ele obtém as informações diretamente do kernel e as altera provavelmente exigiria recompilação.
Você pode alterar o binário para que você não faça o que quiser, basta escrever sobre ele com o programa que desejar. A desvantagem é que alguns scripts contam com essa saída.
fonte
strace uname
, confirmará que auname
chamada do sistema é usada.A maneira correta de alterar a uname seria alterar os cabeçalhos de compilação e recompilar como sugerido por outros. Mas não sei por que você gostaria de passar por tantos problemas quando pode fazer algo como,
ou mesmo
fonte
A resposta de Rmano me levou a meio caminho, mas a verdadeira mágica é mais fácil de descobrir, passando a
Q=
opção em suamake
linha de comando no diretório de origem do kernel. ele permite que você veja os detalhes, um dos quais é uma chamada para um script:echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)"
. executar esse mesmo trecho fornece o número da versão do kernel4.4.19-00010-ge5dddbf
,. se você olhar para o script, ele determina o número do sistema de controle de versão e a execuçãobash -x
mostra o processo exato:o que isso me mostra é que, se eu quero construir um módulo do kernel para trabalhar com o meu kernel em execução, estou no release marcado errado e no commit errado. Preciso corrigir isso e criar pelo menos os DTBs (
make dtbs
) para criar os arquivos gerados com o número de versão correto.Acontece que mesmo isso não foi suficiente. Eu tive que substituir
scripts/setlocalversion
por um que simplesmente:em seguida, recrie os arquivos gerados automaticamente:
então eu pude construir o driver de amostra de Derek Molloy e consegui com
insmod
sucesso. aparentemente o aviso sobreModule.symvers
não estar presente não importava. todo o Linux estava usando para determinar se o módulo funcionaria era a string de versão local.fonte
scripts/mkcompile_h
Na v4.19, esse é o arquivo que gera
include/generated/compile.h
e contém várias partes interessantes de/proc/version
: https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_ha
#<version>
parte vem do.version
arquivo na árvore de construção, que é incrementado sempre que o link acontece (requer alterações de arquivo / configuração)scripts/link-vmlinux.sh
.Pode ser substituído pela
KBUILD_BUILD_VERSION
variável de ambiente:a data é apenas uma
date
chamada bruta :e da mesma forma o nome de usuário vem de
whoami
(KBUILD_BUILD_USER
) e o nome de host dehostname
(KBUILD_BUILD_HOST
)A versão do compilador vem
gcc -v
e parece que não pode ser controlada.Aqui está como alterar a versão da questão: https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot
fonte