Linux에서 Kernel Module은 필요할 때 커널에 동적으로 로드(load)하거나 언로드(unload)할 수 있는 코드 조각
즉, 커널 전체를 다시 빌드하거나 시스템을 재부팅하지 않고도 커널의 기능을 확장할 수 있는 메커니즘
Linux kernel에 runtime 중에 코드를 추가하거나 제거할 수 있게 해주는 구조
module 없이 kernel 기능 추가:
module 사용:
Kernel Module은 주로 다음 용도로 사용된다:
컴파일된 Kernel Module은 보통 .ko (kernel object) 확장자를 가지며,
/lib/modules/ 디렉토리에 위치한다.

Linux 시스템은 크게 다음과 같이 나뉜다:
User Space
Kernel Space
User Space의 프로그램은 system call interface를 통해서만 Kernel Space에 접근할 수 있다.
Kernel Module은 Kernel Space에서 실행되므로 아주 강력하지만 매우 위험하다.
Without Kernel Module
With Kernel Module
lsmod현재 kernel에 로드된 module 목록을 출력한다
$ lsmod
Module Size Used by
xor 24576 1 btrfs
zstd_compress 163840 1 btrfs
Size: module이 차지하는 memoryUsed by: 해당 module을 사용하는 다른 module 개수insmodKernel Module을 kernel에 삽입(load)한다
insmod my_module.ko
.ko 파일을 kernel에 직접 로드rmmodKernel Module을 kernel에서 제거(unload)한다
rmmod my_module
주의 사항:
modinfoKernel Module의 상세 정보를 출력한다
modinfo my_module.ko
Kernel Module 소스는 kernel source tree 바깥(out-of-tree)에 있어도 된다
make.ko 파일 생성obj-m := hello_module.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
-C $(KERNEL_DIR)
M=$(PWD)
obj-m
여러 module을 동시에 컴파일할 수도 있다:
obj-m := module1.o module2.o module3.o
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
int __init hello_module_init(void)
{
printk("Hello Module!\n");
return 0;
}
void __exit hello_module_cleanup(void)
{
printk("Bye Module!\n");
}
module_init(hello_module_init);
module_exit(hello_module_cleanup);
MODULE_LICENSE("GPL");
Kernel module은 일반적인 user-level program과 달리
명확한 시작 지점(init)과 종료 지점(exit)을 반드시 가져야 한다
Linux kernel은 module이 언제 로드되고, 언제 언로드되는지를 알아야 하므로
각각에 대응되는 함수를 명시적으로 등록해야 한다
module_init(hello_module_init);
module_init()은 module initialization entry point를 지정하는 매크로다.
의미를 정리하면 다음과 같다.
insmod를 통해 kernel에 insert(load) 될 때module_init()에 등록된 함수가 자동으로 실행된다hello_module_init() 함수가 module의 시작 함수가 된다즉,
sudo insmod hello_module.ko
를 실행하면,
kernel 내부에서 hello_module_init()이 호출된다.
이 함수 안에서는 보통 다음 작업을 수행한다.
printk)module_exit(hello_module_cleanup);
module_exit()은 module exit entry point를 지정한다.
rmmod로 remove(unload) 될 때module_exit()에 등록된 함수가 자동으로 실행된다hello_module_cleanup() 함수가 종료 함수 역할을 한다즉,
sudo rmmod hello_module
를 실행하면,
kernel은 module을 제거하기 전에 hello_module_cleanup()을 먼저 호출한다.
이 함수에서는 보통 다음 작업을 수행한다.
Kernel module은 반드시 다음 두 가지를 포함해야 한다.
이유는 kernel이:
를 명확히 알아야 하기 때문이다.
따라서 init 또는 exit 함수가 없으면
정상적인 kernel module로 동작할 수 없다.
Kernel module은 kernel space에서 실행되는 코드다
그래서 모든 module 관련 명령어는 sudo가 필요하다
sudo insmod hello_module.ko
이 명령을 실행하면 다음 순서로 동작한다
module_init()에 등록된 함수 실행hello_module_init()이 호출됨sudo rmmod hello_module
이때의 동작 순서는 다음과 같다
module_exit()에 등록된 함수 실행hello_module_cleanup()이 호출됨Kernel module은 특정 kernel version에 맞춰 컴파일된다
uname -r
로 확인한 kernel version을 기준으로 build되며,
다른 version의 kernel에서는 해당 .ko 파일을 로드할 수 없다
즉,
Kernel module의 lifecycle은 매우 단순하다
insmod → init function 실행
rmmod → exit function 실행
module_init() : module 시작 지점module_exit() : module 종료 지점