The uname
utilitas mendapat informasinya dari uname()
system call. Ini mengisi struct seperti ini (lihat 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
};
Ini datang langsung dari kernel yang sedang berjalan. Saya akan menganggap semua informasi yang sulit-kode ke dalamnya, kecuali mungkin domainname
(dan ternyata, juga nodename
, machine
dan release
, lihat komentar). Rilis string, dari uname -r
, dapat diatur melalui konfigurasi pada waktu kompilasi, tapi saya sangat meragukan bidang sysname bisa - itu adalah kernel Linux dan tidak ada alasan yang memungkinkan untuk menggunakan hal lain.
Namun, karena ini adalah open source, Anda dapat mengubah kode sumber dan mengkompilasi ulang kernel untuk menggunakan sysname apa pun yang Anda inginkan.
domainname
lapangan set olehdomainname
perintah, menggunakansetdomainname
system call. Demikian pula,nodename
bidang diatur olehhostname
perintah, menggunakansethostname
system call. (Nilainodename
/hostname
dapat disimpan dalam/etc/nodename
.)uname
perintah mendapatkan informasinya dari panggilan sistem. Dan dari mana panggilan sistem mendapatkan informasinya? (Jawab, disediakan oleh poster-poster lain di sini: hard-coded di kernel pada waktu kompilasi.)machine
pernah berubah? Ini mungkin tidak di-hardcode ke dalam kernel karena mungkin beradaptasi dengan perangkat keras, tetapi pasti itu akan diatur pada saat boot dan tidak akan berubah setelah itu. Tapi tidak: itu bisa disetel per proses (misalnya untuk melapori686
ke 32-bit yang diproses pada x86_64). Ngomong-ngomong,release
bisa juga dikustomisasi per proses sampai batas tertentu (cobasetarch i686 --uname-2.6 uname -a
).machine
,,nodename
danrelease
ke pertanyaan dengan referensi ke komentar. Sekali lagi, pertanyaannya sebenarnya bukan tentang semua bidang itu.Data disimpan di init / version.c:
String-nya sendiri di include / generate / compile.h:
dan di include / generate / utsrelease.h:
UTS_SYSNAME dapat didefinisikan di include / linux / uts.h
atau sebagai #define di makefiles
Akhirnya, nama host dan nama domain dapat dikontrol oleh / proc / sys / kernel / {hostname, domainname}. Ini adalah per namespace UTS:
sumber
unshare
. Entah bagaimana saya berhasil melewatkan perintah ini sampai hari ini. Terima kasih!include/generated/compile.h
dihasilkan olehscripts/mkcompile_h
: unix.stackexchange.com/a/485962/32558Dengan bantuan Linux Cross Reference dan penyebutan Anda
/proc/sys/kernel/ostype
, saya melacakostype
untuk memasukkan / linux / sysctl.h , di mana komentar mengatakan bahwa nama ditambahkan dengan memanggilregister_sysctl_table
.Jadi dari mana asalnya ? Satu tempat adalah kernel / utsname_sysctl.c , yang meliputi include / linux / uts.h , tempat kami menemukan:
Jadi, sebagaimana dinyatakan oleh dokumentasi kernel :
:-)
sumber
Seperti dikomentari di tempat lain, informasi tersebut datang dengan
uname
syscall, yang informasinya di-hard-coded di kernel yang sedang berjalan.Bagian versi biasanya diatur ketika mengkompilasi kernel baru oleh Makefile :
ketika saya punya waktu untuk bermain mengkompilasi kernel saya, saya biasa menambahkan hal-hal di sana dalam EXTRAVERSION; yang memberi Anda
uname -r
hal-hal seperti3.4.1-mytestkernel
.Saya tidak sepenuhnya memahaminya, tetapi saya berpikir bahwa sisa informasi tersebut diatur dalam
Makefile
juga sekitar baris 944:Untuk sisa data,
sys_uname
syscall dihasilkan menggunakan makro (dengan cara yang cukup berbelit-belit), Anda bisa mulai dari sini jika Anda ingin bertualang.Mungkin cara terbaik untuk mengubah informasi tersebut adalah menulis modul kernel untuk mengganti
uname
syscall; Saya tidak pernah melakukan itu tetapi Anda dapat menemukan info di halaman ini di bagian 4.2 (maaf, tidak ada tautan langsung). Namun perhatikan bahwa kode tersebut merujuk ke kernel yang cukup lama (sekarang kernel Linux memilikiuts
ruang nama, apa pun artinya) sehingga Anda harus sering mengubahnya.sumber
Meskipun saya tidak dapat menemukan apa pun di sumber untuk menunjukkan ini, saya percaya itu menggunakan syscall yang tidak sama.
man 2 uname
harus memberi tahu Anda lebih banyak tentang hal itu. Jika itu masalahnya, ia mendapatkan informasi langsung dari kernel dan mengubahnya mungkin memerlukan kompilasi ulang.
Anda dapat mengubah biner agar Anda tidak dapat melakukan apa pun yang Anda inginkan, cukup tulis saja dengan program w / e yang Anda inginkan. Kelemahannya adalah beberapa skrip mengandalkan output itu.
sumber
strace uname
, itu akan mengkonfirmasi bahwauname
panggilan sistem digunakan.Cara yang tepat untuk mengubah uname adalah dengan mengubah header kompilasi dan mengkompilasi ulang seperti yang disarankan orang lain. Tapi saya tidak yakin mengapa Anda ingin melalui banyak masalah ketika Anda bisa melakukan sesuatu seperti,
atau bahkan
sumber
Jawaban Rmano membuat saya setengah jalan, tetapi keajaiban sebenarnya lebih mudah ditemukan dengan melewatkan
Q=
opsi dimake
commandline Anda di direktori source kernel. itu memungkinkan Anda melihat rincian, salah satunya adalah panggilan untuk script:echo "4.4.19$(/bin/sh ./scripts/setlocalversion .)"
. mengeksekusi snippet yang sama memberikan nomor rilis kernel4.4.19-00010-ge5dddbf
,. jika Anda melihat skrip, ia menentukan angka dari sistem versi, dan menjalankannya denganbash -x
menunjukkan proses yang tepat:Ini menunjukkan kepada saya bahwa jika saya ingin membangun modul kernel untuk bekerja dengan kernel saya yang sedang berjalan, saya berada pada rilis yang salah ditandai dan komit yang salah. Saya perlu memperbaikinya, dan membangun setidaknya DTB (
make dtbs
) untuk membuat file yang dihasilkan dengan nomor versi yang tepat.Ternyata, bahkan itu tidak cukup. Saya harus mengganti
scripts/setlocalversion
dengan yang sederhana:lalu buat kembali file yang di-autogenerasi:
maka saya bisa membangun driver sampel Derek Molloy dan
insmod
berhasil. rupanya peringatan tentangModule.symvers
tidak hadir tidak masalah. semua Linux menggunakan untuk menentukan apakah modul akan bekerja adalah string versi lokal itu.sumber
scripts/mkcompile_h
Di v4.19, ini adalah file yang menghasilkan
include/generated/compile.h
, dan berisi beberapa bagian menarik/proc/version
: https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_hyang
#<version>
bagian berasal dari.version
file di pohon membangun, yang akan bertambah setiap kali link yang terjadi (membutuhkan file / config perubahan) olehscripts/link-vmlinux.sh
.Itu dapat ditimpa oleh
KBUILD_BUILD_VERSION
variabel lingkungan:tanggalnya hanyalah
date
panggilan biasa:dan juga nama pengguna berasal dari
whoami
(KBUILD_BUILD_USER
) dan nama host darihostname
(KBUILD_BUILD_HOST
)Versi kompiler berasal dari
gcc -v
, dan sepertinya tidak bisa dikontrol.Berikut adalah cara mengubah versi barang dari pertanyaan: https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot
sumber