본문 바로가기
Linux/Driver

간단한 리눅스 모듈 드라이버

by khd0801 2022. 4. 14.
반응형

 1. 모듈드라이버 등록 및 제거 코드 

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

static int __init hello_init(void)
{
	printk(KERN_ALERT "Hello, world!\n");
	pr_debug("This is a debug message!\n");
	pr_err("This is a error message!\n");
	return 0;
}

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

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("khd0801");
MODULE_DESCRIPTION("Hello World program");

insmod로 모듈 드라이버 로드시 hellow_init 함수가 호출되고, rmmod로 모듈 제거시 hello_exit 함수가 실행됩니다.

현재 로드된 모듈 드라이버의 리스트를 보고 싶다면 lsmod를 실행시키면 됩니다.

 

module_init과  module_exit는 일반 함수가 아니라 "include/linux/module.h" 헤더파일에 매크로 함수 선언되어있습니다.

매크로 함수 내부가 궁금한 사람은 따라가 봐도 좋을듯 하며 지금 블로그에서는 설명하지 않습니다.

 

 2. Makefile

# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
    obj-m := hello_world.o

# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)

.PHONY: modules
modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif

.PHONY: clean
clean:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) clean

CFLAGS_main.o := -DDEBUG

3번째 줄 ifneq ($(KERNELRELEASE),) : KERNELRELEASE 환경변수가 정의되어 있지 않다면 아래 구문을 실행하라는 뜻으로 KERNELRELEASE는 리눅스 메인 Makefile 실행시 설정되며, 해당 Makefile만 있는 폴더에서 make 실행시 8번째 줄 else 밑의 구문들이 실행되게 된다.

 

4번째 줄 obj-m := hello_world.o : built-in 컴파일시 해당 hello_world.c 파일은 모듈 드라이버로 컴파일 한다는 의미이다.

 

9번째 줄 KERNELDIR ?= /lib/modules/$(shell uname -r)/build : KERNELDIR 변수가 정의되어 있지 않으면 해당 설정 경로를 대입한다.

 

10번째 줄 PWD := $(shell pwd) : 현재 디렉토리 값으로 PWD 변수를 설정한다. 

 

12번째 줄의 .PHONY는 실제 파일명과 target 이름의 충돌 문제를 해결하며, make의 성능을 향상시킨다.

Phony는 가짜라는 의미이며, phony target이란 실제 파일이름이 아니라 target의 이름을 의미한다.

make 명령을 실행하는 디렉토리에 Makefile의 target과 같은 이름의 파일이 존재하면 충돌이 발생하는데 .PHON에 명시하여 충돌을 피할 수 있다. 

 

14번째 줄 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules : make 명령이 make 명령어를 호출 하는 구문으로 -C $(KERNELDIR)로 이동하여  make를 실행한 후 다시 돌아오게 된다. M=$(PWD) 옵션은 Module 소스 코드가 있는 곳을 나타내며 modules는 make의 입력 파라미터로 사용되어진다.

최종적으로는 $(KERNELDIR)에 위치한 make 파일을 실행시키며, modules라는 입력 파라미터를 받아 모듈 소스 코드가 있는 곳의 파일을 이용하여 make modules를 실행하게 된다. $(KERNELDIR)의 make 파일을 열어보면 modules에 관한 실행 코드가 있다.

 

 3.실행 결과

 

sudo 권한으로 드라이버 로드시 "insmod: ERROR: could not insert module hello_world.ko: Operation not permitted"  에러가 발생되고 커널 메세지에 "Lockdown: insmod: unsigned module loading is restricted; see man kernel_lockdown.7"가 출력 된다면 아래 링크를 참조하여 환경을 구축하면 실행이 된다

 

드라이버 정상적으로 로드가 되지 않을 때(Lockdown: insmod: unsigned module loading is restricted;)

 
 

 

반응형

댓글