이 기사는 실시간 특성을 지원하는 몇 가지 리눅스 아키텍처를 살펴보고 실시간 아키텍처가 실제로 무엇을 의미하는지 설명한다. 몇 가지 해법이 리눅스에 실시간 능력을 부여하고 있으며, 이 기사에서 마이크로 커널 접근 방법, 나노 커널 접근 방법, 자원 커널 접근 방법을 분석하겠다. 마지막으로 표준 2.6 커널에 들어있는 실시간 기능을 설명하고 이를 활성화해 사용하는 방법을 보여주겠다.
다음은 실시간 리눅스 아키텍처를 설명하는 단계에서 필요한 실시간 정의다. 이 정의는 Donald Gillies가 운영하는 실시간 컴퓨터 FAQ에서 가져왔다(참고자료 참조).
실시간 시스템은 계산의 정확성이 단순히 논리적인 계산 정확성뿐만 아니라 결과를 만들어내는 시간에 의존한다. 시스템의 시간 제약을 충족하지 못하면, 시스템에 실패가 일어났다고 말한다.
다시 말해, 시스템은 (최소 부하에서 최악의 부하에 이르기까지) 다양한 부하 상황에서 타이밍 행동 양식을 보장하도록 결정된 스케줄링을 제공해야 한다. 위에서 내린 정의는 성능에 대해 아무런 언급도 없음에 주목하자. 실시간은 속력에 대한 개념이 아니라 예측 가능성에 대한 개념이기 때문이다. 예를 들어, 요즘 나오는 고속 프로세서를 사용하면, 리눅스는 전형적인 인터럽트 반응을 20μ 내에 끝낼 수 있지만, 종종 반응 속력이 늦어지는 경우도 생긴다. 이는 근본적인 문제다. 리눅스가 빠르지 않거나 비효율적이라는 이야기가 아니라 결정된 스케줄링을 제공하지 못할 뿐이라는 이야기다.
몇 가지 예제는 이런 개념이 의미하는 바를 잘 나타낸다. 그림 1은 인터럽트 대기 시간 측정 결과를 보여준다. 인터럽트가 도착하면(이벤트), CPU에 인터럽트가 걸리고, 인터럽트 처리 모드로 들어간다. 동일한 작업은 어떤 이벤트가 벌어졌는지 결정해, 추가 작업을 거친 다음에 원하는 태스크를 가져와 이벤트를 처리하도록 만든다(문맥 전환). 인터럽트 도착과 필요한 작업을 가져오는(가장 우선순위가 높은 태스크로 가정한다) 과정에서 벌어지는 시간적인 차이를 반응 속력이라고 부른다. 실시간에서, 반응 속력은 결정된 스케줄링을 따라야 하며, 알려진 최악의 시간 내에 처리되어야 한다.
그림 1. 인터럽트 대기 시간과 반응 시간
이런 과정을 소개하는 유용한 예는 오늘날 많이 쓰이는 표준 에어백이다. 자동차 충돌을 보고하는 센서가 CPU에 인터럽트를 걸면, 운영체제는 다른 비실시간 처리가 방해하지 못하도록 재빠르게 에어백을 전개하는 태스크를 가져와야 한다. 2초 늦게 터지는 에어백은 없느니만 못하다.
인터럽트 처리에 결정된 스케줄링을 고려하는 이외에, 실시간 처리를 위해 주기적인 휴지 기간을 두고 동작하는 태스크 스케줄링도 필요하다. 그림 2를 살펴보자. 이 그림은 주기적인 태스크 스케줄링을 보여준다. 많은 제어 시스템이 주기적인 표본 추출과 처리를 요구한다. 정해진 기간(p)에, 시스템 안정성을 높이기 위해 특정 태스크를 수행해야 한다. 자동차 ABS(Anti-lock Braking System)를 생각해보자. 이 제어 시스템은 자동차에 달려있는 각 바퀴 속력을 표본 추출해 (브레이크가 잠겨버리지 않도록) 초당 20회에 걸쳐 브레이크 압력을 각각 제어한다. 제어 시스템이 동작하려면, 센서 표본 추출과 통제 시스템은 주기적인 휴지 기간을 두고 수행되어야 한다. 이는 ABS 태스크가 원하는 주기에 걸쳐 수행하도록 다른 처리 과정을 선점해야 함을 의미한다.
그림 2. 주기적인 태스크 스케줄링
(심지어 최악의 처리 부하에서도) 실시간 태스크에 원하는 데드라인을 제공할 수 있는 운영체제를 딱딱한 실시간 시스템으로 부른다. 하지만 딱딱한 실시간 지원은 모든 경우에 필요한 기능은 아니다. 평균적으로 데드라인을 지원할 수 있는 운영체제를 부드러운 실시간 시스템으로 부른다. 딱딱한 실시간 시스템은 데드라인을 놓치는 순간 (에어백이 너무 늦게 터지거나 브레이크 압력을 너무 오래 거는 등) 재앙이 벌어진다. 부드러운 실시간 시스템은 (비디오 프레임 손실 등) 전반적인 시스템이 실패하지 않은 상황에서 데드라인을 놓칠 수도 있다.
이제 실시간 요구 사항에 대해 통찰력을 얻었으므로, 어떤 수준까지 어떻게 실시간을 지원하는지 몇 가지 리눅스 실시간 아키텍처를 살펴보기로 하자.
마이크로 커널 접근 방법은 하드웨어와 리눅스 커널 사이에 추상화된 인터페이스로 두 번째 커널을 사용한다(그림 3 참조). 비실시간 리눅스 커널은 마이크로 커널 위에서 낮은 우선순위 태스크로 배경에서 동작하며, 모든 비실시간 태스크를 담당한다. 실시간 태스크는 마이크로 커널 위에서 직접 동작한다.
그림 3. 딱딱한 실시간을 위한 마이크로 커널 접근 방법
(실시간 태스크를 수행하는 이외에) 마이크로 커널이 담당하는 주된 작업은 인터럽트 관리다. 마이크로 커널은 인터럽트를 가로채어 비 실시간 커널이 마이크로 커널 연산을 선점하지 못하도록 보장한다. 이는 마이크로 커널이 딱딱한 실시간 지원을 제공하도록 만든다.
비록 마이크로 커널 접근 방법에는 (딱딱한 실시간 커널 지원을 표준 리눅스 커널과 공존하게 만드는) 장점이 있지만, 이런 접근 방법에는 단점도 있다. 실시간과 비실시간 태스크가 독립적이므로, 디버깅을 더욱 어렵게 만든다. 또한 비실시간 태스크는 완벽한 리눅스 플랫폼 지원을 받지 못한다(마이크로 커널 수행을 마이크로라고 부르는 이유를 생각해보자).
이런 접근 방법 예는 (이제 윈드 리버 시스템이 소유한 독점 소프트웨어인) RTLinux와 RTAI(Real-Time Application Interface), Xenomai를 포함한다.
마이크로 커널 접근 방법이 태스크 관리를 포함한 최소화한 커널에 의존하는 반면에, 나노 커널 접근 방법은 커널을 좀더 최소로 만들도록 한발자국 더 나간다. 이런 방식으로 커널 특성을 줄이고 HAL(Hardware Abstraction Layer) 특성을 늘린다. 나노 커널은 고차원에서 여러 운영체제 시스템이 운영하도록 하드웨어 자원을 공유하는 기능을 제공한다(그림 4 참조). 나노 커널은 하드웨어를 추상화하므로, 고차원 운영체제를 위한 우선순위화를 제공하므로 결국 딱딱한 실시간도 지원이 가능하다.
그림 4. 하드웨어 추상화를 위한 나노 커널 접근 방법
나노 커널 접근 방법과 다중 운영체제를 동작하기 위한 가상화 접근 방법에 유사성이 있음에 주목하자. 이 경우, 나노 커널 추상화는 실시간과 비실시간 커널로부터 하드웨어를 추상화한다. 이는 손님 운영체제로부터 실제 하드웨어를 하이퍼바이저가 추상화하는 방식과 비슷하다. 필요한 정보는 참고자료를 참조하자.
나노 커널 접근 방법의 예는 ADEOS(Adaptive Domain Environment for Operating Systems)다. ADEOS는 여러 운영체제를 동시에 돌리는 기능을 지원한다. 하드웨어 사건이 발생하면, ADEOS는 운영체제에 연쇄적으로 질의를 던저 사건을 처리할 대상을 찾아나선다.
실시간을 위한 또 다른 아키텍처는 자원 커널 접근 방법이다. 이 접근 방법은 모듈을 커널에 추가해 다양한 자원 유형을 예약한다. 이와 같은 예약 기법은 (CPU, 네트워크, 디스크 대역폭과 같은) 시스템 자원을 시분할해 접근하도록 보장한다. 각 자원마다 반복 시간, 필요한 처리 시간(다시 말해 처리에 필요한 전체 시간), 데드라인 등 여러 예약 매개변수를 포함한다.
자원 커널은 API 집합을 제공해 태스크가 자원 예약 요청을 하도록 만든다(그림 5 참조). 자원 커널은 요청을 합쳐 태스크가 정의한 제약 조건을 사용해 접근을 보장하거나 보장이 불가능할 경우에 오류를 반환한다. EDF(Earliest-Deadline-First)와 같은 스케줄링 알고리즘을 사용해 동적 스케줄링 작업 부하를 처리하는 데 커널을 사용한다.
그림 5. 자원 예약 기법을 위한 자원 커널 접근 방법
자원 커널 구현 예로 CMU에서 만든 리눅스/RK가 있는데, 적재 가능한 모듈로 이식 가능한 자원 커널을 리눅스에 통합하는 방식을 사용한다. 이런 구현 방법은 상용인 TimeSys 리눅스/RT로 발전했다.
지금까지 아키텍처 상으로 흥미로운 접근 방법을 설명했는데, 모두 커널 주변을 둘러싸고 동작한다. 이렇게 하는 대신에, 실시간을 지원하기 위해 표준 리눅스 커널이 필요한 변경 내역을 포함하면 어떨까?
오늘날, 2.6 커널에서 간단한 커널 환경 설정을 통해 커널을 완벽하게 선점 가능하도록 만들어서 부드러운 실시간 기능을 활용할 수 있다(그림 6 참조). 표준 2.6 리눅스 커널에서, 사용자 영역 프로세스가 (시스템 호출을 통해) 커널 내부로 서비스를 호출할 때, 선점이 불가능하다. 이는 낮은 우선순위 프로세스가 시스템 호출을 부를 때, 높은 우선 순위 프로세스는 CPU 접근 권한을 얻기 위해 낮은 우선순위 프로세스가 요청한 호출이 끝나기를 기다려야 한다는 사실을 의미한다. 새로운 환경 설정 옵션인 CONFIG_PREEMPT는 이런 커널 동작 방식을 바꿔서 (심지어 프로세스가 시스템 호출 중간에 있더라도) 높은 우선 순위 작업이 작업을 수행해야 할 경우 프로세스를 선점하도록 허용한다.
그림 6. 선점이 가능한 표준 2.6 리눅스 커널
하지만 이 환경 설정 옵션에는 교환 조건이 있다. 이 옵션이 부드러운 실시간 기능을 활성화하며, 심지어 부하가 걸리는 상황에서도 운영체제를 좀 더 부드럽게 돌아가도록 만들긴 하지만, 대가를 치뤄야 한다. 약간 떨어지는 작업량과 커널 성능 저하라는 비용을 지불해야 하는 이유는 CONFIG_PREEMPT 옵션으로 인한 부하가 추가로 걸리기 때문이다. 이 옵션은 데스크톱과 임베디드 시스템에 유용하지만 서버와 같은 시스템에는 적합하지 않을지도 모른다.
2.6 커널에서 또 다른 유용한 환경 설정 옵션은 고해상도 타이머다. 이 새 옵션은 (기반 하드웨어가 뒷받침할 경우) 타이머를 1μ 해상도로 동작하게 만들며, 또한 효율을 위해 레드-블랙 트리로 타이머를 관리한다. 레드-블랙 트리를 사용하면, 타이머 하위 시스템 성능에 영향을 미치지 않고 대규모 타이머를 O(log n) 시간에 활성화할 수 있다.
조금만 수고하면, PREEMPT_RT 패치를 적용해 딱딱한 실시간 지원이 가능하다. PREEMPT_RT 패치는 딱딱한 실시간 지원을 위해 여러 가지 변경 내역을 담고 있다. 몇 가지 변경 내역을 살펴보면 커널 잠금 기본 구성 요소를 완전히 선점이 가능하도록 다시 구현했으며, 커널 내부 뮤텍스를 위한 우선 순위 상속을 구현했으며, 인터럽트 처리기를 커널 스레드로 변환해 완벽하게 선점이 가능하도록 만들었다.
리눅스는 실시간 알고리즘 실험과 구현을 위한 완벽한 플랫폼은 아니지만 오늘날 표준 2.6 커널에 탑재된 실시간 기능을 확인할 수 있다. 표준 커널을 사용해 부드러운 실시간 성능을 활용하거나 아니면 (커널 패치 등으로) 좀 더 작업해 딱딱한 실시간 응용 프로그램을 만들 수도 있다.
이 기사는 리눅스 커널에 실시간 컴퓨팅이 가능하도록 만드는 몇 가지 기법을 개괄했다. 실시간 태스크를 표준 커널에서 분리하도록 초기에는 마이크로 커널 접근 방법을 다양하게 시도했다. 나중에는 나노 커널 접근 방법이 등장해 오늘날 가상화 해법에서 사용하는 하이퍼바이저와 아주 비슷한 기술을 선보였다. 마지막으로 리눅스 커널은 딱딱하고 부드러운 실시간 수단을 독자적으로 제공한다.
이 기사는 리눅스를 위한 실시간 방법을 겉으로 보고 넘어가지만, 참고자료 절에서 추가 정보를 얻는 방법과 다른 유용한 실시간 기법에 대한 좀 더 많은 정보를 제공한다.
교육
- 팀이 쓴 "가상 리눅스"(한국 developerWorks, 2007년 2월)에서는 오늘날 아주 인기있고 유용한 가상화 아키텍처에서 빌어온 마이크로 커널과 나노 커널 접근 방법을 설명한다.
- 팀이 쓴 "Inside the Linux scheduler"(developerWorks, 2006년 6월)에서 2.6 커널에 탑재된 O(1) 스케줄러에 대해 살펴보자.
- developerWorks에서 팀이 쓴 모든 ... 분석 기사를 읽어보자.
- developerWorks에서 팀이 쓴 모든 리눅스 기사를 읽어보자.
- Realtime Computing FAQ는 실시간 컴퓨팅에 대한 출발점으로 휼륭한 자료다. 이 FAQ는 POSIX, 실시간 운영체제, 실시간 분석 관련 자료를 다룬다.
- "Real-time Control Systems"(PDF)는 A. Gambier가 작성한 흥미로운 튜토리얼로 실시간 제어 시스템 설계를 소개하며, 다양한 스케줄링 알고리즘을 논한다.
- 6th Real-time Linux Workshop(2007년 11월 열림)에서 첨단 실시간 리눅스 기술을 확인하는 논문과 자료를 구하자.
- 초기 RTLinux, RTAI, Xenomai는 모두 마이크로 커널 접근 방법을 적용했다. 응용 프로그램은 조금씩 다르지만, 전반적인 접근 방법은 가치가 있음이 판명났다.
- ADEOS는 하드웨어 추상화 층(HAL)이나 나노 커널이며, 리눅스 커널에 실시간 기능을 제공한다. ADEOS는 또한 SMP 클러스터링이나 커널 디버깅을 위해서도 쓰인다.
- "Portable RK: A Portable Resource Kernel for Guaranteed and Enforced Timing Behavior"는 자원 예약 API를 통해 시분할 자원(CPU, 네트워크, 디스크) 접근을 보장하기 위한 구성 요소를 설명한다.
- 레드-블랙 트리는 자체적으로 균형 잡힌 이진 탐색 트리다. 비록 알고리즘 자체는 복잡하지만, 현실에서 아주 효율적인 알고리즘이며, O(log n) 내에 동작한다.
- PREEMPT_RT 패치는 표준 2.6 리눅스 커널에 딱딱한 실시간 기능을 제공한다. 이 페이지는 PREEMPT_RT 환경 설정을 사용한 설치 세부 사항과 유용한 FAQ를 제공한다.
- 우선 순위 역전 시나리오에서, 낮은 우선 순위 태스크는 높은 우선 순위 태스크가 요구하는 자원을 잡고 있다(이 문제는 윈드리버에서 만든 VxWorks 운영체제를 탑재한 화성 착륙선인 패스파인더에서 발생했다). 이 문제를 풀어낼 해법은 우선 순위 상속인데, 높은 우선 순위 태스크가 동작하도록 자원을 풀기 위해 낮은 우선 순위 태스크 우선 순위를 높이는 방법이다.
- 노벨은 최근 SLERT(SUSE Linux Enterprise Real-Time) 버전 1.0을 발표했다. 이 배포판은 커널 패치와 실시간 응용 프로그램을 위한 POSIX 실시간 지원을 포함한다. 두 가지 개선 사항은 CPU 차폐와 동적 우선 순위 할당을 포함한다.
- Xenomai/SOLO는 협력 커널 접근 방법에서 벗어나 리눅스 커널 층으로 좀 더 밀접한 통합을 위한 이주 계획을 발표했다. 이런 접근 방법은 전통적인 POSIX(사용자 영역) 프로그래밍을 지원한다.
- developerWorks 리눅스 영역에서, 리눅스 개발자를 위한 자료를 좀 더 찾아보고 가장 인기있는 기사와 튜토리얼을 살펴보기 바란다.
- developerWorks에서 모든 리눅스 팁과 리눅스 튜토리얼을 살펴보기 바란다.
- developerWorks 기술 행사와 웹 캐스트를 놓치지 말기 바란다.
제품 및 기술 얻기
- SEK for Linux 주문: 최신 IBM 평가판 소프트웨어가 담긴 두 장 짜리 DVD 세트다. DB2®, Lotus®, Rational®, Tivoli®, WebSphere®를 포함한다.
- IBM 시험판 소프트웨어: developerWorks에서 직접 내려받아 다음번 리눅스 프로젝트를 구축하기 바란다.
토론
- 새로운 developerWorks space에서 블로그, 포럼, 포트캐스트, 공동체 주제를 통해 developerWorks 공동체에 참여하자.
