강좌 & 팁
글 수 2,412
2011.04.14 17:53:22 (*.138.143.120)
96522
커널 빌드시에 언제 부터인가
WARNING: modpost: Found 2 section mismatch(es).
To see full details build your kernel with:
'make CONFIG_DEBUG_SECTION_MISMATCH=y'
이런 메세지를 보게 되었다.
어떤때는 문제가 발생하고 어떤때는 빌드가 되어 동작시키면 문제가 없기도 했다.
이기회에 이런 에러가 왜 생기는지 무엇이 문제인지 한번 확실하게 짚고 넘어가자.
먼저 친절하게도 커널은 CONFIG_DEBUG_SECTION_MISMATCH=y 옵션을 이용해서
컴파일해서 상세한 내용을 보라고 친절하게 알려준다.
이 옵션을 주고 컴파일을 하였을때 어떤 에러메세지를 내는지 한번 살펴보자.
WARNING: vmlinux.o(__ksymtab+0x4e8): Section mismatch in reference from the variable __ksymtab_s3c24xx_ts_set_platdata to the function .init.text:s3c24xx_ts_set_platdata()
The symbol s3c24xx_ts_set_platdata is exported and annotated __init
Fix this by removing the __init annotation of s3c24xx_ts_set_platdata or drop the export.
착하게도 __init 를 제거하라고 나옵니다.
실제 그렇게 하면 에러메세지는 사라집니다.
혹은 EXPORT_SYMBOL 로 함수를 선언한 부분을 제거해도 됩니다.
그렇다면 왜 그렇게 될가요?
http://www.kernel.org/doc/htmldocs/kernel-hacking.html 에 보면 자세한 이야기가 나와 있다.
_init/__exit/__initdata include/linux/init.h
After boot, the kernel frees up a special section;
functions marked with __init and data structures marked with __initdata are dropped after boot is complete:
similarly modules discard this memory after initialization.
__exit is used to declare a function which is only required on exit:
the function will be dropped if this file is not compiled as a module.
See the header file for use.
Note that it makes no sense for a function marked with __init to be exported to modules with EXPORT_SYMBOL() - this will break
__init 지시어는 커널이 부팅되고 난후에 버려집니다.
비슷하게 모듈일 경우도 초기회가 끝나면 버려집니다.
__exit 는 해당 function 이 exit 될때 사용되는데 모듈이 아닐때는 역시 버려집니다.
이렇게 놓고 보면 __init 로 선언한 함수를 EXPORT_SYMBOL 로 선언하여 다른 함수에서 불릴수 있게 한다는 것은
모순이 되어 버리고 맙니다. 초기화가 끝난 이후에는 제거되기 때문이죠.
커널의 include/linux/init.h 파일을 참조해 보면 __init 를 사용하는 방법이 나옵니다.
49 /* modpost check for section mismatches during the kernel build.
50 * A section mismatch happens when there are references from a
51 * code or data section to an init section (both code or data).
52 * The init sections are (for most archs) discarded by the kernel
53 * when early init has completed so all such references are potential bugs.
54 * For exit sections the same issue exists.
55 * The following markers are used for the cases where the reference to
56 * the *init / *exit section (code or data) is valid and will teach
57 * modpost not to issue a warning.
58 * The markers follow same syntax rules as __init / __initdata. */
59 #define __ref __section(.ref.text) noinline
60 #define __refdata __section(.ref.data)
61 #define __refconst __section(.ref.rodata)
modepost 에서 section mismatch 를 확인한답니다.
그리고 그 원인은 init section 이 code 혹은 data section 을 참조할려 할때 발생한답니다.
EXPORT_SYMBOL 을 하게 되면 그렇게 되겠죠...
아 init.h 함수의 마지막에는 이런 것도 있습니다.
330 #if defined(MODULE) || defined(CONFIG_HOTPLUG)
331 #define __devexit_p(x) x
332 #else
333 #define __devexit_p(x) NULL
334 #endif
모듈도 아닌것인 핫플러깅도 아닌것이 __devexit_p 로 선언될 경우...
커널 빌트인되어 컴파일 되는 것이기 때문에 결코 exit 가 불려질 일이 없습니다.
따라서 해당 함수는 삭제됩니다...