uname은 어디서 정보를 얻나요?

uname은 어디서 정보를 얻나요?

uname은 실제로 어디서 정보를 얻나요?

나는 이것이 간단한 문제라고 생각합니다. 안타깝게도 이 정보가 포함된 책을 찾을 수 없습니다.

unameuname -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(결과적으로 , nodenamemachine, release주석 참조)를 제외하고 모든 정보가 여기에 하드코딩되어 있다고 가정했습니다 . 릴리스 문자열은 uname -r컴파일 타임에 구성을 통해 설정할 수 있지만 sysname 필드가 가능한지 의심스럽습니다. 이는 Linux 커널이므로 다른 것을 사용할 이유가 없습니다.

그러나 오픈 소스이기 때문에 소스 코드를 변경하고 커널을 다시 컴파일하여 원하는 시스템 이름을 사용할 수 있습니다.

답변3

누군가의 도움으로리눅스 상호 참조/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>에서 나옵니다 (파일/구성 변경 필요) ..versionscripts/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

관련 정보