In-tree 빌드란?
In-tree 빌드는 커널 모듈을 리눅스 커널 소스 트리 안에 추가하여 커널 빌드 시스템이 커널과 함께 해당 모듈을 빌드하도록 하는 방법이다. 이 방법을 사용하면 사용자는 menuconfig 명령어를 통해 메뉴 형태로 구성된 커널 설정 화면에서 모듈을 선택하거나 선택해제할 수 있다.
In-tree building 과정 요약
- 리눅스 커널 소스 트리 내에 모듈 추가
- 로컬 Kconfig 파일 작성
- 로컬 Makefile 작성
- 상위 레벨 Kconfig 파일에 로컬 Koconfig 파일 추가
- 상위 레벨 Makefile에 로컬 Makefile 추가
- 커널 소스 루트 디렉토리로 이동해서 make menuconfig를 이용해 설정 (Optional)
- 커널 소스 루트 디렉토리로 이동해서 모듈 빌드
1. 리눅스 커널 소스 트리 내에 모듈 추가
리눅스 커널 소스 트리 내에 모듈을 추가할 디렉토리를 생성한 뒤 모듈 소스 파일을 배치한다.
$cd <kernel-source-top>/drivers/char
$mkdir my_c_dev
$cd my_c_dev
$vim hello.c
#include<linux/module.h>
static int __init hello_init(void)
{
pr_info("Hello world\n");
return 0;
}
static void __exit hello_exit(void)
{
pr_info("Goodbye world\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ME");
MODULE_DESCRIPTION("A simple Hello World kernel module");
2. 로컬 Kconfig 파일 작성
menuconfig에 모듈을 선택할 수 있는 메뉴 항목을 추가하려면 menu 키워드로 시작하고 endmenu 키워드로 끝나는 메뉴 항목을 Kconfig 파일에 작성해야 한다. 위에서 생성한 디렉토리 내에 로컬 Kconfig 파일을 작성한다.
$vim Kconfig
menu "my custom modules"
config CUSTOM_HELLOWORLD
tristate "hello world module support"
default n
endmenu
- menu 뒤에 오는 "my custom modules"는 menuconfig에서 환경설정 시 볼 수 있는 메뉴 항목의 이름이다.
- config 뒤에 오는 CUSTOM_HELLOWORLD는 앞에 CONFIG_가 붙어 커널 구성 파일(.config)에서 식별자로 사용된다.
- tristate는 이 설정 항목이 세 가지 상태를 가질 수 있음을 나타내고 그 뒤에 오는 문자열을 사용자에게 표시될 설명문이다.
- 옵션 y(정적), n(비활성), m(동적) 중에서 기본 옵션을 지정하기 위해 default 키워드를 사용한다.
3. 로컬 Makefile 작성
역시 같은 디렉토리 내 로컬 Makefile을 만든다. 그리고 리눅스 커널 빌드 시스템에서 사용하는 obj-<X> 변수에 빌드할 모듈을 추가 정의한다.
$vim Makefile
obj-$(CONFIG_CUSTOM_HELLOWORLD) += hello.o
위에서 $(CONFIG_CUSTOM_HELLOWORLD)는 사용자가 menuconfig를 통해 빌드 옵션을 수정했을 때 .config 파일에서 해당 식별자를 통해 실제 선택된 옵션을 찾아 y 또는 n 또는 m으로 대치된다.
그리고 obj-<X> 변수를 통해 리눅스 커널 소스 트리에 존재하는 여러 다른 모듈과 같이 빌드되므로 여기서는 :=가 아닌 += 연산자를 사용한다.
4. 상위 레벨 Kconfig 파일에 로컬 Koconfig 파일 추가
상위 디렉토리(<kernel-source-top>/drivers/char/)로 이동해서 상위 레벨의 Kconfig 파일 끝 endmenu 윗 줄에 다음과 같이 추가한다.
$cd ..
$vim Kconfig
source "drivers/char/my_c_dev/Kconfig"
5. 상위 레벨 Makefile에 로컬 Makefile 추가
상위 Makefile에서 하위 Makefile을 찾을 수 있도록 끝줄에 다음 문구를 추가한다.
$vim Makefile
6. 커널 소스 루트 디렉토리로 이동해서 make menuconfig를 이용해 설정한다.
Device Drivers > Character devices 에서 my custom modules가 추가된 것을 확인할 수 있다.
엔터를 치고 들어가 스페이스를 여러번 치면 빌드 옵션을 바꿀 수 있다.
- <M> : 동적으로 커널에 로드 및 언로드 될 수 있는 독립적인 개체(.ko 파일)로 빌드 됨
- < * > : 커널 이미지에 직접 통합됨
- < > : 모듈을 빌드하지 않음
<M>으로 설정한 뒤 저장하고 빠져나오면 .config 파일이 생성되는 데 로컬 Kconfig 파일에 지정했던 식별자 앞에 CONFIG_를 붙여 검색하면 설정을 찾아볼 수 있다.
$vim .config
/CONFIG_CUSTOM_HELLOWORLD
이후 아래 명령어로 커널 소스 모듈을 빌드하면 최초 생성했던 디렉토리 안에 .ko 파일이 생성된 것을 확인할 수 있다.
$make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules -j4
modinfo 명령어로 확인해보면 intree: 에 Y 표시가 되어있다.
참고 :
Fastbit Embedded Brain Academy
https://medium.com/@adityapatnaik27/linux-kernel-module-in-tree-vs-out-of-tree-build-77596fc35891
'임베디드 개발 > 리눅스 디바이스 드라이버' 카테고리의 다른 글
LDD ] printk를 활용한 디버깅 (0) | 2024.10.06 |
---|---|
LDD ] Hello World 커널 모듈 (0) | 2024.10.02 |
modprobe와 insmod의 차이 (0) | 2024.09.30 |
리눅스 커널 모듈 (Linux Kernel Module) (0) | 2024.09.28 |