uname 从哪里获取信息?

uname 从哪里获取信息?

uname 真正从哪里获取信息?

我认为这应该是直截了当的事情。不幸的是,我找不到任何包含该信息的标题。

uname假设有人想将/的基本输出更改uname -sLinux其他内容(本质上是重命名内核)。

他/她将如何以正确的方式做到这一点(即更改来源)?

答案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,,machinerelease,请参阅评论)。发布字符串 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/versionhttps://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

相关内容