
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
。コメントを参照してください)。 からのリリース文字列は、uname -r
コンパイル時に構成で設定できますが、 sysname フィールドが設定できるかどうかは非常に疑問です。これは Linux カーネルであり、他のものを使用する理由は考えられません。
ただし、オープンソースなので、ソース コードを変更してカーネルを再コンパイルし、任意の sysname を使用することができます。
答え3
の助けを借りてLinux クロスリファレンスそしてあなたの言及/proc/sys/kernel/ostype
、私は追跡しostype
ましたインクルード/linux/sysctl.h、コメントには、 を呼び出すことによって名前が追加されると書かれていますregister_sysctl_table
。
それでそれはどこにあるのですかから呼び出された? 1つの場所はカーネル/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