
uname은 실제로 어디서 정보를 얻나요?
나는 이것이 간단해야 할 일이라고 생각합니다. 안타깝게도 해당 정보만 포함된 헤더를 찾을 수 없습니다.
uname
누군가가 / uname -s
from 의 기본 출력을 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
, 주석 참조) 를 제외하고 모든 정보가 여기에 하드 코딩되어 있다고 가정합니다 . from 의 릴리스 문자열은 uname -r
컴파일 타임에 구성을 통해 설정할 수 있지만 sysname 필드가 그럴 수 있을지 의심스럽습니다. 이는 Linux 커널이므로 다른 것을 사용할 이유가 없습니다.
그러나 오픈 소스이기 때문에 소스 코드를 변경하고 커널을 다시 컴파일하여 원하는 sysname을 사용할 수 있습니다.
답변3
의 도움으로리눅스 상호 참조그리고 에 대한 당신의 언급을 추적 /proc/sys/kernel/ostype
했습니다.ostype
include/linux/sysctl.h, 주석에는 를 호출하여 이름이 추가된다는 내용이 있습니다 register_sysctl_table
.
그럼 그게 어디야?에서 전화? 한 곳은커널/utsname_sysctl.c, 이는 다음을 포함합니다include/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