본문 바로가기
IT 기술/리눅스 커널

커널 로컬 버전 세팅

by 땅뚱 2012. 11. 9.

리눅스 커널 버전을 나타내는 파일은 다음과 같이 2가지가 존재한다. 파일은 모두 컴파일시에 생성된다.

include/config/kernel.release

include/generated/utsrelease.h

위 파일중 utsrelease.h 내에 정의된 UTS_RELEASE 의 값이 실제 uname 에서 보여지는 커널의 버전이 된다.

systemTap 을 사용해서 특정 모듈을 올리는데, kernel.release 와 UTS_RELEASE 가 다르다고 해서 모듈로딩이 실패하는 상황이 발생하였다.

코드를 찾아보니 Makefile 에서 KERNEL_RELEASE 대신 KERNEL_VERSION 을 UTS_RELEASE 에 넣도록 수정을 해놓은 상황.. 이렇게 되어서 kernel.release 와 utsrelease.h 안의 UTS_RELEASE 버전이 다른게 된 것이다.

systemTap 에서 모듈을 로딩할 때, 위 두 값을 비교하도록 되어 있어서 모듈로딩이 실패한 것이다.

이 것을 계기로 kernel.release 파일이 어떻게 생성되는지 확인해보았다.

커널 최상위 Makefile 을 살펴보면 다음과 같은 내용이 있다.

# Store (new) KERNELRELASE string in include/config/kernel.release
include/config/kernel.release: include/config/auto.conf FORCE
    $(Q)rm -f $@
    $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@

kernel.release 를 만드는 부분이다. 기본적으로 KERNEL_VERSION 에 setlocalversion 의 결과 문자열을 합쳐서 만들도록 되어있다. scripts/setlocalversion 을 살펴보자. 코드 중간쯤에 다음과 같은 내용이 있다.

# CONFIG_LOCALVERSION and LOCALVERSION (if set)
res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"

# scm version string if not at a tagged commit
if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
    # full scm version string
    res="$res$(scm_version)"
else

즉 커널 옵션 에서 설정한 CONFIG_LOCALVERSION 이 있는 경우, 해당 문자열을 추가하고, LOCALVERSION 이 존재하면 이것도 뒤에 추가해준다. CONFIG_LOCALVERSION 은 커널 옵션에서 설정해주는데, LOCALVERSION 은 어디서 설정하는지 찾지 못했다.

그런 후에 역시 커널 옵션에서 설정해주는 CONFIG_LOCALVERSION 이 'y' 로 설정되어있으면 scm_version 을 뒤에 추가해준다. scm_version 은 source control management version 의 줄임말이다. git rev-parse 명령을 사용해서 tag 정보를 가공해서 생성된 문자열을 해당 정보를 뒤에 붙여준다. 이렇게 생성된 localversion 은 kernel.release / utsrelease.h 에 반영된다.