hello.c의 Makefile
- Makefile에 대한 정리
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
endifCode language: JavaScript (javascript)
주의점 : 넓게 띄어 쓴 부분은 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).
SUBDIRSis where your module source code is. (I thinkSUBDIRSis deprecated andMis 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/kmsgCode language: PHP (php)
# 2번 터미널
insmod ./hello.ko
lsmod | grep hello
rmmod helloCode language: PHP (php)
- 문제 발생
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.logCode language: PHP (php)
klogd, syslogd 데몬을 따로 만들어 주지 않는다면 /proc/kmsg에는 커널 메시지가 기록되지 않을 것이다.
syslog 설치
sudo apt-get install syslog-ngCode language: JavaScript (javascript)
이제 cat /proc/kmsg 를 실행하면 실시간으로 커널 메시지를 확인할 수 있다.
insmod, rmmod, lsmod
insmod //insert module. 커널에 kernel object file 삽입
rmmod // remove module. 커널에서 kernel object file 제거
lsmod // a list of loaded modules. 적재된 모듈 확인Code language: JavaScript (javascript)
예제
LDD의 예제는 github에 많이 올라와있다.