2022-06-13 리눅스_디바이스_드라이버_5
2022. 6. 13. 02:23ㆍBE/Linux
Makefile 연습
main.c
#include <stdio.h>
int main(void){
printf("hello\n");
#ifdef SCULL_DEBUG
printf("World\n");
#endif
return 0;
}
Makefile
TARGET = main
SOURCE = main.c
CC = gcc
all :
$(CC) $(SOURCE) -O2 -o $(TARGET)
clean :
rm -f $(TARGET)
-O2
: Optimization 최적화, 최적화 레벨 2
- 최적화 옵션 : 실행 파일의 크기를 줄이고, 실행 속도를 향상시킨다.
-O0
: 최적화를 수행하지 않는다.-O1
: -O0보다는 높은 수준의 최적화. (=-O
)-O2
: 가장 많이 사용하는 수준의 최적화. 일반 응용 프로그램이나 커널을 컴파일할 때 사용.-O3
: 가장 높은 수준의 최적화. 모든 함수를 인라인 함수와 같이 취급한다.( 되도록이면 사용을 지양)-O5
: 사이즈 최적화를 실행한다. (공간이 협소한 곳에서 사용 - 임베디드 시스템)
TARGET = main
SOURCE = main.c
CC = gcc
#SCULL_DEBUG=y
ifeq ($(SCULL_DEBUG), y)
CFLAGS = -O -g -o
else
CFLAGS = -O2 -o
endif
all :
$(CC) $(SOURCE) $(CFLAGS) $(TARGET)
clean :
rm -f $(TARGET)
gdb라는 디버거를 사용할 때는 위의 CFLAGS
를 사용한다.
이유는 -O2
옵션을 사용하면 최적화를 위해서 코드의 순서가 변형되기에 -g
의 이용이 불가하다.
그래서 디버깅 때는 위에 라인을, 디버깅이 끝나면 아래 코드를 사용하도록 한다.
- 디버깅 옵션
-g
: gdb에게 제공하는 정보를 바이너리에 삽입한다. (-g 옵션을 사용하지 않고 gdb로 디버깅하면, 역어셈 → 어셈블리 코드로만 디버깅 가능)-pg
: 프로파일을 위한 코드를 삽입한다. (-pg 옵션으로 컴파일 → gmon.out(프로파일 정보) → gprof로 gmon.out 파일 분석)
gdb는 the GNU Project debugger다.
출처 : https://jangpd007.tistory.com/220
출처 : https://jangpd007.tistory.com/220 [참 놀라운 세상:티스토리]
LDD example install
git clone https://github.com/martinezjavier/ldd3.git
cd ldd3
make
강의 시간에 사용할 예제를 다운로드한다. (뭔지는 모르겠지만 일단은 ;;)
/ldd3/scull/Makefile
# Comment/uncomment the following line to disable/enable debugging
#DEBUG = y
# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)
DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
else
DEBFLAGS = -O2
endif
LDDINC=$(PWD)/../include
EXTRA_CFLAGS += $(DEBFLAGS)
EXTRA_CFLAGS += -I$(LDDINC)
ifneq ($(KERNELRELEASE),)
# call from kernel build system
scull-objs := main.o pipe.o access.o
obj-m := scull.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.mod modules.order *.symvers
depend .depend dep:
$(CC) $(EXTRA_CFLAGS) -M *.c > .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
scull
cd scull
ll
3개의 shell script : scull.init, scull_load, scull_unload
scull_load
#!/bin/sh
# $Id: scull_load,v 1.4 2004/11/03 06:19:49 rubini Exp $
module="scull"
device="scull"
mode="664"
# Group: since distributions do it differently, look for wheel or use staff
if grep -q '^staff:' /etc/group; then
group="staff"
else
group="wheel"
fi
# invoke insmod with all arguments we got
# and use a pathname, as insmod doesn't look in . by default
insmod ./$module.ko $* || exit 1
# retrieve major number
major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices)
# Remove stale nodes and replace them, then give gid and perms
# Usually the script is shorter, it's scull that has several devices in it.
rm -f /dev/${device}[0-3]
mknod /dev/${device}0 c $major 0
mknod /dev/${device}1 c $major 1
mknod /dev/${device}2 c $major 2
mknod /dev/${device}3 c $major 3
ln -sf ${device}0 /dev/${device}
chgrp $group /dev/${device}[0-3]
chmod $mode /dev/${device}[0-3]
rm -f /dev/${device}pipe[0-3]
mknod /dev/${device}pipe0 c $major 4
mknod /dev/${device}pipe1 c $major 5
mknod /dev/${device}pipe2 c $major 6
mknod /dev/${device}pipe3 c $major 7
ln -sf ${device}pipe0 /dev/${device}pipe
chgrp $group /dev/${device}pipe[0-3]
chmod $mode /dev/${device}pipe[0-3]
rm -f /dev/${device}single
mknod /dev/${device}single c $major 8
chgrp $group /dev/${device}single
chmod $mode /dev/${device}single
rm -f /dev/${device}uid
mknod /dev/${device}uid c $major 9
chgrp $group /dev/${device}uid
chmod $mode /dev/${device}uid
rm -f /dev/${device}wuid
mknod /dev/${device}wuid c $major 10
chgrp $group /dev/${device}wuid
chmod $mode /dev/${device}wuid
rm -f /dev/${device}priv
mknod /dev/${device}priv c $major 11
chgrp $group /dev/${device}priv
chmod $mode /dev/${device}priv
major 넘버와 minor 넘버를 할당하고 /dev 아래 디바이스 디렉터리를 만드는 과정
scull이 들어간 많은 디바이스들이 만들어진다.
➜ scull git:(master) ✗ ls -l /dev/scull*
zsh: no matches found: /dev/scull*
➜ scull git:(master) ✗ ./scull_load
➜ scull git:(master) ✗ ls -l /dev/scull*
lrwxrwxrwx 1 root root 6 Jun 7 15:39 /dev/scull -> scull0
crw-rw-r-- 1 root staff 243, 0 Jun 7 15:39 /dev/scull0
crw-rw-r-- 1 root staff 243, 1 Jun 7 15:39 /dev/scull1
crw-rw-r-- 1 root staff 243, 2 Jun 7 15:39 /dev/scull2
crw-rw-r-- 1 root staff 243, 3 Jun 7 15:39 /dev/scull3
lrwxrwxrwx 1 root root 10 Jun 7 15:39 /dev/scullpipe -> scullpipe0
crw-rw-r-- 1 root staff 243, 4 Jun 7 15:39 /dev/scullpipe0
crw-rw-r-- 1 root staff 243, 5 Jun 7 15:39 /dev/scullpipe1
crw-rw-r-- 1 root staff 243, 6 Jun 7 15:39 /dev/scullpipe2
crw-rw-r-- 1 root staff 243, 7 Jun 7 15:39 /dev/scullpipe3
crw-rw-r-- 1 root staff 243, 11 Jun 7 15:39 /dev/scullpriv
crw-rw-r-- 1 root staff 243, 8 Jun 7 15:39 /dev/scullsingle
crw-rw-r-- 1 root staff 243, 9 Jun 7 15:39 /dev/sculluid
crw-rw-r-- 1 root staff 243, 10 Jun 7 15:39 /dev/scullwuid
scull 실행
scull_load
를 실행해서 /dev/scull*
파일을 생성하고 쓰고 읽어 보았다.
➜ scull git:(master) ✗ cat > /dev/scull0
hello world
^D
➜ scull git:(master) ✗ cat /dev/scull0
hello world
ctrl+D
: cat 입력 종료
scull_unload
➜ scull git:(master) ✗ ./scull_unload
➜ scull git:(master) ✗ ls -l /dev/scull*
zsh: no matches found: /dev/scull*
'BE > Linux' 카테고리의 다른 글
2022-06-29 다중사용자, 슈퍼유저 (1) | 2022.06.29 |
---|---|
2022-06-28 Cron_실행 (0) | 2022.06.28 |
2022-06-13 리눅스_디바이스_드라이버_4 (0) | 2022.06.13 |
2022-06-05 리눅스_디바이스_드라이버_3 (0) | 2022.06.05 |
2022-06-05 Makfile_이해 (0) | 2022.06.05 |