-
디바이스 드라이버 / 실습 환경 설정 및 준비Linux/Linux Device Driver 2020. 9. 1. 12:36
디바이스 드라이버은 커널에 적재되기 때문에 디바이스 드라이버 코드를 컴파일하기 위해서는 커널 소스가 따로 필요하다.
https://johnjarrer.tistory.com/110
디바이스 드라이버 / 커널 소스가 필요한 이유
타깃 보드에 이미 리눅스 커널이 올려져 있는데 디바이스 드라이버 코드를 컴파일하기 위해서는 커널 소스가 따로 필요하다.?? 뭔 소리일까? 디바이스 드라이버는 커널 영역에 적재되어 동작하�
johnjarrer.tistory.com
pi@raspberrypi:~/Downloads $ git clone http://github.com/raspberrypi/linux.git
git명령어를 사용하면 최신 버전의 커널을 다운로드할 수 있다.
pi@raspberrypi:~/Downloads $ sudo mv linux /usr/src
일반적으로 리눅스 커널 소스 코드는 /usr/src 디렉터리에 위치한다. 나도 똑같이 다운로드한 커널 소스를 /usr/src 디렉터리에 옮겨줬다.(레드헷이나 우분투 등의 배포판에서 커널 소스는 일반적으로 /usr/src/linux 디렉터리에 위치하고 있다.)
이제 커널을 컴파일하기 전 설정하자
근데 /arch/arm/configs/에 들어가면 bcm2709_defconfig, bcm2711_defconfig, bcm2835_defconfig, bcmrpi_defconfig 이렇게 4개가 존재한다. 라즈베리파이4는 BCM2711 SOC을 사용하니까 bcm2711_defconfig를 하면 되지만 나머지 SOC라즈베리파이3 B+로 치면 BCM2837 SOC와 딱 맞게 떨어지진 않는다. ;; 그래서 찾아봤는데 SOC가 아니라 HW(Silicon die)였다.
https://www.raspberrypistarterkits.com/comparison/raspberry-pi-3-pi-2-pi-b-benchmark-review/
Raspberry Pi 3 vs Pi 2 vs Pi B+ (Benchmark & Review)
Check the benchmarks, features, specs, & comparison of Raspberry Pi 3 Vs 2 Vs B+ models. These reviews will help you choose the most suitable circuit board.
www.raspberrypistarterkits.com
그럼 어떤건 맞고 어떤 건 맞아떨어지지 않는 것인가??;;
https://qastack.kr/raspberrypi/840/why-is-the-cpu-sometimes-referred-to-as-bcm2708-sometimes-bcm2835
CPU가 때때로 BCM2708, 때로는 BCM2835라고 불리는 이유는 무엇입니까?
qastack.kr
글을 읽어보니 한 개의 실리콘 다이(HW)로 여러 SOC를 만든다면 어느 부분 기준으로 의견이 달라서 그런 것 같다.
예를 들면 라즈베리파이2 B+ 모델과 라즈베리파이3 B 모델은 BCM2709로 제품군은 같은데 구현된 SOC는 BCM 2846과 BCM2837로 나와서 어느 것으로 정해야 하는지 모호해서 그런 거지 않을까??
어쨌든 라즈베리파이 공식 문서에서 제품별로
Raspberry Pi 1, Pi Zero, Pi Zero W
KERNEL=kernel
make bcmrpi_defconfig
Raspberry Pi 2, Pi 3, Pi 3+
KERNEL=kernel7
make bcm2709_defconfig
Raspberry Pi 4
KERNEL=kernel7l
make bcm2711_defconfig
이렇게 하라고 하니 그냥 하자. 나는 Raspberr Pi 3이기 때문에 중간 거다.
pi@raspberrypi:/usr/src/linux $ KERNEL=kernel7
pi@raspberrypi:/usr/src/linux $ make bcm2709_defconfig
..
..
bison: not found
비손이 없단다..
깔아주자
pi@raspberrypi:/usr/src/linux $ sudo apt-get install bision
다시 설정하자
pi@raspberrypi:/usr/src/linux $ make bcm2709_defconfig
..
..
flex: not found
플랙스가 없단다
깔아주자
pi@raspberrypi:/usr/src/linux $ sudo apt-get install flex
설정 완료..
flex랑 bison이 있으면 그냥 설정이 완료될 것이다. 나는 없어서 깔아줌
설정이 완료되면 .config파일이 만들어진다.
pi@raspberrypi:/usr/src/linux $ ls -al
라즈베리파이3 B+모델은 BCM2709 HW를 사용하기 때문에 make bcm2709_defconfig를 하면 라즈베리파이3 B+에 가장 알맞게 설정이되고, 이 설정들이 .config파일에 모아지게 된다. 라즈베리파이3 B+에 가장 알맞은 설정들이 모여졌으니 이제 컴파일 하자~
pi@raspberrypi:/usr/src/linux $ make zImage modules dtbs -j4
bc: not found
bc가 없단다..
깔아주자
pi@raspberrypi:/usr/src/linux $ sudo apt-get install bc
다시 컴파일
pi@raspberrypi:/usr/src/linux $ make zImage modules dtbs -j4
make zlmage 의미
위에서 make bcm2709_defconfig 한 대로 커널을 빌드하는 것을 의미한다.
arch/arm/boot 디렉터리에 zImage가 생성된다. 모듈은 따로 빌드해야 된다.
make modules 의미
모듈을 빌드한다.
make dtbs 의미
이제 모듈을 설치한다.
pi@raspberrypi:/usr/src/linux $ sudo make modules_install
make modules_install 의미
make modules로 빌드된 모듈을 /lib/modules/'uname -r' 디렉터리를 만들고 모듈을 복사(?)한다.
이제 컴파일한 커널의 정보로 수정하는 작업을 진행한다
pi@raspberrypi:/usr/src/linux $ cp arch/arm/boot/zImage /boot/$KERNEL.img
pi@raspberrypi:/usr/src/linux $ cp arch/arm/boot/dts/*.dtb /boot
pi@raspberrypi:/usr/src/linux $ cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays
pi@raspberrypi:/usr/src/linux $ cp arch/arm/boot/dts/overlays/README /boot/overlays
위 작업은 다운로드한 커널을 현재 시스템에 적용시키는 것이다.
리부팅하기 전 현재 커널 버전을 확인해보자
pi@raspberrypi:~ $ uname -r
리부팅시켜준다.
pi@raspberrypi:/usr/src/linux $ sudo reboot
pi@raspberrypi:~ $ uname -r
커널 버전이 4.19.97-v7+ -> 4.19.115-v7+로 변경되었다.
근데 굳이 커널 버전을 바꿔줘야 할까??
내 생각은 내려받은 커널 버전과 현재 동작중인 커널 버전이 같으면 굳이 안 바꿔줘도 될 것 같다. 하지만 커널 버전이 달라지면 커널 함수가 조금 달라질 것이고 커널 함수가 달라진다는 뜻은 커널 함수 위치도 달리지기 때문에 커널 심벌 테이블에 있는 커널 함수 별 주소가 달라져서 빌드는 가능해도 커널로 적재하면 오류가 생길지 않을까??
테스트해보자.
pi@raspberrypi:~/Documents/test $ nano test.c
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("KOOK"); static int module_begin(void) { printk(KERN_ALERT, "Hello, Wellcom to module!!\n"); return 0; } static void module_end(void) { printk(KERN_ALERT, "Gooybye, Exit module!!\n"); } module_init(module_begin); module_exit(module_end);
pi@raspberrypi:~/Documents/test $ nano Makefile
obj-m := test.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: make -C $(KDIR) M=$(PWD) modules clean: make -C $(KDIR) M=$(PWD) clean
pi@raspberrypi:~/Documents/test $ make
현재 로드된 모듈을 살펴보자.
pi@raspberrypi:~/Documents/test $ lsmod
모듈을 로드하자.
pi@raspberrypi:~/Documents/test $ sudo insmod test.ko
현재 로드된 모듈을 살펴보자.
pi@raspberrypi:~/Documents/test $ lsmod
test 모듈이 삽입되어있다.
커널 메시지 버퍼를 확인하자.
pi@raspberrypi:~/Documents/test $ dmesg
빨간색으로 Hello 어쩌고가 나온다.
모듈을 제거하자.
pi@raspberrypi:~/Documents/test $ sudo rmmod test
커널 메시지 버퍼를 확인하자.
pi@raspberrypi:~/Documents/test $ dmesg
빨간색으로 Goodbye 어쩌고가 나온다.
성공
위에서 make를 실행했을 때 다음과 같이 출력된다.
나는 Makefile에서 KDIR := /lib/modules/$(shell uname -r)/build 이라고 명시해놨는데
뜬금없이 Entering directory '/usr/src/linux'라고 나온다.
왜 그럴까?
/lib/modules/4.19.115-v7+ 디렉터리에서 ls -al 명령어를 사용하면
build 파일과 source 파일이 뭔가 다른 색이고 ->로 /usr/src/linux를 가리키고 있다.
맞다.
링크 파일이었던 거다. 정확하게는 심볼릭 링크가 되어있다.
그래서 KDIR := /lib/modules/$(shell uname -r)/build라고 지정해도 결국 /usr/src/linux로 넘어갔던 거다..
심볼릭 링크는 make modules_install을 진행하면서 생겼거나
새로운 커널 버전으로 적용시키고 리부팅하는 과정에서 생성된 것으로 생각된다.
틀린점이 있다면 댓글 부탁드리겠습니다. 감사합니다.
'Linux > Linux Device Driver' 카테고리의 다른 글
디바이스 드라이버 / 모듈 파일들의 정체 (0) 2020.09.01 디바이스 드라이버 / 커널 소스가 필요한 이유 (0) 2020.09.01 디바이스 드라이버 / 개발 방법 (0) 2020.09.01 디바이스 드라이버 / 헤더 파일별 함수 정의 (0) 2020.08.30 디바이스 드라이버 / 알게 된 것들 (0) 2020.08.28