uname
Narzędzie dostaje swoją informację z uname()
funkcji systemowej. Wypełnia strukturę taką jak ta (patrz 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
};
Pochodzi bezpośrednio z działającego jądra. Przypuszczam, wszystkie informacje są zakodowane w nim, z wyjątkiem być może domainname
(i jak się okazuje, również nodename
, machine
i release
patrz komentarze). Łańcuch zwalniający, z uname -r
, można ustawić za pomocą konfiguracji w czasie kompilacji, ale wątpię, czy pole sysname jest w stanie - jest to jądro Linuksa i nie ma żadnego możliwego powodu, aby używać czegoś innego.
Ponieważ jednak jest to oprogramowanie typu open source, można zmienić kod źródłowy i ponownie skompilować jądro, aby użyć dowolnej nazwy systemowej.
domainname
Pole jest ustawione przezdomainname
polecenia, za pomocąsetdomainname
wywołania systemowego. Podobnienodename
pole jest ustawiane przezhostname
polecenie za pomocąsethostname
wywołania systemowego. (Wartośćnodename
/hostname
może być przechowywana w/etc/nodename
.)uname
polecenie otrzymuje informacje z wywołania systemowego. A skąd wywołanie systemowe uzyskuje informacje? (Odpowiedź udzielona przez inne plakaty tutaj: jest mocno zakodowana w jądrze w czasie kompilacji.)machine
zmieniać? Może nie być zakodowany na stałe w jądrze, ponieważ może się dostosować do sprzętu, ale na pewno zostanie ustawiony w czasie uruchamiania i nie zmieni się później. Ale nie: można ustawić na proces (np. Raportowaći686
do wersji 32-bitowej na x86_64). Nawiasem mówiąc,release
można również w pewnym stopniu dostosować do poszczególnych procesów (spróbujsetarch i686 --uname-2.6 uname -a
).machine
,nodename
irelease
do pytania z odniesieniem do komentarzy. Znów pytanie nie dotyczyło wszystkich tych dziedzin.Dane są przechowywane w init / version.c:
Same łańcuchy znajdują się w plikach include / Wygenerowane / Kompilacja. H:
oraz w include / wygenerowane / utsrelease.h:
UTS_SYSNAME może być zdefiniowany w include / linux / uts.h
lub jako #define w makefiles
Na koniec nazwa hosta i nazwa domeny mogą być kontrolowane przez / proc / sys / kernel / {nazwa hosta, nazwa domeny}. Są to według przestrzeni nazw UTS:
źródło
unshare
. Jakoś udało mi się przegapić to polecenie do dziś. Dzięki!include/generated/compile.h
jest generowany przezscripts/mkcompile_h
: unix.stackexchange.com/a/485962/32558Z pomocą Linux Odsyłacze i swojej wzmianki
/proc/sys/kernel/ostype
, że śledzoneostype
do include / linux / sysctl.h , gdzie komentarz mówi, że nazwy są dodawane przez wywołanieregister_sysctl_table
.Więc gdzie jest to nazywane od ? Jednym z nich jest jądro / utsname_sysctl.c , które obejmuje include / linux / uts.h , gdzie znajdujemy:
Tak więc, jak stwierdza dokumentacja jądra :
:-)
źródło
Jak skomentowano w innym miejscu, informacje pochodzą z
uname
syscall, który jest zakodowany na stałe w uruchomionym jądrze.Część wersji jest zwykle ustawiana podczas kompilacji nowego jądra przez Makefile :
kiedy miałem czas na zabawę w kompilowanie jądra, dodawałem tam rzeczy w EXTRAVERSION; które dały ci
uname -r
takie rzeczy jak3.4.1-mytestkernel
.Nie do końca to rozumiem, ale myślę, że reszta informacji znajduje się
Makefile
również w wierszu 944:W przypadku pozostałych danych
sys_uname
syscall jest generowany za pomocą makr (w dość skomplikowany sposób), możesz zacząć od tego miejsca, jeśli czujesz się ryzykowny.Prawdopodobnie najlepszym sposobem na zmianę takich informacji jest napisanie modułu jądra, aby zastąpić
uname
syscall; Nigdy tego nie zrobiłem, ale informacje można znaleźć na tej stronie w punkcie 4.2 (przepraszam, brak bezpośredniego linku). Zauważ jednak, że ten kod odnosi się do dość starego jądra (teraz jądro Linuksa mauts
przestrzenie nazw, cokolwiek mają na myśli), więc prawdopodobnie będziesz musiał je zmienić.źródło
Chociaż nie mogłem znaleźć w źródle niczego, co by to wskazywało, sądzę, że używa on połączenia systemowego uname.
man 2 uname
powinienem ci więcej o tym powiedzieć. W takim przypadku pobieranie informacji bezpośrednio z jądra i ich zmiana prawdopodobnie wymagałoby ponownej kompilacji.
Możesz zmienić plik binarny, aby nie robić nic, co chcesz, po prostu napisz go za pomocą w / e programu, który chcesz. Minusem jest to, że niektóre skrypty polegają na tych wynikach.
źródło
strace uname
, potwierdziuname
to użycie połączenia systemowego.Właściwym sposobem zmiany uname byłaby zmiana nagłówków kompilacji i ponowna kompilacja, jak sugerują inni. Ale nie jestem pewien, dlaczego miałbyś mieć tyle problemów, skoro możesz zrobić coś takiego,
lub nawet
źródło
Odpowiedź Rmano w pewnym stopniu mnie wciągnęła, ale prawdziwą magię łatwiej odkryć, przekazując
Q=
opcję w liniimake
poleceń w katalogu źródłowym jądra. To pozwala zobaczyć szczegóły, z których jeden jest wezwaniem do skryptu:echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)"
. wykonujące ten sam fragment podaje numer wersji jądra,4.4.19-00010-ge5dddbf
. jeśli spojrzysz na skrypt, określa on liczbę z systemu kontroli wersji, a uruchomienie go zbash -x
pokazuje dokładny proces:pokazuje mi to, że jeśli chcę zbudować moduł jądra do pracy z działającym jądrem, mam niewłaściwie oznakowane wydanie i niewłaściwe zatwierdzenie. Muszę to naprawić i zbudować co najmniej DTB (
make dtbs
), aby utworzyć wygenerowane pliki z odpowiednim numerem wersji.okazuje się, że to nie wystarczyło. Musiałem wymienić
scripts/setlocalversion
na taki, który po prostu robi:następnie odbuduj automatycznie wygenerowane pliki:
wtedy mogłem zbudować przykładowy sterownik Dereka Molloya i udało mi się
insmod
to z powodzeniem. najwyraźniej ostrzeżenie oModule.symvers
nieobecności nie miało znaczenia. cały Linux używał do ustalenia, czy moduł będzie działał, był tym ciągiem wersji lokalnej.źródło
scripts/mkcompile_h
W wersji 4.19 jest to plik, który generuje
include/generated/compile.h
i zawiera kilka interesujących części/proc/version
: https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_h#<version>
część pochodzi z.version
pliku na drzewie build, który zostanie zwiększany, gdy związek się dzieje (wymaga pliku / config zmianami), których autoremscripts/link-vmlinux.sh
.Można go zastąpić
KBUILD_BUILD_VERSION
zmienną środowiskową:data jest tylko surowym
date
połączeniem:i podobnie nazwa użytkownika pochodzi od
whoami
(KBUILD_BUILD_USER
) i nazwa hosta odhostname
(KBUILD_BUILD_HOST
)Wydaje się, że wersja kompilatora pochodzi
gcc -v
i nie można jej kontrolować.Oto jak zmienić rzeczową wersję pytania: https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot
źródło