리눅스/디바이스 드라이버

[디바이스 드라이버] 2. 모듈 프로그래밍

다락공방 2024. 9. 1. 23:55

이전 챕터에서 디바이스 드라이버는 모듈로 만들어서 커널에 적재하고, 해제할 수 있다고했다.

일단 환경은 라즈베리파이 4B / 64비트 커널 기반으로 진행하였다.


가장 간단한, 모듈을 만들어보자면 아래와 같이 만들 수 있을 것이다. 

 

 

모듈 소스 파일

나는 day1_module.c로 이름 붙였다.

#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("IH02");
MODULE_DESCRIPTION("Day1");

static int __init driver_init(void) {
	printk("Hello, World!\n");
	return 0;
}

static void __exit driver_exit(void) {
	printk("Bye, World!\n");
}

module_init(driver_init);  
module_exit(driver_exit);

모듈 정보를 선언해준다.

여기서 author, description은 내가 설정할 수 있는, 내 이름과 설명이다.

 

license는 짚고 가야되는데, 위처럼 선언하면 이 모듈이 GPL(General Public License) 라이선스 하에 배포된다는 것을 명시한다. 이 매크로는 Linux 커널이 모듈을 로드할 때 중요한 역할을 한다.

 - GPL이 아닌 모듈을 메모리에 로드하면 오염 플래그가 설정된다.

 - 또한 Linux 커널은 다양한 기능을 모듈에 제공하는데, 이 기능들은 "심볼"로 불린다. GPL 라이선스가 명시된 모듈은 커널 내의 모든 심볼에 접근할 수 있지만, 비GPL 모듈은 제한된 심볼만 접근할 수 있다.

따라서 라이선스 선언은 반드시 해줘야한다.

 

그뒤에 나오는 __init과, __exit 매크로는 각 함수가 모듈 초기화, 해제시에만 사용되는 함수임을 말하고,

  • module_init(driver_init): 커널에 모듈을 로드할 때 호출될 초기화 함수(driver_init)를 등록한다.
  • module_exit(driver_exit): 커널에서 모듈이 언로드될 때 호출될 종료 함수(driver_exit)를 등록한다.

 

 

 


 

Makefile

obj-m += day1_module.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

 

 

Makefile은 간단하다. 지난 포스트에서도 설명한대로, 라이브러리의 모듈build 파일을 이용해 현재 폴더의 소스파일로 모듈 파일을 생성한다.

obj-m 변수는 컴파일할 모듈 객체 파일의 목록을 지정하고, 생성될 day1_module 오브젝트 파일을 지정하여 ko파일로 컴파일 되도록해준다.

 

 

 


모듈 등록

make 명령어를 시켜 컴파일을 진행한다.

 

실행하면, 위와같이 .ko 파일이 생성된 것을 볼 수 있다.

 

기본적인 명령어는 3개이다.

모듈 명령어

 insmod [모듈명].ko : 모듈의 커널 적재 

 rmmod [모듈명] : 커널에 적재된 모듈 제거

 lsmod [모듈명] : 커널에 적재된 모듈 확인

 

먼저 모듈 수 부터 확인해보자. 

70개의 모듈이 등록되어있다.

 

insmod 모듈이름.ko 로 등록하면 갯수가 늘어났음을 확인할 수 있다.

또한 dmesg로 커널의 

 

lsmod 에서 day1_module을 찾을 수 있고, 뒤의 두 수의 의미는 모듈에 의해서 사용되는 메모리 양(byte), 사용되고 있는 인스턴스 수라고 볼 수 있다.

 

이제 모듈을 해제시켜보자.

 

언제 한번 포스트 한적이 있는데, dmesg를 통해 Linux에서 커널 메시지 버퍼의 내용을 출력할 수 있다.

이 명령어는 시스템의 부팅 과정, 드라이버 로드 및 언로드, 하드웨어 문제, 오류 메시지 등과 같은 다양한 커널 관련 로그를 확인하는 데 사용된다.

이걸 사용해보면, 

이렇게 커널로그를 볼 수 있다.

모듈이 init, exit될때의 함수에 따라 문구가 출력되었음을 볼 수 있었다.

맨앞 메시지는  메시지는 커널에 외부(out-of-tree) 모듈이 로드될 때 나타나는 경고 메시지이다. "out-of-tree module"이란 커널의 기본 소스 트리에 포함되지 않은 모듈을 의미한다.