hello 모듈 : "Ubuntu 16.04.5 LTS" , 4.15.0-33-generic에서 진행
함수 실행시간 측정 예제 : "Ubuntu 18.04.2 LTS", 5.1.5에서 진행(출처: https://jjudrgn.tistory.com/25 [jjudrgn's note])
커널에 모듈을 적재하고 메세지를 띄우기 위해서는 다음과정이 필요하다.
.ko파일 만들기
hello.c 와 Makefile을 만들고 make
모듈 로드
insmod hello.ko
메세지 확인하기
dmesg
먼저 hello.c파일을 만든다
hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init init_hello(void){
printk(KERN_ALERT "Hello, kernel!\n");
return 0;
}
static void __exit exit_hello(void){
printk(KERN_ALERT "Good-bye, kernel!\n");
}
module_init(init_hello);
module_exit(exit_hello);
MODULE_LICENSE("GPL");
커널이 모듈을 로드할때와 커널이 모듈을 제거할때 사용할 때 사용할 두개의 함수를 정의한다. 정의한 함수안에는 printk를 이용해서 log를 남긴다.
이떄 주의할점은 module_init라는 매크로와 module_exit에 들어갈 함수는 return을 주의해야 한다.
필자는 첫 hello.c파일을 만들시 int나 void를 쓰지 않거나 const형으로 써서
return from incompatible pointer type [-Werror=incompatible-pointer-types]에러가 발생했다
/home/jy-os/lab/test2/hello.c:5:15: warning: return type defaults to ‘int’ [-Wreturn-type]
static __init init_hello(void){
^
/home/jy-os/lab/test2/hello.c:10:15: warning: return type defaults to ‘int’ [-Wreturn-type]
static __exit exit_hello(void){
^
In file included from /home/jy-os/lab/test2/hello.c:2:0:
/home/jy-os/lab/test2/hello.c: In function ‘__exittest’:
/home/jy-os/lab/test2/hello.c:15:13: error: return from incompatible pointer type [-Werror=incompatible-pointer-types]
module_exit(exit_hello);
^
./include/linux/module.h:138:11: note: in definition of macro ‘module_exit’
{ return exitfn; } \
^
/home/jy-os/lab/test2/hello.c: In function ‘exit_hello’:
/home/jy-os/lab/test2/hello.c:12:1: warning: control reaches end of non-void function [-Wreturn-type]
}
위처럼 hello.c파일을 만든후 같은 폴더안에 Makefile을 만든다.
2.6버전 이후부터는 .ko파일을 만들기 위해 gcc말고 Makefile을 만들어 줘야한다.
Makefile
obj-m = hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.kr *.mod.* .*.cmd *.o
obj-m은 목적파일이다. 이떄 m은 모듈, y는 built-in 형식의 ko파일을 만든다.
KDIR은 Kernel Source Directory이다. 현재 커널소스의 디렉토리는 /lib/modules/$(shell uname -r)/build에 링크 되어있다.)
PWD는 현재 디렉토리 위치인데
PWD := $(shell pwd) 또는 PWD := `pwd`를 써도된다. ( 이떄 `는 '와 다르다.)
clean은 빌드결과물과 부산물을 삭제하는 Clean Rule으로 이다.
Makefile을 작성하는 공식 전체 메뉴얼 :
http://www.gnu.org/software/make/manual/make.html
이렇게 Makefile을 만든후
#make
를 실행하면 현재 폴더에 .ko파일이 생성된다.
(모듈 관련 명령어는 root 권한으로 실행해야한다. Permission denied 에러가 발생할시 sudo를 앞에 붙이거나 root로 로그인하면 된다.)
이후 만든 모듈을 적재할때는 insmod명령어를 사용하면 된다.
#insmod hello.ko
(insmod error: inserting './hello.ko': -1 Invalid module format"같은 에fj가 뜬다면 https://stackoverflow.com/questions/34379013/insmod-error-inserting-hello-ko-1-invalid-module-format
다른 모듈관련 명령어는 아래와 같이 있다.
모듈확인
#lsmod
모듈삭제
#rmmod hello
그후 dmesg를 사용하여 log를 확인할수 있다.
#dmesg
.
.
.
.
.
.
이런식으로도 가능하다..(4.19.0)
obj-m = hello.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
rm -rf *.mod.*
rm -rf *.o
rm -rf *.ko
rm -rf *.order
rm -rf *.symvers
모듈 컴파일과 현재 커널의 버전이 다를경우 에러가 나면서 insmod가 안되니 확인하자.
'Programming > Linux' 카테고리의 다른 글
우분투 커널 5.0 업그레이드 [How to upgrade linux Kernel 5.0 on ubuntu 18.04 LTS with ukuu] (0) | 2019.05.23 |
---|---|
우분투 버전 업그레이드 방법 [How to upgrade ubuntu 18.04 LTS] (0) | 2019.03.28 |
커널과 모듈의 개념 (2) | 2018.11.20 |
우분투 네트워크 오류 해결 [ubuntu network error] (8) | 2018.09.11 |
우분투 화면이 안보이는 현상,ubuntu Unknown Display ,Built-In Display, 일때 Display setting (0) | 2018.07.20 |