실행한 커널과 빌드한 커널을 대조합니다
uname -r
make -s -C "$KDIR" kernelrelease
modinfo -F vermagic ./sample.koKDIR은 모듈을 사용할 커널의 설정과 빌드 결과가 있는 디렉터리입니다. 위 명령은 각각 실행 커널 release, 지정한 빌드의 release, 모듈의 vermagic을 보여 줍니다. 문자열이 같아도 모든 ABI와 설정의 일치를 증명하지는 않습니다. 교차 빌드에서는 호스트 uname 결과를 타깃 커널이라고 쓰지 않습니다.
| 파일 | 용도 |
|---|---|
| vmlinux | 커널 ELF입니다. 디버그 정보 포함 여부는 설정에 달려 있습니다. |
| System.map | 해당 빌드의 커널 심벌 주소 목록입니다. 임의의 실행 커널에 대입하지 않습니다. |
| Module.symvers | export 심벌과 모듈 버전 확인에 쓰이는 정보입니다. |
| .config | 그 출력 트리의 실제 커널 설정입니다. 소스의 defconfig와 구분합니다. |
CONFIG_LOCALVERSION은 release에 붙는 문자열입니다. localversion 파일, LOCALVERSION 인자, SCM 접미사도 관여하므로 최종 kernelrelease를 확인하는 편이 확실합니다.
모듈 하나를 여러 오브젝트로 묶습니다
obj-m += sample.o
sample-y := sample_main.o sample_io.o
sample-$(CONFIG_SAMPLE_DEBUG) += sample_debug.osample_main.c와 sample_io.c를 각각 컴파일한 뒤 sample.o로 묶고 sample.ko를 만듭니다. 복합 모듈의 결과 이름 sample.o를 다시 자신의 구성 목록에 넣으면 안 됩니다. 한 소스로 만드는 obj-m += hello.o와 hello.c의 같은 이름은 정상적인 형태입니다.
- 소스별 컴파일sample_main.c와 sample_io.c를 오브젝트로 만듭니다.
- 모듈 오브젝트 결합두 결과를 sample.o로 연결합니다.
- 모듈 검사와 최종 링크modpost 등의 단계를 거쳐 sample.ko를 만듭니다.
번호는 빌드 단계입니다. sample-y의 y는 sample 전체가 반드시 커널 내장이라는 뜻이 아닙니다.
메뉴에 보이는 값과 최종 값을 구분합니다
CONFIG 항목은 depends on, select, default와 타입의 영향을 받습니다. tristate 항목이 m인 의존성에 제한되면 y를 요청해도 최종 값이 달라질 수 있습니다. 메뉴에 표시되지 않는 내부 항목도 .config에 존재할 수 있습니다. source 디렉터리와 O= 출력 디렉터리의 설정을 혼동하지 않습니다.
choice 문법도 버전을 확인합니다. Linux 6.6 문서는 bool과 tristate choice를 다루지만 Linux 6.18 문서는 bool choice를 규정합니다. “choice는 역사적으로 항상 bool만 허용한다”는 설명은 맞지 않습니다. Linux의 CONFIG_MMC_BLOCK을 U-Boot에 같은 뜻으로 대입하는 것도 피해야 합니다.
undefined와 버전 오류를 따로 조사합니다
modpost의 undefined는 선언을 못 찾았다는 컴파일 오류와 다릅니다. 정의가 실제 빌드되는지, export되었는지, 필요한 모듈의 심벌 정보가 들어왔는지, 이름이 일치하는지 확인합니다. modules_prepare만으로는 CONFIG_MODVERSIONS에 필요한 Module.symvers가 만들어지지 않습니다.
MODVERSIONS는 export된 인터페이스의 CRC 등을 확인하는 장치이며 어떤 커널 버전에도 모듈을 호환시켜 주는 옵션이 아닙니다. 헤더를 바꿀 때마다 무조건 전체 clean이 필요하지도 않습니다. 먼저 실제 컴파일 명령과 의존성, 다른 출력 트리를 잘못 읽는지 확인하고 재현에 필요한 빌드 기록을 보관합니다.