라즈베리파이에 Real Time kernel 올리기

라즈베리파이에 Real Time kernel 올리기

필자는 라즈베리파이에서 Timing 이 아주 중요한 application 을 개발하고 있었다. 프로세스가 context switching 되어 나가는 동안 데이터를 처리하지 못해 문제가 발생하는 상황이었다.

그래서,  real time kernel 을 사용했다. 모든 kernel 관련된 작업이 마찬가지지만, 이 작업 또한 참 귀찮다. 한국어로 된 자료도 마땅한 것이 없기에 이 포스트를 작성한다.


배경 지식

  • Real Time Kernel & Linux
    Real Time Kernel 이 무엇이냐 하면, 개념적으로는 프로세스가 scheduling 될 때 잠시 멈추더라도 최대한 빨리 돌아와서 다시 수행하는 것을 의미한다.
    Linux 에서는 이를 Preemption 레벨을 조정하는 방법으로 구현? 적용? 한다.
  • PREEMPT_RT patch
    Linux 에서는 각 버전에 맞는 rt 패치를 받아서 kernel 소스 코드에 적용할 수 있다. 그리고 빌드 & 설치를 하면 된다. Patch는 git 의 commit 을 가져와서 꼽는다고 생각하면 대충 비슷하다.
    ( PREEMPT_RT Patch 참조 )
  • Raspberry Pi, Linux Cross-compile
    이 글을 읽는 사람 정도 되면, 아마 다 알 것 같긴 한데...
    RPI 는 ARM 기반 CPU 를 사용하고, 보통 우리는 x86 기반의 CPU를 고성능 컴퓨터로 사용한다.  RPI 에서 Linux 를 직접 빌드 하려고, 하면 너무 느리다. 그러다 보니 다른 x86 Linux 호스트에서 ARM 용 Linux 를 빌드하게 되는데, 이게 Cross-compile 이다.
    (요즘엔 Apple 이 ARM 기반 고성능 CPU를 내주고 있으니, 곧 상황이 달라질 지도?)
  • Docker
    필자는 Cross Compile 을 하기 위해서 Docker 위에 환경을 구축하고, 빌드 했다. Docker 는 굳이 설명 안 해도 다들 알겠지.

자 이제 시작해보자

0. 선 결과 요약

아래와 같이 "PREMPT_RT" 가 보이게 될 것 이다.

1. 환경

필자는 Raspberry Pi OS 를 사용한다.

현재 Raspberry Pi OS (구 Raspbian) 은 5.15 커널을 기반으로 한다.
(꽤 최근의 OS 를 쓰지 않으면, 새로 구매한 보드들은 동작하지 않기에 어쩔 수 없다.)

2. 설명

나도 처음부터 다 직접한 것은 아니다. 검색을 해보니 아주 좋은 소스가 있어서 이를 가지고 시작했다.
Docker & 빌드 코드 를 받아서 진행해보자.
간략하게 설명하자면,
- Docker 컨테이너 위에 빌드 환경을 설정한다.
- RT 최신 패치를 받아와서 적용한다.
- 빌드하고 image 로 만든다.

빌드 환경으로는 ubuntu 를 사용하도록 되어 있는데, 원하면 버전을 바꿀 수 있다.
빌드 타겟은 5.10 Linux 를 사용하게 되어있는데, 나는 5.15 가 필요하니 이를 살짝 바꿨다.
두 내용 모두 "Dockerfile" 을 열고 편집하면 된다.

안타깝게도 나는 빌드하고 생성된 image 를 sd card 에 굽고 사용했더니, RT 패치가 안되더라. 이유는 안 알아봤다.
이미 사용하고 있는 RPI 가 있으니, 거기에 빌드된 코드를 옮겨서 install 해버렸더니 잘 되더라.

3. 따라하기

A. x86 linux 시스템에 위 github repo를 clone 한다.

git clone https://github.com/jonhpark7966/rpi-rt-kernel.git

A - 1 (Optional). Docker 파일을 편집한다.
 필자는 linux 버전은 5.15 로 변경했다.

B. 빌드 & install

그냥 make 해도 되지만, 여러 문제를 해결해야 하니 자세하게 설명한다.
그래서 make custom 을 한다.
그러면 생성된 Docker Container 안으로 진입이 가능하다.

진입하면 다음과 같이 rpi-kernel 이 받아져 있고, patch 도 받아져 있다.

위 코드와 패치는 각각
- https://downloads.raspberrypi.org/raspios_lite_arm64/images/
- https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/
여기서 받아온다.

받아진 Linux 코드는 rpi-5.15.y 브랜치이고, git status 에서 확인할 수 있듯이 많은 내용이 patch 되어 있다.

자 여기서 한번 make menuconfig를 해서 확인해보자.


이렇게. Fully Preemptivle Kernel 이 활성화 되어있다. 이대로 빌드 하면 된다. 그 외 다른 설정들도 바꿀 수 있으니 원하시는 대로 설정하시길.

이제 빌드를 하면 되는데, 빌드는 아래 써있는 것들만 하면 된다.

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs

이제 빌드된 결과물들을 install 해야한다.
소스 포함에서 통째로 raspberry pi OS 로 옮기자.
나는 SCP 로 옮겼다. 워낙 기초적인 내용이니 생략한다.

Raspberry Pi OS 에서는 아래와 같이 install 하면 된다.
경로는 각자 알아서들 확인 해야한다.

make modules_install
make dtbs_install

cp /rpi-kernel/linux/arch/arm64/boot/Image /raspios/mnt/boot/$KERNEL\_rt.img
cp /rpi-kernel/linux/arch/arm64/boot/dts/broadcom/*.dtb /raspios/mnt/boot/
cp /rpi-kernel/linux/arch/arm64/boot/dts/overlays/*.dtb* /raspios/mnt/boot/overlays/
cp /rpi-kernel/linux/arch/arm64/boot/dts/overlays/README /raspios/mnt/boot/overlays/

Raspberry Pi OS 의 자세한 빌드&설치 내용은 공홈의 설명 링크를 참조하면 된다. 어떤것들을 설정하고, 빌드하고, 설치해야하는지 아주 잘 써져있다.
( Raspberry PI 공홈 가이드 참조 )

여기 까지 했으면, 다 된 것이다!

uname -a

했을시 PREMPT_RT 가 잘 나오면 된다!


이상으로 간략한 관련 지식 설명과, 하는 법을 안내했다.
RT 관련 작업은 처음 해보았는데, 생각보다는 어렵지 않다. RT 패치를 linux 버전이 올라감에 따라 계속 maintain 되고 있다는 것이 놀라웠다. 누가 왜 하는 건지...
덕분에 나는 개꿀