일반 애플리케이션은 gcc -o로 컴파일하지만, 커널 모듈은 커널 빌드 시스템(kbuild)을 통해 컴파일해야 합니다. Makefile을 만들고 make 명령어로 빌드하면 .ko (Kernel Object) 파일이 생성됩니다.
현재 실행 중인 커널 버전에 맞는 헤더 파일이 필요합니다.
# 우분투 / 라즈비안 (Debian 계열)
sudo apt-get update
sudo apt-get install build-essential linux-headers-$(uname -r)

WSL2는 일반 리눅스 커널이 아니라 마이크로소프트가 개조한 전용 커널을 씁니다.
apt install linux-headers-$(uname -r)로 설치 가능uname -r 결과가 5.15.90.1-microsoft-standard-WSL2 이런 식으로 나오는데, 이 버전에 맞는 헤더가 우분투 저장소(apt)에 없습니다따라서 WSL에서는 커널 모듈 개발이 까다롭습니다.
kernel_task_check.c 파일을 만듭니다:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
int init_module(void) {
struct task_struct *task = current;
printk(KERN_INFO "[Kernel] Module Loaded.\n");
printk(KERN_INFO "[Kernel] Current PID: %d, Comm: %s\n", task->pid, task->comm);
return 0;
}
void cleanup_module(void) {
printk(KERN_INFO "[Kernel] Module Removed.\n");
}
MODULE_LICENSE("GPL");

같은 폴더에 Makefile (대소문자 주의)을 만들고 아래 내용을 입력합니다.
중요: make 구문의 들여쓰기는 반드시 Tab 키를 사용해야 합니다 (스페이스 안 됨).
obj-m += kernel_task_check.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

make

실수로 홈 디렉토리에 파일 만들고 빌드해서.. 소스 코드만 원하는 폴더로 옮기고 re-build 해주었습니다.

성공하면 kernel_task_check.ko 파일이 생성됩니다.
커널 영역에 모듈을 로드합니다 (root 권한 필요):
sudo insmod kernel_task_check.ko
printf가 아니라 printk를 사용했기 때문에 출력이 터미널이 아닌 커널 로그 버퍼에 찍힙니다.
sudo dmesg | tail
출력 예시:
[Kernel] Module Loaded.
[Kernel] Current PID: 1234, Comm: insmod

[479830.297782] kernel_task_check: loading out-of-tree module taints kernel. 오류
왜 오염? -> 공식 커널이 아닌 외부에서 만든 코드니까 안정성을 보장할 수 없다는 뜻이다.
sudo rmmod kernel_task_check
다시 sudo dmesg | tail로 확인하면 [Kernel] Module Removed. 메시지를 볼 수 있습니다.

kernel compile을 하는 주체는 compiler인데 이게 WSL2 kernel이 customization된 kernel인것과 무슨 상관인가요?