저 자 : 송인준
출판일 : 2003년 8월호
특별한 장치 지원
임베디드 시스템 크기의 제약으로 하드디스크를 달기에는 공간이 부족하고 그렇다고 디스크나 CD-ROM을 넣자니 디스크 리더나 CD-ROM을 꽂을 소켓도 없을 뿐만 아니라 전원도 부족합니다. 따라서 임베디드 장치들을 위한 저장장치는 적은 전력을 사용하면서도 크기의 요구를 맞출 수 있는 작은 종류의 저장장치들을 사용합니다. 물론 응용 프로그램도 아주 작은 수준이고, 하는 일도 매우 단순해서 저장장치가 필요 없다면 운영체제와 특정 응용 프로그램만을 저장할 수 있는 크기의 메모리 공간만을 사용하면 되겠지만, PDA와 같은 임베디드 시스템의 경우 내용을 저장할 수 없다면 몹시 불편하겠지요.
플래시 롬과 같은 장치들이 PDA나 디지털 카메라와 같은 임베디드 시스템의 저장장치로 많이 사용되고 있습니다. 이러한 플래시 롬은 저장장치로만 사용되는 것은 아닙니다. 시스템에서 사용하고 있는 메모리의 부족분을 이러한 저장장치의 여유 공간으로 사용하는 것입니다. 결국 플래시 롬을 가지고 메모리의 역할과 저장 장소의 역할로 같이 사용하는 것입니다. 이러한 저장장치들을 관리하기 위한 구조로 플래시 파일 시스템을 들 수 있습니다.
임베디드 리눅스를 만드는 회사 중 하나인 Axis에서는 플래시 롬을 사용하기 위한 파일 시스템을 만들었습니다. JFFS라고 불리는 이 파일 시스템은 저널링 파일 시스템을 플래시 롬에서 사용가능하도록 만든 것입니다. 저널링 파일 시스템은 로그 구조를 가진 파일 시스템입니다. 대개의 시스템의 경우 파일 시스템을 접근하는 도중에 시스템이 다운되어 버리면 파일 시스템이 통째로 날아가 버리게 되는데, 이를 막기 위해 로그 형식의 데이터 저장을 해두고 실제 저장은 한꺼번에 하도록 하는 형식의 파일 시스템입니다. 전원 공급이 일반 PC보다 불안정적인 임베디드 시스템에서 이와 같은 저널링 파일 시스템을 사용함으로써 더욱 안전한 데이터 저장을 할 수 있습니다. 또한 이 파일 시스템은 매번 시스템을 켤 때마다 파일 시스템을 체크하지 않아도 되기 때문에 빠른 속도의 부팅이 가능하며, 플래시 롬의 사용 영역을 조절하여 전체 플래시 롬을 사용하도록 함으로써 수명을 오래도록 사용할 수 있도록 하고 있습니다.
윈도우 계열의 운영체제에 사용되는 파일 시스템은 NTFS와 EFS입니다. 윈도우 NT용으로 개발된 파일 시스템인 NTFS는 자체적으로 압축 기능과 인덱싱 기능 및 보안 기능을 가지고 있어서 저장 공간을 효율적으로 사용할 수 있는 것으로 알려져 있습니다. EFS는 암호화 파일 시스템으로 여러 사용자를 지원할 수 있는 구조에 적합합니다.
운영체제의 크기 및 사용 메모리 줄이기
프로그램을 실행하기 위해서 필요한 저장장치들(램과 디스크)의 필요량은 얼마나 될까요? 실행될 응용 프로그램의 이미지 파일과 이들이 실제 메모리에 올라가서 사용하는 공간으로 구분되겠죠. 앞에서 살펴본 바와 같이 메모리와 플래시 롬을 같이 사용하는 시스템의 경우라 할지라도, 이미지 크기나 메모리 사용량은 크게 변하지 않습니다.
PDA에 들어가 있는 램의 크기는 대개 64MB에서 128MB 정도입니다. PC의 응용 프로그램 중에서 대표적인 인터넷 익스플로러의 크기를 한번 살펴볼까요? 인터넷 익스플로러의 경우 사용량에 따라 크기가 변하는 것을 알 수 있지만 필자가 지금 사용하고 있는 환경에서는 27MB 정도이군요. 커널 메모리 사용량만 해도 50MB 정도가 넘고 있습니다. 임베디드 시스템 들이 응용 프로그램을 많이 사용하지 않는다고 하지만 이전의 32MB짜리 램이 달린 PDA에 윈도우 운영체제를 그대로 사용한다는 것은 어림도 없는 일이었겠지요. 플래시 파일 시스템을 사용한다고 해도 여러 개의 응용 프로그램을 사용하는 것은 어림없는 일입니다. 임베디드 시스템의 메모리 사용량을 대개 footprint라고 부릅니다. 작은 메모리를 사용하면서도 시스템을 구축할 수 있다면 비용 절감의 효과가 있는 것이지요.
실제로 uc-OS(MicroC OS)의 경우 수십 KB 단위의 수준에서 응용 프로그램을 사용할 수 있습니다. 하지만 아무리 footprint를 작게 잡더라도 그것이 실제 사용하는 시스템의 footprint와 비교할 수 없다면 의미가 없겠지요. 실제로 uc-OS와 리눅스나 윈도우와 같은 시스템을 비교했을 때 네트워킹 지원이나 UI 지원의 수준이 엄청난 차이가 나고, 구조나 보안과 같은 문제가 고려되어야 하는 시스템의 경우 비교는 메모리 사용량만으로는 불가능합니다. 실제로 최근에 나온 윈도우 XP-임베디드 버전의 경우 설정에 따라서 5MB에서부터 300MB까지 구성이 가능하도록 되어있기 때문에 응용 프로그램이나 자신의 설정을 원하는 수준에 따라 시스템이 사용하는 메모리의 양은 다르다고 할 수 있습니다. 실제로 이 버전의 윈도우는 3가지 구성의 베이스 라인을 설정할 수 있도록 하였으며 최소 구성인 커널에 WIN32 서브 시스템이 빠져있기 때문에 커널을 올린 상태에서도 WIN32 응용 프로그램들을 사용할 수 없습니다.
마지막으로 메모리 사용을 줄이기 위한 임베디드 시스템에서 한 가지 중요한 사실은 불필요한 장치들의 지원을 하지 않아도 된다는 사실입니다. 범용 시스템과 같이 복잡 다양한 장치들을 모두 지원할 필요는 없다는 사실입니다. 결국 수많은 디바이스 드라이버들을 필요에 따라 삭제함으로써 메모리 사용을 줄일 수 있고, 디바이스가 추가된 경우를 대비하여 장치 관리자를 강화하는 방식의 접근을 하고 있는 경향을 볼 수 있습니다.
임베디드 시스템과 실시간 운영체제
앞서 말했듯이 임베디드 시스템에는 실시간 운영체제를 많이 이용합니다. 그것은 임베디드 시스템의 실시간적 특성 때문이죠. 간단히 언급한 휴대폰의 호 처리 외에도 실시간성이 필요한 경우가 또 있을까요? 사실 대부분의 임베디드 시스템의 경우 이 질문에 대한 답변은 ‘그렇다’입니다. 주변의 많은 임베디드 시스템을 생각해보기로 하죠. 자동차의 브레이크 미끄럼 방지 시스템(ABS)의 경우, 실시간성이 보장되지 않는다면 사고가 날 것입니다. 또한 전자 레인지나 세탁기 같이 시간을 예약해놓고 사용하는 가전제품의 경우에도 실시간성이 보장되어야 합니다. 비행기의 자동 항법 장치나 무기 시스템의 경우에도 시간은 중요한 요소입니다. 이렇게 작고 가벼운 장치부터 매우 큰 장치까지 임베디드 시스템이라면 거의 대부분이 시간에 대한 요소를 충족시켜야 하는 경우가 많고, 이것이 실시간 시스템의 디자인이 들어가야 하는 이유입니다.
그렇다면 어떠한 독자들은 과연 저런 장치들에 운영체제가 들어가는 것이 적합한가에 대한 의문을 가질 수도 있을 겁니다. 그에 대한 대답은 ‘있을 수도 있고 없을 수도 있다’입니다. 일반 사용자에게는 임베디드 시스템에 컴퓨터 시스템이 내장되어 있다고 보기 힘들고, 그렇다 하더라도 복잡하지도 않는 일을 하는 장치에 운영체제라는 것은 오히려 덩치만 커지는 것처럼 보이기 때문입니다. 실제로 단순한 장난감이나 아주 단순한 가전제품의 경우에는 컨트롤러 장치와 그를 구동시키는 간단한 프로그램만이 들어가는 경우도 있습니다. 하지만 요즘에는 장난감과 가전제품의 기능이 많아지고 복잡해져서 운영체제가 들어가는 경우가 많습니다. 소니에서 만든 장난감 강아지 로봇 아이보(AIBO)에는 Apertos라는 실시간 운영체제가 내장되어 있습니다. 자, 그러면 임베디드 시스템의 실시간성을 만족시키기 위한 실시간 운영체제의 디자인 이슈들을 공부해보도록 하죠.
간단한 장치들을 위한 구조
간단한 장난감 혹은 가전제품과 같이 간단한 시스템의 경우 평소에는 CPU를 중단하고 있다가 무엇인가 처리해야 할 작업이 있을 때만 그것을 처리하는 구조를 택합니다. 이렇게 하면 전력 소비 측면에서도 유리합니다.
<그림 2> Foreground/Background 구조
<그림 2>와 같이 Background는 처리해야 할 작업을 위해 특정한 모듈이나 함수들을 호출하는 무한루프로 구성되어 있습니다. 그리고 Foreground는 비동기적으로 발생하는 이벤트들의 처리를 위해 인터럽트 서비스 루틴을 실행하는 일을 합니다. 이러한 구조는 매우 간단한 만큼 많은 문제점을 가지고 있습니다. 바로 실시간성을 만족시키지 못한다는 점입니다. Foreground에서 실행되는 인터럽트 서비스 루틴의 응답시간이 예상하기 힘들기 때문입니다. 만약 Background에서 수행시간이 길면 Foreground에서 처리해야 할 인터럽트 서비스 루틴의 응답시간이 길어지게 됩니다. 즉, 이러한 구조를 갖는 장치는 외부의 자극에 대해 빠르게 반응해줄 수 있다는 보장은 하기가 힘들게 됩니다.
Preemptive vs. Non-preemptive 커널
Foreground/Background 구조보다 실시간성에 대한 고려를 갖춘 구조에는 어떤 것이 있을까요? 그것을 설명하기 이전에 앞서 Preemptive와 Non-preemptive 커널에 대해서 알아보도록 합시다. 운영체제에 관한 번역서를 본 독자라면 Preemp tive 라는 말은 선점형, Non-preemptive라는 말은 비선점형이라고 해석되어진 글을 봤을 겁니다. 하지만 이러한 해석은 매우 어렵고 잘못되어진 것이므로 원문 그대로 사용하겠습니다.
<그림 3>에서 보듯이 Non-preemptive 커널은 각 태스크가 CPU의 제어권을 자신의 실행 중간에 넘겨주지 않습니다. 즉, 우선 순위가 낮은 작업이 실행 중에 있고 중간에 우선 순위가 높은 작업을 실행하라는 요청이 들어와도 그것에 대한 요청을 빠르게 응답해주기 어렵습니다. 하지만 <그림 4>와 같이 Preemptive 커널의 경우는 중간에 우선 순위가 높은 요청이 들어오게 되면, 우선 순위가 낮은 작업은 잠시 양보를 하게 됩니다. Non-preemptive 커널은 높은 우선 순위의 작업이 언제 실행될지 알 수 없기 때문에 실시간 운영체제에는 잘 쓰이지 않습니다. 반대로 Preemptive 커널은 우선 순위가 높은 작업에 대하여 빠른 처리를 보장할 수 있으므로, 응답시간을 줄일 수 있게 됩니다. 그래서 많은 실시간 운영체제들이 preemp tive 커널 구조를 사용합니다.
<그림 3> Non-Preemptive 커널
<그림 4> Preemptive 커널
임베디드 시스템은 점점 특화되고 있다
지금까지 임베디드 시스템부터 그곳에 쓰이는 운영체제까지 살펴보았습니다. 다루는 주제는 최신의 것이고 여러분이 쉽게 접할 수 있는 소재이지만 실상은 어려운 주제이기도 합니다. 작고 제한된 환경에서 컴퓨터 시스템을 구축하는 것이 어렵기 때문이지요. 간단히 이번 호의 내용을 되짚어보면, 임베디드 시스템에 쓰이는 운영체제의 특성과 디자인을 이해하기 위한 흐름이었습니다. 그러기 위해서 첫째로, 임베디드 시스템이 무엇을 하는 녀석인지 살펴보았습니다. 그래야 임베디드 시스템을 구동시키는 운영체제에 대한 감을 잡을 수 있기 때문이지요. 이 운영체제에 대한 디자인의 이해를 위해서 임베디드 시스템이 무엇인지를 설명한 것이 좀 길었네요. 하지만 이 임베디드 시스템의 정의와 그 제약점들은 매우 중요한 것이므로 꼭 알아둬야 합니다.
특히 여기서 중요한 점은 이러한 임베디드 시스템들이 점점 더 특화된 목적으로 사용되어지고, 그 목적을 계속해서 변화시킬 수 있어야 한다는 점입니다. 만약 운영체제의 디자인이 레고 블럭과 같다고 상상해보죠. 아주 재밌겠지요. 원하는 목적을 갖는 시스템을 뚝딱뚝딱 만들어 내는 모습을 말입니다. 다음 호에는 바로 그런 운영체제의 디자인을 공부해보기로 하죠. 임베디드 시스템이든 범용 시스템이든 목적과 쓰임에 맞게 뚝딱뚝딱 만들어내는 그런 레고와 같은 모습을 갖는 운영체제를….