라즈베리파이 리눅스 커널 소스 빌드 (크로스 컴파일)

이세현's avatar
Jun 19, 2024
라즈베리파이 리눅스 커널 소스 빌드 (크로스 컴파일)
라즈베리파이 리눅스 커널 소스 빌드 (크로스 컴파일)
  1. 빌드 패키지 (도구) 설치
    1. * Vmware, 호스트 PC에 설치 1. 크로스-컴파일용 패키지(도구) 설치 $ sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev 2. 크로스 컴파일러 설치 * 32비트 크로스 컴파일러 $ sudo apt install crossbuild-essential-armhf // arm-linux-gnueabihf- * 64비트 크로스 컴파일러 $ sudo apt install crossbuild-essential-arm64 // aarch64-linux-gnu- 라즈베리파이에서 gcc -v -> target -> GCC 컴파일러의 버전과 타겟 아키텍처 정보 확인
 
  1. 커널 소스 다운로드
    1. * 전체 소스 다운로드(변경 이력 포함, 1시간 이상 소요) $ git clone https://github.com/raspberrypi/linux * 현재 최신 버전 다운로드(active branch) $ git clone --depth=1 https://github.com/raspberrypi/linux * 원하는 버전(브랜치) 다운로드(약 20 분 소요) $ git clone --depth=1 --branch rpi-6.6.y https://github.com/raspberrypi/linux 커널 소스를 다운로드 받으면 현재 경로에 linux 디렉토리가 생성된다. 모듈 Makefile 구현 시 KDIR 변수에 linux 디렉토리의 절대 경로(pwd)를 넣어준다. longterm 버전 (안정화된 버전)을 선택하는게 좋다. $ git checkout rpi-6.6.y (longterm 버전)
      다운 받은 커널 소스 경로 (linux 디렉토리)
      다운 받은 커널 소스 경로 (linux 디렉토리)
       
  1. 빌드 설정 파일(.config) 생성
    1. * linux 디렉토리에서 .config 생성 1. 빌드 설정 파일(.config) 생성 (32 비트) * 라즈베리파이3B, 3B+ cd linux KERNEL=kernel7 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig * 라즈베리파이4B cd linux KERNEL=kernel7l make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig 2. 빌드 설정 파일(.config) 생성 (64 비트) * 라즈베리파이 3b, 3b+, 4B cd linux KERNEL=kernel8 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
 
  1. 빌드 하기 (make) 약 40분 소요
    1. * 32비트 빌드 make -j$(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs * 64비트 빌드 make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs -j$(nproc)보단 -j4와 같이 코어 개수를 직접 입력해주는게 더 빠른거 같던데 기분 탓인가?
      linux/arch/arm/boot에 zImage가 생성된다.
      linux/arch/arm/boot에 zImage가 생성된다.
  1. 모듈 설치 하기(make modules_install), 마이크로 SD카드 마운트
    1. micro SD카드를 호스트 PC(Vmware)에 연결 lsblk (디스크, 파티션 정보) mkdir mnt mkdir mnt/fat32 mkdir mnt/ext4 sudo mount /dev/sdb1 mnt/fat32 // bootfs 마운트 sudo mount /dev/sdb2 mnt/ext4 // rootfs 마운트
      sd 카드 연결 후 lsblk 실행 화면, 위와 같이 인식해야 한다.
      sd 카드 연결 후 lsblk 실행 화면, 위와 같이 인식해야 한다.
       
  1. 모듈 설치 하기(make modules_install)
    1. * 32비트 sudo env PATH=$PATH make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- \ INSTALL_MOD_PATH=mnt/ext4 modules_install // 32비트 modules_install --> mnt/ext4/lib/modules/kernel-version/ * 64비트 sudo env PATH=$PATH make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \ INSTALL_MOD_PATH=mnt/ext4 modules_install // 64비트 modules_install --> mnt/ext4/lib/modules/kernel-version/
       
  1. 커널 설치 (install)
    1. * 32비트 sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img sudo cp arch/arm/boot/zImage mnt/fat32/$KERNEL.img sudo cp arch/arm/boot/dts/broadcom/*.dtb mnt/fat32/ sudo cp arch/arm/boot/dts/overlays/*.dtb* mnt/fat32/overlays/ sudo cp arch/arm/boot/dts/overlays/README mnt/fat32/overlays/ sudo umount mnt/fat32 sudo umount mnt/ext4 zImage 설치 --> mnt/fat32/boot/kernel7.img dtb 설치 --> mnt/fat32/boot/ * 64비트 sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img sudo cp arch/arm64/boot/Image mnt/fat32/$KERNEL.img sudo cp arch/arm64/boot/dts/broadcom/*.dtb mnt/fat32/ sudo cp arch/arm64/boot/dts/overlays/*.dtb* mnt/fat32/overlays/ sudo cp arch/arm64/boot/dts/overlays/README mnt/fat32/overlays/ sudo umount mnt/fat32 sudo umount mnt/ext4 Image 설치 --> mnt/fat32/boot/kernel8.img dtb 설치 --> mnt/fat32/boot/ 설치가 완료되면 sd카드를 라즈베리파이에 넣고 부팅한다.
       
  1. 커널 버전 일치하는지 확인
    1. 호스트 PC(Vmware)에서 빌드한 커널 버전 6.6.32
      호스트 PC(Vmware)에서 빌드한 커널 버전 6.6.32
      라즈베리파이 커널 버전 6.6.32 (반드시 일치해야함)
      라즈베리파이 커널 버전 6.6.32 (반드시 일치해야함)
  • hello.c 모듈 컴파일
    • // SPDX-License-Identifier: GPL-2.0-only /* * hello.c * */ #define pr_fmt(fmt) "MY-MODULE: " fmt #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> static int __init example_init(void) { pr_info("Hello world.\n"); return 0; } static void __exit example_exit(void) { pr_info("Goodbye world.\n"); } module_init(example_init); module_exit(example_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Linux");
      크로스 컴파일 APP := p238_ledkey_app MOD := p238_ledkey_dev SRC := $(APP).c obj-m := $(MOD).o CROSS = ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- CC := arm-linux-gnueabihf-gcc KDIR := /home/ubuntu/workspace/projects/linux PWD := $(shell pwd) default:$(APP) $(MAKE) -C $(KDIR) M=$(PWD) modules $(CROSS) @if ! ssh sehyeon@ip exit; then \ echo "SSH connection failed, skipping scp"; \ else \ scp $(MOD).ko sehyeon@ip:/home/sehyeon/workspace; \ fi $(APP): $(CC) $(APP).c -o $(APP) @if ! ssh sehyeon@ip exit; then \ echo "SSH connection failed, skipping scp"; \ else \ scp $(APP) sehyeon@ip:/home/sehyeon/workspace; \ fi clean: rm -rf *.ko rm -rf *.mod.* rm -rf .*.cmd rm -rf *.o rm -rf modules.order rm -rf Module.symvers rm -rf $(MOD).mod rm -rf .tmp_versions rm -rf $(APP) ---------------------------------------------------------------------------------- 로컬 컴파일 obj-m := hello.o all: modules modules: make -C /lib/modules/${shell uname -r}/build M=$(PWD) modules clean: make -C /lib/modules/${shell uname -r}/build M=$(PWD) clean*/
  • SSH 키 생성
    • ssh-keygen -t rsa -b 4096 -C "your_email@example.com" // SSH 키 생성,여러 프롬프트가 떠도 그냥 엔터 ssh-copy-id sehyeon@ip // SSH 키 라즈베리파이로 복사 ssh sehyeon@ip // SSH 접속 시 비밀번호를 묻지 않는다면 성공 /*scp 명령어 실행 시 라즈베리파이 계정 비밀번호 입력이 필요한데 매번 비밀번호를 입력하지 않고 자동으로 파일을 전송할 수 있다.*/
Share article

isehyeon258