본문 바로가기

Embedded/Device Driver

Device Driver] Hello World 모듈 컴파일

Hello World 모듈을 만들어보자.

프로그래밍을 함에 있어서 맨 처음으로 작성하는 코드는 항상 Hello World일 것이다.
우리는 모듈로 이 Hello World를 만나보자!! ^───^,,

우리는 hello.c와 Makefile을 작성하고 
# make 명령으로 hello.ko 파일을 내고자 한다.
hello.ko 파일이 삽입될 모듈이다.

천천히 소스코드와 그 내용을 살펴보자.

hello.c
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 MODULE_LICENSE("GPL");

 int module_start()
 {
     printk ("Hello World!! \n");
     return 0;
 }
 
 void module_end()
 {
     printk ("Goodbye World!! \n");
 }  
 
 module_init(module_start);
 module_exit(module_end);

Makefile
CC := /usr/local/arm-linux-4.1.1/bin/arm-linux-gcc
obj-m := hello.o
KDIR := /lib/module/$(shell uname -r)/build

all:
make -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* .*.cmd 
우선 all: 아래의 종속절을 보자
make -C $(KDIR) SUBDIRS=$(PWD) modules

make 를 하게 되면 우선 지금 현재 리눅스 소스 안에서 default로 정의된 컴파일러를 사용한다.
그 컴파일러는
/usr/src/kernel/<version>/Makefile 을 열어보면
HOSTCC로 정의 된 녀석이 있을 것이다.
그러나 이 컴파일러외에 다른 컴파일러를 쓰고자 한다면 위의 코드와 같이
CC매크로를 정의해주면 된다.
예제 소스에서는
1번째라인 CC매크로에 4.1.1버전의 크로스 컴파일러를 설정해줬음을 볼 수 있다.

-C $(KDIR)은 Kernel Source Directory 를 알려줘야 하는데.
예제소스에서는
3번째 라인의 KDIR 매크로에 커널 소스의 최상의 디렉토리를 명명 해줬다.
( 현재 커널소스의 디렉토리는 /lib/module/$(shell uname -r)/build 에 링크 되어 있다 )
  예를 들어서 /home/kkang/linux-2.6.32.2 에 커널 소스를 받아놓고 이녀석에 맞는 모듈을 만들고자 한다면
  KDIR := /home/kkang/linux-2.6.32.2 라고 명시해줘야 한다.  

SUBDIRS=$(PWD)는 목적 파일을 만들기 위해 참조할 .c파일의 위치를 명시해줘야 한다.
예제 소스와 같이 그냥 $(PWD)라고 입력하면 make 명령시 현재 디렉토리로 잡는다.
 
목적파일은 2번째 라인에 명시 되어 있다.
obj-m := hello.o
그런데 obj-m 으로 목적파일을 명명해 줌을 볼 수 있다.
여기서 "m" 으로 적어 줌으로써 모듈임을 나타낸다.
"m"대신에 "y"를 쓰면 built-in 형식의 ko 파일을 만든다.

위의 두 소스코드를 작성 했으면 다음의 과정을 통해 
컴파일과 모듈 삽입/제거 를 해보자.

    컴파일
# make
    모듈 삽입
# insmod hello.ko
# tail -5 /var/log/messages
# modinfo hello.ko
    filename : hello.ko
    ...
    ... 
    모듈 제거
# rmmod hello