2022-06-05 리눅스_디바이스_드라이버_3

2022. 6. 5. 22:04BE/Linux

hello.c의 Makefile

 

  • Makefile에 대한 정리

Makefile 이해

 

2022-06-05 Makfile_이해

make, Makefile 이해 gcc C언어의 컴파일 과정 make Makefile의 구성 예시 gcc 명령어 사용 make 명령어 사용 Makefile 매크로 Makefile 보충 := , ?= 와 += 는 뭐지? $(OBJS:.o=.d) 는 뭐지? Makefile 조건문 Mak..

ramen4598.tistory.com

 

vi Makefile

make
ifneq ($(KERNELRELEASE),)
    obj-m := hello.o

else
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)

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

주의점 : 넓게 띄어 쓴 부분은 tab을 사용한다. Space bar를 사용하면 오류 난다.

 

  • ifneq ($(KERNELRELEASE),) : KERNELRELEASE라는 환경변수가 정의되어 있지 않다면 다음을 추가하라

 

  • obj-m := 모듈 이름 : obj-y 에 저장된 리스트들은 커널 컴파일 시 built-in 되어 커널 이미지의 일부가 되며(include), obj-m은 모듈로 컴파일될 리스트이며(modularize), obj- 는 컴파일 제외 리스트이다.

 

  • KERNELDIR ?= /lib/modules/$(shell uname -r)/build : KERNELDIR 변수가 정의되어있지 않았다면 값을 대입한다.

 

  • PWD := $(shell pwd) : 현재 디렉터리를 값으로 가지는 변수 선언.

 

  • -C : 기본적으로 MAKE는 make로 정의되어 있다. make 수행 시 해당 경로(커널 소스 위치)로 이동해서 빌드됨. 그리고 다시 돌아옴

 

  • M=$(PWD) : M=$PWD라는 옵션으로 현재 작업 디렉터리를 서브 디렉터리로 인식시켜 제작한 Makefile을 사용하게 된다.

 

  • Make then reads the Makefile there (in the kernel source dir). SUBDIRS is where your module source code is. (I think SUBDIRS is deprecated and M is used instead now).

 

  • $(MAKE) ~~ module : make 명령어가 다시 make 명령어를 부르는 중. module은 target인 듯. 실제 KERNELDIR의 위치에 Makefile을 열어보면 modules라는 target이 존재한다.

핵심은 커널의 소스가 있는 디렉터리와 hello.c가 위치한 디렉터리를 오가며 컴파일한다는 것이다.

 

완벽히 이해하려 노력했지만 모르는 것이 많아서 그럴 수 없었다. (교수님이 조금이라 설명해주시면 좋을 텐데…)

 

이해할 수 있게 된다면 그때 다시 와서 볼 수 있도록 하자.

 

출처 : https://kldp.org/node/73511

출처 : https://www.gnu.org/software/make/manual/make.html

출처 : http://egloos.zum.com/mokuzin21/v/2372474

출처 : http://www.eastsky.co.kr/Android_Board/11596366

출처 : https://unix.stackexchange.com/questions/122095/understanding-a-make-file-for-making-ko-files


실행

 

모듈을 실행하고 끌 터미널과 실시간으로 커널 메시지를 확인할 터미널 2개가 필요하다.

# 1번 터미널

cat /proc/kmsg
# 2번 터미널

insmod ./hello.ko

lsmod | grep hello

rmmod hello
  • 문제 발생

dmesg는 실행하면 Hello world의 실행 결과를 확인할 수 있다.

 

하지만 cat /proc/kmsg는 안됨.

 

printk log level의 문제는 아니었다. (https://whatmam.tistory.com/83)

 

  • 원인

교수님과 달리 logpath 혹은 syslogd 가 로그를 관리하고 있지 않았다. 그래서 /proc/kmsg가 비어있었던 것이다.

 

대신에 rsyslog라는 녀석이 시스템 로그를 관리하고 있었다. (https://m.blog.naver.com/sunchan683/221511250171)

 

rsyslog에서 시스템 로그가 기록되는 위치는 /var/log/kern.log다(https://dosunny.tistory.com/114)

 

# rsyslog의 커널 로그는 /var/log/kern.log다.
cat /var/log/kern.log

klogd, syslogd 데몬을 따로 만들어 주지 않는다면 /proc/kmsg에는 커널 메시지가 기록되지 않을 것이다.

 

syslog 설치

sudo apt-get install syslog-ng

이제 cat /proc/kmsg 를 실행하면 실시간으로 커널 메시지를 확인할 수 있다.

 


insmod, rmmod, lsmod

insmod //insert module. 커널에 kernel object file 삽입

rmmod // remove module. 커널에서 kernel object file 제거

lsmod // a list of loaded modules. 적재된 모듈 확인

예제

https://github.com/martinezjavier/ldd3

 

GitHub - martinezjavier/ldd3: Linux Device Drivers 3 examples updated to work in recent kernels

Linux Device Drivers 3 examples updated to work in recent kernels - GitHub - martinezjavier/ldd3: Linux Device Drivers 3 examples updated to work in recent kernels

github.com

 

 

LDD의 예제는 github에 많이 올라와있다.