
라즈베리파이 리눅스 커널 소스 빌드 (크로스 컴파일)
- 빌드 패키지 (도구) 설치
* 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시간 이상 소요)
$ 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 버전)

- 빌드 설정 파일(.config) 생성
* 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
- 빌드 하기 (make) 약 40분 소요
* 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와 같이 코어 개수를 직접 입력해주는게 더 빠른거 같던데 기분 탓인가?

- 모듈 설치 하기(make modules_install), 마이크로 SD카드 마운트
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 마운트

- 모듈 설치 하기(make modules_install)
* 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/
- 커널 설치 (install)
* 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카드를 라즈베리파이에 넣고 부팅한다.
- 커널 버전 일치하는지 확인


- 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