커널 모듈 만들기

2024. 12. 19. 16:23디바이스 드라이버

로드 가능한 커널 모듈(Loadable Kernel Module, LKM)이란?

운영 체제 커널의 기능을 동적으로 확장하거나 수정하기 위해 사용되는 소프트웨어 모듈.

LKM은 커널이 실행 중인 상태에서 시스템에 로드(추가)하거나 언로드(제거)할 수 있는 모듈로 재부팅 없이 커널의 기능을 추가하거나 수정할 수 있게 해준다.

 

커널 설정 문법

menu ~ endmenu : 설정 메뉴 추가

config<설정 이름 (대문자)> : Makefile과 코드에서 사용할 이름을 지정

tristate <간략한 설명> : 3가지 설정값(Y/N/M)을 가짐 (Y는 커널에 포함, N은 미포함, M은 모듈로 빌드를 의미)

bool <간략한 설명> : 2가지 설정값(Y/N)을 가짐

default <기본값> : 별도로 설정하지 않았을 때 사용할 값

help <상세한 설명> : Help로 봤을 때 보이는 상세한 설명

 

새로운 커널 설정 (Kconfig) 추가하기

 

linux/drivers에 가서 lkm이라는 디렉토리를 하나 만들어준 후

drivers의 Makefile과  Kconfig에 들어가서  만들어준 디렉토리를 등록한다.

 

그 다음 만들어둔 lkm 디렉토리에 가서 Kconfig파일과 Makefile을 만든다.

main.c를 만들면 자동적으로 main.o (목적파일)로 변환되서 lkm.o에 들어간다.

 

main.c를 작성한 코드이다. 

<linux/module.h> 헤더 파일은 리눅스 커널 모듈을 작성할 때 필수적으로 포함해야하는 헤더 파일이다. 이 헤더 파일은 커널 모듈의 기본적인 구조와 동작에 필요한 매크로,함수, 그리고 데이터 구조를 정의하고 제공한다. (위에 있는 module_init, module_exit,AUTHO,DESCRIPTION,LICENSE등등)

 

lkm_module_init 함수는 모듈이 로드될 때 실행되는 함수이고, lkm_module_exit 함수는 모듈이 언로드될 때 실행되는 함수이다.

init함수 안에는 보통 모듈 초기화 내용이 들어가 있고, exit함수 안에는 보통 정리 작업에 관한 내용이 들어가 있다.

__func__는 현재 실행 중인 함수의 이름을 반환해주는 함수이다. 

 

MODULE_AUTHO는 작성자의 정보를, DESCRIPTION은 모듈에 관한 간단한 설명을, LICENSE는 모듈의 라이선스를 지정한다. 

라이선스 부분에 있는 GPL v2는 오픈소스 라이선스로 자유로운 사용, 수정, 배포를 보장하는 라이선스이다.

 

그 다음 menuconfig에 들어가서 Device Driver에 들어가서 맨 아래쪽을 보면

 

만들어 뒀던 LKM Example Driver가 생긴다.

들어가서 M으로 바꿔준다.

 

CROSS_COMPILE을 해주면

 

위와 같이 ko파일이 생성되는 것을 확인할 수 있다.

 

 

위와 같은 과정으로 lkm.ko파일을 modules이라는 디렉토리를 생성하고 그 곳에 복사한다.

QEMU에 들어가서 lkm.ko가 잘 복사되었는지 확인하고, insmod 명령어를 사용해서 리눅스 커널 모듈을 커널에 삽입한다.

dmesg 명령어로 insmod,rmmod,modprobe로 모듈을 로드하거나 언로드한 후 그 결과를 확인할 수 있다. 

결과를 확인해보면 main.c에서 로드했을 때 init함수가 실행되어 실행중인 함수의 이름인 lkm_module_init이 성공적으로 출력했다는 것을 확인할 수 있다.

 

그 다음 rmmod로 언로드 후 dmesg 명령어를 사용하면 exit가 출력되는 것을 확인할 수 있다. init과 exit가 동시에 뜨는 이유는 init은 로드할 때 기록되고, exit는 언로드할 때 기록되기 때문이다.

 

시스템 콜 vs 리눅스 커널 모듈

시스템 콜과 리눅스 커널 모듈은 둘 다 커널 모드에서 내가 작성한 함수를 실행할 수 있게 해주는 기능이다.

두 기능의 차이점은 시스템 콜은 사용자 프로그램에서 커널 기능을 호출하는 방법이고, 커널 모듈은 커널의 기능을 확장하거나 변경하는 방법이다. 

시스템 콜을 사용하면 커널 안에 있는 기능을 호출할 수 있고, 커널 모듈을 사용하면 동적으로 커널의 기능을 확장시킬 수 있다.

예를 들면 고기만 파는 정육점을 커널이라고 생각하면, 우리는 시스템 콜을 사용해서 커널(정육점)에서 원하는 기능(고기 부위)를 가져올 수 있고, 커널 모듈을 사용하면 커널(정육점)에 기능을 확장시킬 수 있다. (채소같은 판매하는 종류를 넓히는)

'디바이스 드라이버' 카테고리의 다른 글

시스템 콜 추가하기 (실습)  (0) 2024.12.10
GDB를 통한 디버깅  (0) 2024.12.02
새로운 시스템 콜 추가하기 (2)  (0) 2024.11.28
새로운 시스템 콜 추가하기 (1)  (0) 2024.11.27
Makefile 실습  (1) 2024.11.26