# 실시간 커널 설정 방법

Preempt RT 패치를 적용한 리눅스 커널을 설치하고 나면, 이를 실시간 운영 환경에 맞게 설정하는 단계가 필요하다. 이 장에서는 실시간 커널 설정을 통해 시스템의 성능과 안정성을 최적화하는 방법을 다루겠다. 실시간 시스템은 지연 시간(latency)을 최소화하고 일관된 응답 시간을 보장해야 하기 때문에, 적절한 설정이 필수적이다.

#### 1. 커널 설정 도구 사용

리눅스 커널의 설정은 `menuconfig` 등의 인터페이스를 통해 수행할 수 있다. 일반적으로 다음 명령어를 사용하여 커널 설정 메뉴를 엽니다.

```bash
make menuconfig
```

`menuconfig`는 텍스트 기반의 인터페이스로, 커널 옵션을 손쉽게 탐색하고 설정할 수 있게 해준다.

#### 2. Preempt RT 관련 주요 설정

Preempt RT 커널에서 중요한 설정 항목은 다음과 같다. 각 항목은 실시간 성능을 극대화하기 위해 조정될 수 있다.

**a. CONFIG\_PREEMPT\_RT**

* **옵션 경로:** `Kernel Features → Preemption Model → Fully Preemptible Kernel (RT)`
* **설명:** 이 옵션은 Preempt RT 패치를 활성화하여 커널이 최대한의 선점성을 제공하도록 설정한다. 이 설정은 실시간 요구사항을 충족시키기 위한 핵심적인 설정이다.

**b. CONFIG\_HZ**

* **옵션 경로:** `Processor type and features → Timer frequency`
* **설명:** 타이머 주파수를 설정하는 옵션이다. 일반적인 리눅스 커널에서는 250Hz 또는 1000Hz로 설정되지만, 실시간 시스템에서는 1000Hz 이상으로 설정하는 것이 일반적이다. 예를 들어 1000Hz로 설정하면 시스템 타이머가 1밀리초 단위로 인터럽트를 발생시킨다.
* **설정 예시:** 1000Hz

```latex
\text{CONFIG\_HZ} = 1000
```

**c. CONFIG\_NO\_HZ\_FULL**

* **옵션 경로:** `Processor type and features → Tickless System (Dynamic Ticks) → Full dynticks system (tickless)`
* **설명:** 이 옵션은 CPU가 유휴 상태일 때 타이머 틱(tick)을 완전히 제거하는 기능을 제공한다. 이는 실시간 애플리케이션에서 불필요한 인터럽트를 줄이고 지연 시간을 최소화하는 데 도움이 된다.

**d. CONFIG\_HIGH\_RES\_TIMERS**

* **옵션 경로:** `Kernel Features → High Resolution Timer Support`
* **설명:** 고해상도 타이머를 활성화하여 높은 정확도로 타이머를 설정할 수 있게 한다. 실시간 응용 프로그램에서는 정밀한 타이밍이 중요하기 때문에 이 옵션은 반드시 활성화해야 한다.

```latex
\text{CONFIG\_HIGH\_RES\_TIMERS} = y
```

#### 3. CPU 관련 설정

**a. CPU Isolation**

* **옵션 경로:** `Processor type and features → Isolating CPUs`
* **설명:** 특정 CPU를 실시간 작업에 전용으로 사용할 수 있게 설정한다. 이는 실시간 작업이 다른 시스템 작업으로 인해 방해받지 않도록 하는 데 유용하다. 이 설정을 통해 선택된 CPU는 일반적인 시스템 작업 스케줄링에서 제외된다.

**b. CPU Frequency Scaling**

* **옵션 경로:** `Power management and ACPI options → CPU Frequency scaling`
* **설명:** CPU 주파수 스케일링을 비활성화하거나 고정된 주파수를 사용하도록 설정한다. 이는 주파수 변경으로 인한 지연 시간을 방지하기 위한 것으로, 실시간 시스템에서는 CPU가 일정한 주파수로 동작하도록 설정하는 것이 권장된다.

#### 4. IRQ 설정

**a. IRQ Affinity 설정**

* **설명:** IRQ(Interrupt Request)의 처리가 특정 CPU에서만 이루어지도록 설정하여 인터럽트 처리로 인한 실시간 작업의 지연을 최소화한다. 이를 위해 `/proc/irq/IRQ_NUMBER/smp_affinity` 파일을 통해 특정 CPU에 IRQ를 할당할 수 있다.

```bash
echo 2 > /proc/irq/IRQ_NUMBER/smp_affinity
```

위 예시에서 `2`는 CPU 1에 해당하는 마스크 값이다.

#### 5. 커널 명령줄 파라미터 설정

커널 부팅 시 사용되는 명령줄 파라미터를 설정하여 실시간 성능을 최적화할 수 있다. 다음은 실시간 커널에서 자주 사용되는 파라미터들이다.

* **`isolcpus=`**: 특정 CPU를 일반 스케줄러에서 제외하고 실시간 작업에만 사용할 수 있도록 설정한다.
* **`irqaffinity=`**: 인터럽트 처리에 사용되는 CPU를 제한하여 실시간 CPU가 인터럽트 처리에 방해받지 않도록 한다.
* **`nohz_full=`**: 특정 CPU에서 틱 없는 모드를 활성화한다.
* **`rcu_nocbs=`**: RCU(Read-Copy-Update) 콜백 처리를 특정 CPU에서만 하도록 설정하여 실시간 작업이 방해받지 않도록 한다.

명령줄 설정은 GRUB 등의 부트로더 설정 파일을 통해 추가할 수 있다.

#### 6. 커널 컴파일 및 설치

커널 설정이 완료되면, 설정된 옵션을 기반으로 커널을 컴파일하고 설치해야 한다. 일반적인 컴파일 및 설치 과정은 다음과 같다.

**a. 커널 컴파일**

커널을 컴파일하기 전에, `make` 명령을 사용하여 필요한 초기 설정을 적용할 수 있다.

```bash
make -j$(nproc)
```

여기서 `$(nproc)`은 사용 가능한 CPU 코어 수를 의미하며, 모든 코어를 사용하여 병렬 컴파일을 수행한다. 컴파일 시간이 상당히 소요될 수 있으므로, 시스템 자원을 최대한 활용하는 것이 좋다.

**b. 모듈 설치**

커널 모듈을 설치하기 위해 다음 명령을 사용한다.

```bash
sudo make modules_install
```

이 명령은 새로 컴파일된 커널에 필요한 모든 모듈을 시스템에 설치한다.

**c. 커널 설치**

커널 이미지 및 기타 관련 파일을 설치하기 위해 다음 명령을 사용한다.

```bash
sudo make install
```

이 명령은 커널 이미지를 `/boot` 디렉토리에 복사하고, 부트로더(GRUB)가 이를 인식할 수 있도록 설정 파일을 업데이트한다.

#### 7. GRUB을 통한 커널 선택 및 부팅

새로운 커널을 설치한 후, 시스템 부팅 시 해당 커널을 선택할 수 있도록 GRUB 부트로더를 설정해야 한다.

**a. GRUB 업데이트**

커널이 설치된 후, GRUB 설정을 업데이트하여 새로 설치된 커널이 부팅 메뉴에 나타나도록 한다.

```bash
sudo update-grub
```

이 명령은 GRUB 설정 파일을 갱신하여 새로 추가된 커널을 포함시킨다.

**b. 커널 선택**

시스템 부팅 시, GRUB 메뉴에서 새로 설치한 Preempt RT 커널을 선택한다. 일반적으로 GRUB 메뉴는 부팅 시 `Shift` 키를 누르고 있으면 나타난다.

**c. 부팅 확인**

새로운 커널로 부팅한 후, 다음 명령어로 커널 버전 및 Preempt RT 설정을 확인할 수 있다.

```bash
uname -r
```

출력된 커널 버전에 "rt"가 포함되어 있으면, Preempt RT 커널이 성공적으로 설치되고 부팅된 것이다.

#### 8. 실시간 커널 설정의 검증

커널이 성공적으로 설치되었다면, 실시간 성능을 검증해야 한다. 다음은 실시간 시스템의 성능을 확인하는 데 도움이 되는 몇 가지 방법이다.

**a. Latency 확인**

`cyclictest`와 같은 도구를 사용하여 시스템의 지연 시간을 측정할 수 있다. 이 도구는 주기적인 타이머 인터럽트를 통해 시스템의 최대 지연 시간을 측정한다.

```bash
cyclictest -l1000000 -m -n -q
```

이 명령어는 최대 100만 회의 타이머 인터럽트를 측정하며, 최대 지연 시간을 결과로 출력한다.

**b. 스케줄링 확인**

`chrt` 명령어를 사용하여 특정 프로세스에 실시간 스케줄링 정책을 적용하고, 이를 통해 시스템이 실시간 요구사항을 충족하는지 확인할 수 있다.

```bash
sudo chrt -f 99 ./실시간프로그램
```

위 명령어에서 `-f 99`는 FIFO 스케줄링 정책을 우선순위 99로 적용하는 것을 의미한다. `./실시간프로그램`은 실행할 실시간 애플리케이션이다.

#### 9. 시스템 리소스 모니터링

실시간 시스템에서의 성능을 모니터링하기 위해, `htop`, `top`, `iotop` 등 다양한 모니터링 도구를 사용할 수 있다. 이러한 도구들은 CPU 사용량, I/O 활동, 메모리 사용량 등을 실시간으로 모니터링하여 시스템의 실시간 성능을 평가하는 데 도움이 된다.

특히, `htop`과 같은 도구를 사용하여 특정 CPU에 할당된 작업을 실시간으로 모니터링하고, 실시간 작업이 예상대로 실행되고 있는지 확인할 수 있다.

#### 10. 추가 설정 및 최적화

마지막으로, 시스템에 특화된 실시간 요구사항에 따라 추가적인 설정 및 최적화가 필요할 수 있다. 이러한 설정은 실시간 애플리케이션의 특성에 따라 다르며, 다음과 같은 요소들을 고려할 수 있다.

* **NUMA 설정**: NUMA(Numerical Memory Access) 시스템에서 메모리 접근 지연을 최소화하기 위해 메모리와 CPU 간의 최적화를 수행한다.
* **IRQ Balance**: 실시간 작업의 성능을 위해 특정 CPU에 IRQ를 집중시키는 대신, IRQ를 균형 있게 분산시킨다.
* **메모리 잠금**: 실시간 애플리케이션이 메모리 페이지 교체로 인해 지연되지 않도록 메모리를 잠가서 교체를 방지한다.

이와 같은 설정을 통해 시스템이 실시간 요구사항을 충족하도록 더욱 최적화할 수 있다.
