
uname 真正從哪裡獲取資訊?
我認為這應該是直截了當的事情。不幸的是,我找不到任何包含該資訊的標題。
uname
假設有人想將/的基本輸出更改uname -s
為Linux
其他內容(本質上是重命名內核)。
他/她將如何以正確的方式做到這一點(即更改來源)?
答案1
資料儲存在init/version.c:
struct uts_namespace init_uts_ns = {
.kref = {
.refcount = ATOMIC_INIT(2),
},
.name = {
.sysname = UTS_SYSNAME,
.nodename = UTS_NODENAME,
.release = UTS_RELEASE,
.version = UTS_VERSION,
.machine = UTS_MACHINE,
.domainname = UTS_DOMAINNAME,
},
.user_ns = &init_user_ns,
.proc_inum = PROC_UTS_INIT_INO,
};
EXPORT_SYMBOL_GPL(init_uts_ns);
字串本身位於 include/ generated/compile.h 中:
#define UTS_MACHINE "x86_64"
#define UTS_VERSION "#30 SMP Fri Apr 11 00:24:23 BST 2014"
並在 include/ generated/utsrelease.h:
#define UTS_RELEASE "3.14.0-v2-v"
UTS_SYSNAME 可以在 include/linux/uts.h 中定義
#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif
或作為 makefile 中的 #define
最後,主機名稱和網域名稱可以透過/proc/sys/kernel/{hostname,domainname}來控制。這些是每個 UTS 命名空間:
# hostname
hell
# unshare --uts /bin/bash
# echo test > /proc/sys/kernel/hostname
# hostname
test
# exit
# hostname
hell
答案2
該uname
實用程式從系統呼叫中獲取其資訊uname()
。它填充這樣的結構(參見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
};
這直接來自正在運行的核心。我假設所有資訊都被硬編碼到其中,也許除外domainname
(事實證明,也nodename
,,machine
和release
,請參閱評論)。發布字串 fromuname -r
可以在編譯時透過配置進行設置,但我非常懷疑 sysname 欄位是否可以——它是 Linux 內核,沒有任何理由讓它使用其他任何東西。
但是,由於它是開源的,您可以更改原始程式碼並重新編譯核心以使用您想要的任何系統名稱。
答案3
在一個人的幫助下Linux 交叉參考你提到的/proc/sys/kernel/ostype
,我追蹤ostype
到包括/linux/sysctl.h,其中有評論說名稱是通過調用添加的register_sysctl_table
。
那麼那是哪裡打電話自?有一個地方是核心/utsname_sysctl.c, 包括包含/linux/uts.h,我們發現:
/* * Defines for what uname() should return */ #ifndef UTS_SYSNAME #define UTS_SYSNAME "Linux" #endif
所以,作為內核文件狀態:
調整這些值的唯一方法是重建內核
:-)
答案4
scripts/mkcompile_h
在 v4.19 中,這是產生 的文件include/generated/compile.h
,並且包含 的幾個有趣的部分/proc/version
:https://github.com/torvalds/linux/blob/v4.19/scripts/mkcompile_h
該
#<version>
部分來自.version
構建樹上的文件,每當連結發生(需要文件/配置更改)時,該文件就會增加scripts/link-vmlinux.sh
.它可以被
KBUILD_BUILD_VERSION
環境變數覆蓋:if [ -z "$KBUILD_BUILD_VERSION" ]; then VERSION=$(cat .version 2>/dev/null || echo 1) else VERSION=$KBUILD_BUILD_VERSION fi
日期只是一個原始
date
呼叫:if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then TIMESTAMP=`date` else TIMESTAMP=$KBUILD_BUILD_TIMESTAMP fi
類似地,使用者名稱來自
whoami
(KBUILD_BUILD_USER
) ,主機名稱來自hostname
(KBUILD_BUILD_HOST
)編譯器版本來自
gcc -v
,看起來無法控制。
這是如何更改問題的內容版本:https://stackoverflow.com/questions/23424174/how-to-customize-or-remove-extra-linux-kernel-version-details-shown-at-boot