리눅스 커널 버전을 나타내는 파일은 다음과 같이 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 에 반영된다.
'IT 기술 > 리눅스 커널' 카테고리의 다른 글
[linux] find_first_zero_bit() 분석 (0) | 2013.05.14 |
---|---|
sparse : kernel static analysis tool (0) | 2013.02.12 |
Linux kernel CPU Frequency 변경(DVFS) 코드 (2) | 2011.02.11 |
kjournald 에 IPPRIO_CLASS_RT 권한 부여 (0) | 2010.05.03 |
리눅스 2.6 pdflush VS. 리눅스 2.4 bdflush, kupdate (1) | 2009.09.04 |