ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 디바이스 드라이버 작성 with Raspberry Pi 4B (1) - 개발 환경 구축
    카테고리 없음 2026. 7. 20. 21:59

    0. 준비물 구비

    라즈베리파이가4가 너무 비싸져서 눈물을 머금고 샀다.. ㅠㅠ 구매 옵션에 "OS가 동봉되어 있는/없는 SD카드" 옵션이 있었는데, 앞으로 임베디드 공부를 계속 해나갈 생각이라 좀 더 좋은 SD카드를 갖추고 있는 게 더 좋지 않을까 하는 생각이 들었고 이번 기회에 OS를 직접 구워보는 것도 좋은 경험일 것 같아서 따로 구매했다. (라즈베리파이5 어댑터는 구매하지 않아도 상관은 없는데, 지금 집에 라즈베리파이5는 있고 어댑터가 따로 없어서 사는 김에 같이 사게 되었다.)

     

    1. WSL2 우분투 설치

    1) PowerShell을 관리자 권한으로 실행한다.

    2) 다음 명령어를 통해 wsl2를 설치한다.

    wsl --install

    완료 화면

     

    재부팅하면 우분투가 자동으로 실행되면서 설치가 마무리된다고 하는데, 내 경우에는 그렇지 않아서 우선 상태를 확인한 후, Ubuntu를 명시적으로 설치했다.

    wsl -l -v 			# 현재 wsl의 상태 확인
    wsl --install -d Ubuntu 	# Ubuntu를 명시적으로 설치

     

    그런데도 ubuntu를 실행할 수가 없어서 wsl을 업데이트했다. wsl2 설치 후 이것 먼저 실행하는 게 맞았을 것 같다.

    wsl --update



    완료되고, wsl을 실행시키면 몇 가지 설정을 한다. 

    Ubuntu 성능 향상에 도움이 되도록 사용자 report를 전송할 지를 물어보는 것으로, 굳이 할 필요는 없다. 나는 n을 누르고 다음으로 넘어갔다.
    계정을 만든다. ID 및 비밀번호 입력
    WSL2 Ubuntu 설치 완료

     

     

    3) 크로스 컴파일 도구를 설치한다.

    sudo apt update
    sudo apt install -y git bc bison flex libssl-dev make libc6-dev \
    	libncurses5-dev crossbuild-essential-arm64

     

     

    2. SD카드에 OS 굽기

    0) 준비물 (0. 준비물 구비 항목 참고)

    여기서부터 Raspberry Pi 4B와 SD카드를 준비한다. 내 경우엔 Sandisk Extreme microSD 64GB를 준비했다.

    (사진에는 없지만, Raspberry 4B를 구동하기 위해서는 어댑터(5V 3A)도 함께 필요하다.) 

    (케이스도 같이 사긴 했는데, 이후에 케이스를 낀 채로 어댑터를 연결하니 구동이 제대로 되지 않아서, 당분간은 빼고 진행하기로 했다 ㅠ)

     

     

    1) Raspberry Pi Imager를 설치한다.

    https://www.raspberrypi.com/software/ 에서 Windows용을 다운로드하여 설치한다.

     

    2) SD카드를 노트북 microSD 슬롯에 꽂는다.

     

    3) 1)에서 다운로드한 Imager를 실행 후 다음 사진들과 같이 항목들을 선택한다.

     

    hostname, username은 원하는 대로 지정해도 되는데, 내 경우에는 hostname은 rpi4로, username은 내가 자주 사용하는 닉네임인 monghwa로 지정했다.

     

    Wi-Fi 설정 말고, 유선랜을 통해서도 진행할 수 있는데, 내 경우에는 Wi-Fi를 설정시킨 후 진행하였다.

     

    Write 단계에서 OS가 구워지는데 5~10분 정도 소요됐다.

    (Raspberry Pi Connect는 굳이 활성화할 필요 없다.)

     

     

     

    3. WSL2 Ubuntu에서 Raspberry Pi 4B에 접속

    1) OS 굽기가 끝나면 SD카드를 노트북에서 빼서 라즈베리파이4B에 꽂고, 어댑터에 연결한다.

    Raspberry 4B에 SD카드를 삽입한 모습

     

    2) WSL 우분투 터미널에서 ssh를 통해 접속 

    ssh monghwa@rpi4.local

    (username을 monghwa, hostname을 rpi4로 설정하였다는 가정 하의 코드)

     

    내 경우엔  rpi4.local 명령어로 접속이 되지 않고 timed out 에러가 발생해서, 다른 방법을 통해 접속했다. 공유기에서 Pi의 실제 IP를 찾은 다음, 그 IP로 직접 접속하였다.

    ssh monghwa@192.168.x.x 	# 실제 IP 주소 기입

     

    3) 커널 버전을 확인한다.

    uname -r



     

    4. 커널 소스 다운로드 

    4-1) WSL 우분투 터미널에서, kernel_build라는 새로운 폴더를 만든 후, 그 폴더에 커널 최신 스냅샷을 다운로드한다.

    mkdir -p ~/kernel_build
    cd ~/kernel_build
    git clone --depth=1 --branch rpi-6.18.y https://github.com/raspberrypi/linux
    
    cd linux	# 다운로드한 후 linux 폴더를 연다.

    (--depth=1 은 히스토리 없이 최신 스냅샷만 받는 옵션)

    다운로드 중 화면

     

     

    4-2) Raspberry Pi 4B 표준 설정을 불러온다.

    make O=../out ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig

    완료되면, .config 생성 메시지가 뜬다.



     

    4-3) 이제 커널을 빌드한다.

    make O=../out ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image modules dtbs

    이 과정에서 시간이 가장 많이 걸렸다. 보통 20분~1시간 정도 걸린다고 하던데, 내 경우에는 1시간 조금 안 되게 걸렸던 것 같다. 중간에 터미널을 닫거나 종료하면 안 되기 때문에 시간적으로 여유가 있는 상황에서 빌드하는 것이 좋다.

    빌드 중 화면
    빌드 정상 완료 화면

     

     

    빌드 결과를 확인하기 위해서, 다음 명령어들을 입력한다.

    ls -lh ../out/arch/arm64/boot/Image
    ls ../out/arch/arm64/boot/dts/broadcom/*.dtb | head
    ls ../out/arch/arm64/boot/dts/overlays/*.dtbo | head

    첫 번째는 Image 파일을 확인하는 것으로 크기가 수십 MB정도이면 커널 본체가 잘 생긴 것으로 볼 수 있다. 두 번째 줄과 세 번째 줄은 각각 dtb와 dtbo를 확인하는 것으로, 파일 리스트가 잘 나열되면 디바이스 트리도 정상임을 확인할 수 있다.

     

     

    4-4) out 디렉터리로 이동한 다음, 모듈을 설치한다.

    make O=../out ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
    	INSTALL_MOD_PATH=../out/modules_install modules_install

     

     

    4-참고) Pi의 기존 커널 및 모듈을 백업한다.

    이 작업은 Pi에 ssh를 통해 접속한 터미널에서 수행한다.

    ssh monghwa@192.168.x.x
    
    # 접속 후
    sudo cp /boot/firmware/kernel8.img /boot/firmware/kernel8-backup.img
    uname -r	# 버전 확인

     

     

    4-5) Pi에 받을 디렉터리를 만든 후 빌드 결과물들을 Pi로 전송한다.

    WSL 터미널에서 커널 이미지, 디바이스 트리, 모듈을 전송하게 된다.

    우선 Pi에 받을 폴더를 생성한 후, 

    mkdir -p ~/kernel_deploy

     

    WSL 터미널에서 순서대로 전송한다.

    cd ~/kernel_build/out
    
    # 커널 이미지 전송
    scp arch/arm64/boot/Image monghwa@192.168.x.x:~/kernel_deploy/
    
    # 디바이스 트리(broadcom dtb) 전송
    scp arch/arm64/boot/dts/broadcom/*.dtb monghwa@192.168.x.x:~/kernel_deploy/
    
    # 오버레이(dtbo) 전송
    scp monghwa@192.168.x.x "mkdir -p ~/kernel_deploy/overlays"
    scp arch/arm64/boot/dts/overlays/*.dtbo monghwa@192.168.x.x:~/kernel_deploy/overlays/
    
    # 모듈 전체 전송
    scp -r modules_install/lib/modules/6.18.34+rpt-rpi-v8 monghwa@192.168.x.x:~/kernel_deploy/

     

    다만, 내 경우에 마지막 모듈 전체 전송에서 에러가 발생했는데, "6.18.34+rpt-rpi-v8"라는 폴더를 찾을 수 없다는 에러였다. WSL2 폴더를 확인해보니 kernel/out/modules_install/lib/moduels에 "6.18.38-v8+"라는 폴더가 들어있었다. SD카드에 처음 OS를 구울 때, 즉 Imager를 통해 OS를 다운받았을 때 들어있던 버전은 6.18.34였지만, 4-1)의 git clone을 통해 내려받은 버전은 6.18.38로(최신화가 계속해서 이루어지기 때문에) 달랐던 것이다. 마지막 줄만 이 버전에 맞춰서 수정하면,

    scp -r "modules_install/lib/modules/6.18.38-v8+" monghwa@192.168.x.x:~/kernel_deploy/

     

    원래라면 이대로 전송이 이루어졌어야 하는데, 1시간을 넘게 기다려도 터미널 화면에 파일명이 계속 올라가길래 뭔가 문제가 생긴 것 같다는 생각이 들었다. 터미널을 유심히 보니, 같은 이름의 파일명이 반복해서 나타난다거나 중간에 "Maximum directory depth exceeded: 64 levels"라는 에러 메시지도 함께 보였다. 즉시 중단(Ctrl + C)하고, 

    rm -rf ~/kernel_deploy/6.18.38-v8+

    Pi에 남아있는 불완전한 파일들을 삭제한다. (위 명령어는 Pi 터미널에서 실행)

    불완전 파일 삭제 후, 폴더 내용 확인

     

    파일을 하나하나 보내는 이전의 방법에서 모듈을 통째로 tar 압축 파일로 묶어서 보내는 방법으로 선회했다. WSL 우분투 터미널에서,

    cd ~/kernel_build/out/modules_install/lib/modules
    tar -czf ~/modules.tar.gz "6.18.38-v8+"
    
    # tar 파일 크기 확인
    ls -lh ~/modules.tar.gz

    파일 크기가 22M인 걸 확인

    파일 크기를 확인했을 때, 수십 MB~200MB정도이기만 하면 정상이다. 내 경우엔 22MB인 걸 확인하고 진행했다.

    이제 이 tar 파일을 전송한다.

    scp ~/modules.tar.gz monghwa@192.168.x.x:~/kernel_deploy/

     

     

     

    4-6) 전송된 파일들을 Pi 터미널 내에서 실제 부팅 위치에 배치시킨다.

    모듈 압축을 푼 뒤, 6.18.38-v8+ 폴더가 생겼는지 ls로 확인한다.

    cd ~/kernel_deploy
    tar -xzf modules.tar.gz
    ls



    이제 커널 이미지와 디바이스 트리를 교체한다.

    # 새 커널로 교체
    sudo cp Image /boot/firmware/kernel8.img
    
    # 디바이스 트리 교체
    sudo cp *.dtb/boot/firmware/
    sudo cp overlays/*.dtbo /boot/firmware/overlays/

     

    모듈을 설치한다. 이때 depmod는 모듈 간 의존성 정보를 새로 만드는데, 새 커널이 부팅 시 모듈을 제대로 찾기 위해 필요한 작업이다. 

    sudo cp -r 6.18.38-v8+ /lib/modules/
    sudo depmod 6.18.38-v8+

     

     

    4-7) 최종 점검 및 재부팅을 수행한다.

    각 ls 명령어로 파일들이 제대로 있는지를 최종 점검한다.

    # 1. 백업이 있는지 확인
    ls -lh /boot/firmware/kernel8-backup.img
    
    # 2. 새 커널이 제대로 있는지 확인
    ls -lh /boot/firmware/kernel8.img
    
    #3. 새 모듈 폴더가 있는지 확인
    ls -d /lib/modules/6.18.38-v8+

     

    확인되면, 재부팅한다. 이때 SSH 연결이 끊기므로, 1~2분후에 다시 SSH로 Pi에 연결하여 커널 버전을 확인하도록 한다.

    # 재부팅
    sudo reboot
    
    # ssh로 재접속
    ssh monghwa@192.168.x.x
    
    # 커널 버전 확인
    uname -r

    그 결과가 6.18.38-v8+라면 성공이다!

     

     

    댓글

Designed by Tistory.