Linux
making makefile for device driver
반응형
making makefile
__KERNEL__ symbol definition
어떠한 헤더를 포함하기 전에 __KERNEL__ symbol을 define 해야 함
커널 내에 많은 kernel-specific content들이 이 symbol 없이는 unavailable
MODULE
#include <linux/module.h> 하기 전에 MODULE이 정의 되어 있어야 함
(driver를 제외하고 - 왜 ? driver는 kernel 내부로 directly linked)
__SMP__ <- optional (used on SMP machine)
kernel header를 including하기 전에 이것을 정의
ex.
#include <linux/config.h>
#indef CONFIG_SMP
#define __SMP__
#endif
-O flag
module write 경우에는 반드시 compier에게 명시해야 함
많은 함수들이 inline으로서 header file들 내에 선언 되어 있기 때문
gcc는 optimization이 enable되어 있지 않는 한, inline function들을 expand 하지 않음
이것으로 inline function들을 debugging 가능
Documentation/Changes 에서 돌리고 있는 compiler가 kernel과 match되는지 check 해야 함
Kernal and ompiler are developed at the same time
많은 group을 통해서 때때로 tool의 변화는 bug를 만들기도 함
어떤 경우는 separate package를 제공하기도 함
-Wall
all warnings
이것을 사용해서 (compiler flag) 모든 warning을 보게 함.
Linus의 코딩 style에 맞지 않는 경우 warning으로 만들기 도 함
Documentation/CodingStyle
여기의 내용을 반드시 읽어서 coding style을 익혀야 함
CFLAGS
make에 의해서 사용되는 CFLAGS variable 내에 위에서 언급한 flage들이 있으면 됨.
-r
object file들은 ld -r command에 의해서 join됨. (linker를 사용하지만, 실제로 linking operation은 아님)
ex.
minimal example
KERNELDIR = /usr/src/linux
includde $(KERNELDIR)/.config
CFLAGS = -D_ _KERNEL_ _ -DMODULE -I$(KERNELDIR)/include -O -Wall
ifdef CONFIG_SMP
CFLAGS += -D_ _SMP_ _ -DSMP
endif
all: skull.o
skull.o: skull_init.o skull_clean.o
$(LD) -r $? -o $@
clean:
rm -f *.o *? core
there is no .c file in the example above
because make is smart enough to change .c files to .o files
without using $(CC), $(CFLAGS)
Makefile is
include
shared library 생성 가능
static library 생성 가능
-static
gcc -static ... <-- with -static, output files compile are linked statically
and the size of these files are too big. So, it is required to reduce the size of files by using 'strip' like as follows
strip output_name
ex.
arm-nonoe-linux-gnueabi-strip output_name <- 사용하지 않는 symbol들의 strip
insmod
로 위의 방법을 compile된 kernel module을 loading한다.
loading + linking
mknod
compile 후, device driver에서 사용하는 device file /dev/virtual_device를 mknod로 생성
mknod /dev/virtual_Device c 300 0
; mknod로 device node를 생성
; /dev/virtual_device는 생성할 device file name
; c는 character device 의미 (b면 block device 의미)
; 300은 major number
; 0은 minor number
insmod virtual_device1.ko <- 자신이 compile한
생성된 문자 device node를 이용하기 윃서
문자 device driver를 설치하고, app.을 실행한다.
TEST
----
1. create a device driver
2. create a Makefile for the device driver
CC = gcc
obj-m := ku_ipc.o
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default :
$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.ko
rm -rf *.mod.*
rm -rf .*.cmd
rm -rf *.o
rm -f *.markers
rm -f *.order
rm -f *.symvers
rm -rf .tmp_versions
install :
insmod ku_ipc.ko
mknod /dev/ipc c 300 0
uninstall :
rmmod ku_ipc.ko
rm /dev/ipc -f
3. create an application
4. app.을 위한 Makefile
CC = gcc
CFLAGS = -O -g
LDFLAGS = -O -g
LDFLAGS = -O
OBJS = main.o
#LIBS = libproject.a
test: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
main.o: main.c
clean:
rm -f $(OBJS) test
.c.o:
$(CC) $(CFLAGS) $(DEFS) $(INCLUDES) -c $<
5. app.의 compile 및 test를 편리하게 하기 위한 batch file
batch_file.bat를 만들고 다음과 같이 내용을 채운 후,
make clean
make
./test
위 batch file은
./batch_file.bat 로 실행
6. device driver를 편리하게 등록 하기 위한 batch file 작성
make clean
make
mknod /dev/ku_ipc c 300 0
insmod ku_ipc.ko
Build 단계를 분리하기 (1. library file & object file --> 2. executable file)
HAL은 shared library의 형태 (*.so)
link는 안하고 단지 compile만 하려면, “-c” option을 붙인다.
gcc -c
그리고 link
MAIN_SRC = mymain
LIB_SRC1 = mylib_src_1
all : $(MAIN_SRC)
$(MAIN_SRC): $(MAIN_SRC).o $(LIB_SRC1).o
$(CC) $^ -o $@
$(MAIN_SRC).o: $(MAIN_SRC).c
$(CC) -c $^
$(LIB_SRC1).o: $(LIB_SRC1).c
$(CC) -c $^
makefile은 shellscript file임
program 가능
주석 가능 (“#”)
all 부터 시작
target : srouce
method
clean:
rm -f *.o target_name
.bashrc에
alias rm=’rm -i’ ← -i is always asking to remove
library creation
ar is used
ar [options] [archives] [member, member,...]
ar ruv target_name obj1.o obj2.o
archive
tar
gcc options
path 포함
-L [path]
library 포함
-l [library name]
gcc -o target_name target_source.o -L . -lpthread
여기서 경로는 . 현재 위치부터 임을 지정(위 예는 pthread.a를 . 현재 위치부터 찾으라는 것)
library의 type(*.a, *.so)를 지정하지 않음 -- 기본적으로 shared library를 사용
include
-I [path]
shared library compile
1) shared library compile
MAIN_SRC = main
LIB_OUT = lib_name.so
all : $(MAIN_SRC)
$(MAIN_SRC) : $(MAIN_SRC).o $(LIB_OUT)
$(CC) -o $@ $^ -L . -lpthread
$(LIB_OUT): $(LIB_SRC1).o
$(CC) -shared -o $@ @^
$(MAIN_SRC).o: $(MAIN_SRC).c
$(CC) -c $^
$(LIB_SRC2).o : $(LIB_SRC2).c
$(CC) -fPIC -c $(LIB_SRC2).c ← flag로 PIC (Position Independent Code)을 지정
shared library는 PIC 임
2) usage of the shared library
make -f Makefile.sharedlib으로 위 shared lib 사용 것을 해 보면,
gcc -fPIC -c lib_src1.c
gcc -fPIC -c lib_src2.c
gcc -shared -o libtarget_shared.so lib_src1.o lib_src2.o
gcc -o target_name -L . -l target_shared
3) conf for the shared library
shared는 위치를 알 수 있기에 공유가 가능(OS에서 공유 시켜줌)
공유 시켜주는 위치
설정과 관련된 것은 모두 /etc 에
/etc에 가보면 ld.so.conf 파일이 보인다.
UNIX의 linker는 ld
linker & loader
compiler 내 ld는 linking, OS내 ld는 loader
ld.so.conf <- shared library의 loading용 configuration file임
열어보면, vi ld.so.conf file내에는 다음과 같이 모든 conf file들을 include함
include /etc/ld.so.conf.d/-.conf ← 모든 conf를 include함
위에 포함되도록 ld.so.conf.d에 자신의 conf를 만들고 이 conf file내에 자신이 새롭게 추가한 shared library의 path를 지정한다.(pwd로 절대경로를 얻어서)
ex.
include .config <-- inclusion
PLATFORM =
CC = $(PLATFORM)gcc
ifeq ($(CONFIG_LIB), static) <-- CONFIG_LIB은 .config file 내에 정의
target : clean
@echo “CONFIG_LIB: $(CONFIG_LIB)”
$(MAKE) -C /root/linux_sample....
else
target:clean
@echo “CONFIG_LIB: $(CONFIG_LIB)”
$(MAKE) -C /root/linux_sample....
endif
즉, config 을 만들면 위 directory에 추가된다.
/etc/ld.so.conf.d# ← 여기에 들어가보면, 여거 conf가 존재
GL.conf libasound2.conf vmware-toos-libraries.conf
i486-linux-gnu.conf libc.conf
위 conf 중 어떤 것은 절대 경로로 지정된 것도 있음
나중에 shared lib을 사용하려면, shared library가 존재하는 path를 이렇게 지정해 주어야 한다.
현재 작업 중인 (shared lib.이 존재하는 절대 경로를 pwd로 알아내어 *.conf file에 지정한다.)
vi lib_shared.conf ← 에 넣는다.
ldconfig <-- 이제 위에서 지정한 것도 shared library로 path 지정 해 주는 명령어
ldconfig를 수행하면 conf file들을 쭉 읽어서 경로를 update함
.config file
make menuconfig 에서 설정한 설정 정보들이 저장되는 file
build 시마다 다른 makefile 사용하기
make -f Makefiles.staticlib <- 여러 개의 makefile이 존재할 때 특정 makefile을 지정할 수 있음
반응형
'Linux' 카테고리의 다른 글
Linux module example (skeleton code) (0) | 2015.03.10 |
---|---|
Linux Booting Procedure (0) | 2015.03.10 |
checking symbols/modules/devices @ Linux (0) | 2015.03.10 |
Kernel Trap (트랩) (0) | 2015.03.10 |
Linux의 kmalloc과 vmalloc에 대해서 (0) | 2015.03.10 |
댓글