간단한 커널 모듈 코드
apt install linux-headers-($uname -r) build-essential
- 우선 커널 모듈 빌드에 필요한 패키지들을 설치한다
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SIJIN");
MODULE_DESCRIPTION("DEMO");
MODULE_VERSION("0.1";)
static int __init hello_init(void) {
printk(KERN_INFO, "hello");
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO, "exit");
}
module_init(hello_init);
module_exit(hello_exit);
커널 모듈 빌드
obj-m += simple_random.o
all:
make -C /lib/modules/6.8.0-86-generic/build M=$(PWD) modules
clean:
make -C /lib/modules/6.8.0-86-generic/build M=$(PWD) clean
- 위 처럼 Makefile을 작성해서 빌드할 수 있다
obj-m은 커널 모듈로 빌드할 오브젝트 파일 목록이다
make -C ... M=$(PWD)은 커널 빌드 시스템 (Kbuild)를 호출한다
Kbuild
- 커널 모듈은 일반 gcc 빌드와 다른점이 있다
-Iarch/.../include 같은 커널 헤더 포함
-D__KERNEL__ -DMODULE 같은 커널 전용 플래그 포함
- 커널 버전 정보 vermagic 포함
- 심볼 참조, 의존성 확인
- .mod, .mod.o 생성
- 최종적으로 .ko 링크
- 이런 작업들을 커널 빌드 시스템이 해준다
/lib/modules/6.8.0-86-generic/build/Makefile은 커널 빌드 시스템의 entry point가 된다
cmake
- Kbuild를 사용하기 때문에 cmake의 add_executable, add_library 같은 방식은 사용할 수 없다
- 따라서 cmake를 사용하더라도 커널 모듈의 경우엔 add_custom_library, add_custom_target등으로 make 파일을 호출해서 사용해야 한다
add_custom_command(
OUTPUT ${MODULE_NAME}.ko
COMMAND make -C ${KERNEL_DIR} M=${CMAKE_CURRENT_SOURCE_DIR} modules
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
VERBATIM
)