ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 디바이스 드라이버 / 실습 환경 설정 및 준비
    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을 진행하면서 생겼거나

     

    새로운 커널 버전으로 적용시키고 리부팅하는 과정에서 생성된 것으로 생각된다.

     

     

     

    틀린점이 있다면 댓글 부탁드리겠습니다. 감사합니다.

     

     

    댓글

Designed by Tistory.