본문 바로가기

Hacked Brain/embeddedland.net

리눅스 플랫폼의 임베디드 프로그래밍

원작자 누구인지 알수 없네요...
네이버 카페에있는 글을 가져왔는데, 원작자를 알수 없는관계로
표기를 하지 못했습니다. 이 글의 원작자분의 요청이 계시면, 삭제 혹은 표기를 하겠습니다.

정리쪾홍석운 기자 |vichong@pserang.co.kr

리눅스 플랫폼의 임베디드 프로그래밍


임베디드 리눅스 시스템이 안정성과 개발 용이성을 자랑하며 최근 각광받고 있다. 실제 많은 임베디드 시스템에 리눅스가 채택되고 있는 실정이다. 이 글은 이러한 임베디드 리눅스의 발전 과정 및 향후 전망은 물론 실전 애플리케이션 제작에 대해 집중 소개하기로 한다. 임베디드 리눅스 개발 그룹에 대한 정보도 요약 제공한다.



컴퓨터 기술과 인터넷을 포함한 정보 통신의 눈부신 발전은 PC 보급 확산을 재촉했다. PC는 사무 자동화, 교육 및 훈련, 정보 사냥 등 다양한 서비스를 제공해 주고 있으며 고속 성장을 거듭하고 있다. 또한 PC 대중화는 노트북 PC 시장 동반 성장에 한 걸음 더 나아가 핸드 헬드 PC(HPC), 개인 휴대 단말기(PDA) 등의 발전을 낳고 있다. PDA는 개인 데이터베이스 관리, MP3플레이어, 음성 및 영상 통신, 정보통신, 인터네트워킹, 지리 정보 시스템(GPS), 교육 훈련 등의 서비스를 편하고 손쉽게 제공해 줄 것이다. 또한 컴퓨터 기술은 디지털 카메라, 의료 및 산업 원격 조종기 등에 널리 응용되고 있는데,  PDA를 포함한 이런 시스템들이 바로 임베디드 시스템(Embedded System)에 속한다.


임베디드 리눅스의 발전

자유정신의 공개 운영체제인 리눅스는 인터넷의 성장과 더불어 비약적인 발전을 기록하고 있다. 리눅스는 소스가 공개되어 있고, 안정적으로 다양한 서비스를 제공함은 물론 확장 가능하다. 또한 무료 배포로 가격 경쟁력을 지니며, 안정적이고 다양한 서비스를 제공해  품질 경쟁력 면에서도 매력적이다. 소스가 공개되어 있다는 사실은 개발자들의 새 소프트웨어 연구, 개발을 촉진 시키며 운영체제가 확장 가능해 임베디드 시스템에도 적용 가능하다. 따라서 최근에 많은 임베디드 시스템에 리눅스가 채택되고 있다.

리눅스는 유닉스 형태의 공개 운영체제다. 리눅스는 Linus Torvalds 가 창시자로 세계 각국의 많은 개발자들에 의해 발전하고 있다. 유닉스 표준인 POSIX에 따라 구현됐으며, 완전한 멀티태스킹, 가상 메모리, 공유 라이브러리, 효율적인 메모리 관리, TCP/IP 네트워킹 등 유닉스 운영체제로 안성맞춤이다. 리눅스 소스 코드는 GNU General Public License에 따라 누구나 아무런 대가 없이 이용 가능하다.

지난 1999년 9월  안정적이며 완전한 2.2.12 버전이 공개됐으며, 2.3대 버전의 개발이 진행되고 있다. 현재 Linus는 가운데 버전이 홀수인 개발 버전의 관리 및 개발만을 담당하고 있고, 주 개발자들 중의 한명인 Alan Cox가 가운데 버전이 짝수인 안정 버전의 관리 및 개발을 담당하고 있다.


리눅스의 안정성

임베디드 시스템에 위와 같은 리눅스를 적용하면 많은 이점이 따른다. 리눅스의 안정성 및 가격 우월성, 또한 개발용이성 등이 그것이다.

데스크탑 컴퓨터에 쓰이는 리눅스는 다른 운영체제에 비해 훨씬 향상된 안정성을 갖고 있으며, 이는 특히 통신 구성요소에 있어서 더욱 그렇다. 예컨대 마이크로소프트 Windows 95/98/NT 등은 사용자가 이해할 수 없는 메시지를 발생하며 시스템이 다운되는 일이 빈번하나, 리눅스 데스크탑 서버인 경우 수 개월 내지 1년 이상 시스템을 가동시켜도 안정적이란 사실이 많이 보고 되어 왔다.

이런 경향은 PDA를 비롯한 임베디드 시스템의 경우에도 지속되어, 임베디드 시스템의 경우 Windows CE 보다 리눅스가 훨씬 안정적이란 사실이 최근 보고되고 있다. 이런 경향은 수십 내지 수백의 엔지니어 집단에서의 개발, 버그 수정 보다는 리눅스와 같이 전세계 수십만 내지 수백만의 개발자들의 자발적 참여에 의한 공개성이 더욱 우월하다는 사실을 입증시킨 것이다.

따라서 전세계 수 많은 사용자들과 개발자들에 의한 발전이 이루어지고 있으며, 리눅스 기반의 새로운 프로젝트들은 인터넷에 공개된 수 많은 정보 및 경험의 도움으로 다른 운영 체제 기반의 소프트웨어를 개발하는 것보다 추진이 훨씬 용이하다. 임베디드 리눅스 시스템의 경우도 이런 장점이 그대로 유지되면서 발전되어 왔다.


성장 가능성

임베디드의 개념에 리눅스의 장점이 접목되면서 임베디드 리눅스의 성장 가능성은 높이 평가되고 있다.

예를 든다면, 오늘날 많은 기기들이 인터넷에 연결되어 있다. 어떤 냉장고들은 인터넷에 연결되어 온도, 현재 저장량 등과 같은 상태를 웹 브라우저를 통해 모니터링 또는 조절이 가능하다. 이러한 오늘날의 인터넷 세태는 Telerobots이라는 것을 만들어 냈는데 이는 네트워크를 통해 원격 콘트롤이 가능한 Robots을 지칭한다. 냉장고 뿐만이 아니라 세탁기 등 원격으로 집안 기기들을 네트워크를 연결해 콘트롤 할 수도 있다.

위의 내용들을 토대로 살펴보면 임베디드 리눅스의 연구개발은 다음과 같은 분야에서 이루어지리라 전망된다.


저전력 시스템 개발

소형 후대 정보 단말기의 개발에 있어 효율적인 전력 관리를 통한 배터리 사용 시간의 연장은 중요한 경쟁력 향상의 요소이다. 리눅스 커널에 이용되고 있는 진보된 전력 관리 기술을 연구 개발하고 이를 소형 시스템에 구현하는 일이 필요할 것이다.


효율적인 메모리 관리 기술

소형 시스템은 제한된 메모리 지원을 갖고 있으며, 이런 제한된 메모리 지원 위에 다양한 기능을 갖는 소프트웨어를 지원하여 기능성을 향상시키는 기술이 필요할 것이며, 리눅스에 이용된 메모리 및 프로세스 관리 기술을 연구 개발하여 이를 소형 시스템에 구현하여야 할 것이다. 특히 실행 후 잔류 메모리를 감소시키는 연구가 필요할 것이다.


유저 인터페이스 연구 및 개발

유저 인터페이스를 필요로 하지 않는 임베디드 시스템도 있지만, PDA를 포함한 많은 임베디드 시스템들은 간단한 텍스트 기반에서부터 훨씬 복잡한 방식까지 유저 인터페이스를 필요로 한다. 데스크 탑에 쓰이는 유저 인터페이스는 현재까지 키보드, 마우스, 그래픽 등이 사용되어 왔으나 PDA의 경우는 훨씬 작은 플랫폼이란 제한성으로 키패드, 필기체 인식, 음성인식 등이 연구 개발되어 왔다. 최근에는 이 외에도 한 손만으로 사용할 수 있는 방향성이나 무게성에 기반을 둔 유저 인터페이스에 대한 개발도 이루어지고 있다. 사용자 편의성과 전달의 정확성을 중시하는 새로운 개념의 유저 인터페이스에 대한 개발은 리눅스 뿐만 아니라 대부분의 임베디드 시스템의 연구 분야일 것이다.


안정적 시스템 소프트웨어 기술 개발

데스크탑 컴퓨터에 쓰이는 리눅스는 다른 운영체제에 비해 훨씬 향상된 안정성을 갖고 있으며, 이는 특히 통신 구성요소에 있어서 더욱 그러하다. 이런 리눅스의 안정성을 소형 시스템에도 그래도 유지할 수 있는 기술을 개발할 것으로 전망된다. 


실시간성

휴대 정보 단말기를 멀티미디어 플레이어로도 사용하기 위해서 가장 필요한 요소 중의 하나는 운영체제의 실시간성이다. 완화된 실시간성은 기존의 리눅스에 이미 POSIX 연실시간 스케줄링으로 구현되어 있으며, 엄격한 실시간성을 커널에 구현하는 연구는 최근에 이루어지고 있다. 리눅스에 실시간 동작을 접목한 시스템 연구 기관으로는 미국의 뉴멕시코 대학과 캔사스 대학을 꼽을 수 있다. 실시간 리눅스는 멀티미디어 단말 뿐만 아니라 네트워크 라우터 장비에도 적용되고 있다. 따라서 실시간성에 대한 연구가 요구되어 진다.


부분 시스템으로서의 임베디드 시스템

PDA 와 같은 임베디드 시스템 및 이동 단말은 작고 가벼워야 하므로 컴퓨팅 파워 및 메모리 사이즈에 있어서 제한적일 수 밖에 없으며 하드 디스크 같은 대용량 저장 장치를 장착하기도 어렵다. 물론 휴대 시에는, 단말 자체가 독립적인 완전한 시스템으로 작동하여야 하기 때문에 이 부분에 대한 연구 개발이 요구된다.

이렇듯 독립적인 시스템만으로 PDA가 작동하는 데에서 더 나아가 다른 PC 나 워크스테이션에 있는 대용량 저장 용량 장치나 다른 자원을 이용할 수 있다면 더 나은 서비스를 제공할 수도 있을 것이다. 일례로 멀티미디어 단말은 이동 중에는 플래쉬 메모리 사이즈가 작아 불과 수 곡의 MP3 파일만을 연주할 수 있으나, PC 상 MP3 파일 디렉토리를 NFS 마운트로 자신의 파일 시스템으로 사용할 수 있게 만든다면 수백 개의 MP3 파일까지도 연주 가능하다.

한편 임베디드 시스템을 독립적인 시스템 작동 방식에서 경우에 따라 한가지 작은 태스크만을 수행하는 부분 시스템으로 작동하는 방식으로 만든다면, 다른 서버나  임베디드 시스템들과의 네트워킹을 통한 병렬 및 분산 프로세싱을 통해 더 큰 태스크를 수행할 수 있다. 이와 같은 부분 시스템으로서의 임베디드 시스템에 대한 연구도 가치가 있을 것으로 예상된다. 


더 많은 관심과 투자 필요

리눅스는 그 동안 데스크탑에서의 풍부한 개발 경험으로 가격 경쟁력, 성능의 우월성 및 개발의 용이성 등에서 검증된 운영체제이다. 이와 같은 리눅스 운영체제의 장점들이 임베디드 시스템의 개발에도 그대로 적용될 것이라는 기대는 현재까지 만족스러운 편이라고 평가할 수 있다.  임베디드 시스템용 리눅스 기반 소프트 웨어 연구 개발은 미국을 비롯한 선진국에서 활발히 진행되고 있으나, 국내는 이제 태동기로 많은 관심과 투자가 이루어져야 할 것이다.

특히 선진국을 중심으로 활발히 진행되고 있다고는 하나 아직 그 기술 격차가 그리 큰 단계는 아니므로 국내에서 이 분야에 대한 투자와 노력을 추구한다면 다른 분야에 비해 더 나은 국제 경쟁력을 확보할 수 있으리라고 전망된다.  리눅스를 임베디드 시스템에 적용시키려는 노력 중에서도, 위에 언급한 저전력 관리, 효울적 메모리 관리, 안정적 시스템 소프트웨어, 유용한 유저 인터페이스 개발 그리고 실시간 적용이 무엇보다도 우선 수행되어야 할 것이라 판단되며, 또한 부분 시스템으로서의 임베디드 시스템에 관한 연구도 수반되어야 할 것이다.


임베디드 리눅스 시대의 개막

인터넷 등 통신의 발달과 맞물려 컴퓨터, 이동전화, 셋탑박스, 디지털 TV, 개인휴대단말기 등 정보단말기의 네트워크화가 급진전되면서 임베디드 리눅스가 최근 IT분야의 새로운 관심사로 부상하고 있는 현실이다.

이러한 리눅스의 특징과 임베디스 시스템이 맞물리면서 통신, 인터넷 분야에서도 임베디드 리눅스의 인기가 급상승하고 있다. 예를 들면, 컴팩이 리눅스 기반 PDA를 개발한 데 이어서 필립스를 비롯 일본 NEC, CASIO, 도시바 등이 실시간 OS로 리눅스를 탑재한 PDA를 개발 중이다. 국내에서도 섬성, LG등 대기업 뿐만 아니라 많은 벤쳐들이 PDA는 물론 디지털TV, STB(셋탑박스)에 활용할 수 있는 리눅스 개발에 착수했다. 다음은 임베디드 리눅스를 비롯한 임베디드 시스템 시장의 성장에 대한 도표로서 이는 급속히 성장하고 있는 임베디드 시장의 현주소을 보여준다.

IDC에 따르면 지난해 말 리눅스 OS는 세계 서버시장의 17%를 차지하고 서버 라이센스만도 75만 건에 달한 것으로 집계됐다. 이는 다른 유닉스 서버 라이센스를 합친 건수와 대등한 숫자다. 이런 추세라면 향후 2, 3년 안에 전세계 서버의 절반이 리눅스 OS를 탑재하게 될 것으로 전망되고 있다.

게다가 최근 미국, 일본, 유럽 등 선진국에서는 통신용을 넘어 산업용으로까지 확대되고 있어 임베디드 리눅스 시장의 성장 가능성이 한층 더 높아지고 있다.

이에 비해 국내에서는 아직 산업측면에서 임베디드 리눅스 기술의 활용수준이 높지 않은 것이 사실이다. 국내 업계 관계자들은 기술 인력을 확보하는 것조차도 쉬운 일이 아니라고 말한다. 하지만 공장자동화 단말기를 비롯해 수치제어장치, 산업용 로봇 등 기존 장비를 대체하는 분야에서 리눅스 기술의 채택 가능성이 높아지고 있어 시장전망은 밝은 편이며, 이에 따라 국내 우수 인력들의 시선이 이 분야로 쏠리고 있는 실정이다. 임베디드 리눅스의 응용분야는 무궁무진하며 지금부터 국내 업계가 임베디드 리눅스 기술 개발에 나설 경우 세계 시장을 충분히 선점할 수 있다는 것이 전문가들의 의견이다.


임베디드 리눅스 이식 작업

리눅스가 임베디드 애플리케이션에서 주요 위치를 점하고 있는 것은 의심의 여지가 없다. 리눅스는 POSIX 1003.1을 준수하며 POSIX 연성 실시간 확장(Soft real-time extension)을 지원한다. 이론적으로 리눅스는 인터넷 라우팅같은 연성 실시간 수행을 요구하는 임베디드 애플리케이션을 광범위하게 지원할 수 있다. 커스터마이징이 쉽다는 점이 큰 매력인 것이다.

임베디드 시스템용 플랫폼으로 리눅스 사용의 가능성을 타진해보기 위해 커널을 PowerPC 기반의 보드에 이식하는 작업을 수행하였다. 리눅스 커널은 2.2.13기반으로 하였으며 다양한 리눅스 명령을 수행할 수 있는데 직렬 포트를 통해 콘솔에서 bash와 vi도 구동시킬 수 있다.


리눅스와 임베디드 시스템

리눅스가 이식성이 높다는 것은 주지의 사실이고 이미 다양한 프로세서에 리눅스가 이식되는 것을 보아왔다. 이식은 어떠한 운영체제든 간에 쉽지 않은 작업이나 리눅스 커널의 모든 중요한 컴포넌트는 이미 아키텍쳐에 독립적으로 디자인되어 있어 상대적으로 쉬운 작업이라고 여겨진다.

리눅스가 이미 지원되는 프로세서에 이식하는 것보다 새로운 프로세서가 장착된 보드에 리눅스를 이식하는 일이 더 어렵다. 새로운 프로세서 장착 보드에 리눅스를 이식하는 작업에서는 보드에 독립적인 코드를 재사용할 수 있다.

이러한 예로는 메모리 관리 관련 코드들이 있고 단지 커널 코드 중 상대적으로 작은 부분만 이 보드에 의존적인 경우를 들 수 있다. 리눅스는 이미 파워 매킨토시와 소수 PowerPC 기반 머신에 이식되어 있다. 하지만 다양한 보드 아키텍쳐와 아키텍쳐에 따른 다른 설정 상황, 그리고 서로 다른 부팅 방법 때문에 새로운 보드에 이식을 고려할 때는 수정이 필요하다.

이식 작업에 사용한 보드는 Motorola MPC860프로세서 기반으로  메모리 컨트롤러와 PCI 브리지로 Qspan, SCC Driver로 Ethernet, Serial Port 등으로 구성되어 있다. 또한 두 개의 플래시 메모리를 가지고 있으며 각각 Boot ROM과 Flash Memory의 역할을 하고 있다.


<Target Board  Specifications>

· MPC860 PowerQUICC processor (MMU 및 Communica tion Function)

· 4MB on-board D-RAM

· 4MB Flash Memory

· EIA-232 Serial Port

· 10BaseT Ethernet interface

· IEEE-1284 Parallel port interface

· One PCMCIA slot

· Communication Protocol Interface (SCCs, SMCs, TSA, SPI, I2C ports)

먼저 크로스 개발(Cross-Development) 환경 구성을 하고 부트 로더 구성, 커널 수정, 실행 이미지와 루트 파일 시스템 생성 순으로 작업을 진행하도록 한다. 여기서는 구현에 대하여 상세히 설명하기 보다는 전체적인 작업 흐름 위주로 알아보도록 한다.


크로스 개발 환경

개발 호스트 시스템에 Target Board용 개발을 가능하게 하는 크로스 개발 환경을 구성하여야 한다. 어떤 경우는 완벽한 크로스 개발환경을 설정하는데 어려움이 있을 수도 있는데 여기서 필요한 일은 적절한 배포본의 선택, 적합한 설정 및 재컴파일을 검토해 보는 것이다.

작업에 필요한 크로스 컴파일러를 호스트 컴퓨터에 다음과 같이 구성한다.


<호스트 컴퓨터 구성>

· OS : RedHat Linux 6.1

· Platform : X86 Processor 계열

· Tools : Binutils 2.9.5.0.29, Gcc 2.95.2, Linux Kernel 2.2.13, Glibc 2.1.3· Utility : vi, bash, dump, Monitor Program 등


위의 각종 툴 및 유틸리티는 해당 GNU 사이트에서 자료를 받을 수가 있으며 설치 및 컴파일 방법도 포함되어 있다. 자세한 내용은 다음의 사이트를 참고하면 된다.


http://members.home.com/mmporter/linux/cross/

■(Cross Development for Linux/PPC)

http://www.gnu.org (GNU Project)

개발 작업에 있어 모니터 프로그램이 필요하게 되는데 상용 보드 같은 경우는 간단한 자체 모니터 프로그램이 제공되는 경우가 있으나 자체 제작 보드나 평가판 보드에서는 제공이 안될 수도 있다. 이럴 경우에는 직접 타겟 환경에 맞는 모니터 프로그램을 작성하여야 하며 이러한 모니터 프로그램은 하드웨어 초기화, 프로그램 다운로드 및 실행, disassemble 및 trace 기능 등이 요구된다.


부트 로더 구성

운영체제가 부팅되기 위해서는 복잡한 과정을 거치게 되며 부팅은 보드마다 다른 하드웨어 초기화와 소프트웨어의 시작을 포함한다. 리눅스는 각 보드마다 리눅스 아키텍쳐에 의존적인 소스 코드 디렉토리, 즉 /usr/ src/linux/arch/ 내에 서로 다른 부팅 코드가 존재한다. 새로운 보드를 위해서는 보통 새로운 부팅 과정의 내용을 추가하여야 한다.

전형적인 임베디드 보드는 플로피와 하드 디스크를 가지고 있지 않으며 코드와 데이터는 초기화 롬에 내장되거나 네트워크를 통해 다운로드할 수 있다. 여기서는 메모리 적재로 부팅하는 접근 방식으로 디자인 하였으며, 이 이미지를 플래시 메모리에 저장하여 Boot ROM 기능을 수행 할 수 있게 된다.

여기서 부트 이미지는 다음의 두 가지 항목을 가진 단일한 파일로 묶여 있다.


·압축된 커널 이미지■bvmlinux.out

·리눅스 커널로더■bzimage

·압축된 루트 파일 시스템■rootfs.gz


부트 이미지 묶음의 크기는 얼마나 많은 서비스와 프로그램이 포함되었느냐에 좌우된다. 더 큰 프로그램이 필요하다면 시스템이 구동된 후 다운로드하여 사용할 수 있는데 가능하면 부트 이미지 사이즈를 작게 유지하는 것이 좋다. 각 파일을 묶을 때 사용되는 유틸리티로 packbd가 있는데 이 프로그램은 바이너리와 데이터 이미지를 묶어주는 기능을 가지고 있다. 그리고 커널 이미지와 루트 파일 시스템을 해당 설정 파일만 수정하여 간단하게 생성할 수 있는 유틸리티가 있는데 이는 대부분 상용 Linux에서 제공되는 것이며 직접 Linux Kernel Document(/usr/src/linux/documentation)를 참고하여 구성하여도 된다.

이렇게 구성된 이미지를 램 영역에 다운로드하여 실행하게 되는데 이때 TFTP 네트워킹 서비스를 이용하여 부팅하게 된다. 호스트 컴퓨터에 TFTP 서비스 설정을 한뒤 Target Board의 모니터 프로그램 상에서 네트웍 부팅 명령을 이용하여 적재 및 실행하게 된다.


커널 수정

커널 수정은 이식의 가장 어려운 부분이며 리눅스 이식 과정에서 가장 중요하게 여겨지고 있다. 다행이도 리눅스 소스 트리구조 내에서 소스가 잘 조직화되어 이식성이 높게 디자인되어 왔다. 앞서 언급했듯이 리눅스를 새로운 보드에 이식할 때 소스를 수정하고 새로운 코드를 수정하는 일이 반드시 필요하다.

기본적으로 모든 보드에 의존적인 코드는 리눅스가 지원되는 프로세서라 할지라도 수정되거나 조정되어야 한다. 새로운 요구사항이 나타나고 버그 수정을 해야 할 때면 이러한 변경이 필수적이다. 소스 변경의 핵심으로 보드 의존적인 부분으로 제한되어야 한다는 점이 요구된다. /usr/src/linux/arch/ppc 디렉토리 소스 내용 수정이 대부분이며 새로운 하드웨어에 적용할 코드와 메모리 맵핑 같은 새로운 기능 추가와 수정들이 있다.

커널 수정에 있어 주요 변화는 하드웨어 초기화, PCI 버스 초기화, 메모리 관리, 인터럽트 프로세싱 등을 포함하고 있다.

하드웨어 초기화 부분이 상당히 어려운 부분이지만 모니터 프로그램을 지원하는 보드에서는 이러한 일부분을 자체적으로 초기화하는 기능을 포함하고 있다. 이럴 경우에는 메모리 보호와 버스 장치 초기화를 하는 커널 초기화 부분만을 보면 될 것이다.

메모리를 관리하기 위해서는 몇 가지 고려할 사항이 있다. 가상 메모리 관리와 페이징과 같은 메모리 관리를 위해 주요 부분을 변경할 필요가 없다 생각하여도 수정할 부분이 생기게 된다. 이는 특정 메모리 크기와 범위를 설정하고 커널이 시작되는 동안 메모리를 재정렬하며, PowerPC 블록 주소 변환 레지스터를 사용하고 물리적 주소와 가상 주소 간의 메모리 맵핑을 위한 것이 주가 된다.

다른 주요 변화는 인터럽트 컨트롤러를 위한 것이다. 이 컨트롤러는 단순하고 상태 레지스터, 마크 레지스터 그리고 래치(latch) 레지스터를 통해 16개의 IRQ를 제어하며 모든 레지스터는 16비트이다.


<linux/arch/ppc/mpcboot 커널 관련 파일>

embed_config.c       iic.c       misc.c   pci.c        rootfs.gz

Makefile  head.S     m8xx_tty.c  offset*  qspan_pci.c  size*

Makefile 내부를 보면 커널 이미지, 커널 로더 및 루트파일 시스템 등의 생성 및 변화된 코드에 적용할 수 있는 내용을 정의하고 있다. 다른 파일들은 하드웨어 초기화, 메모리 관리, PCI 버스 초기화 등에 대한 하드웨어 의존적인 파일들이다.


<Makefile 중 커널 이미지 부분>

zvmlinux.initrd: zvmlinux

        $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)        $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \

                --add-section=initrd=ramdisk.image.gz \

                --add-section=image=../coffboot/vmlinux.gz \

                zvmlinux.initrd.tmp zvmlinux.initrd

        $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd initrd` \

                -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd initrd` \

                -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd image` \

                -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd image` \

                -c -o misc.o misc.c

        $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)

        $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \


                --add-section=initrd=ramdisk.image.gz \

                --add-section=image=../coffboot/vmlinux.gz \

                zvmlinux.initrd.tmp $@

        rm zvmlinux.initrd.tmp

zImage: zvmlinux

        ln -sf zvmlinux zImage


zImage.initrd: zvmlinux.initrd

        ln -sf zvmlinux.initrd zImage.initrd


zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz

$(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)

        $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/v

mlinux.gz \

                zvmlinux.tmp $@

$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \

                -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux image` \

                -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \

                -c -o misc.o misc.c

        $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)

        $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \

                zvmlinux.tmp $@

        rm zvmlinux.tmp


znetboot : zImage

        cp zImage $(TFTPIMAGE)


znetboot.initrd : zImage.initrd

        cp zImage.initrd $(TFTPIMAGE)


커널 및 부트 이미지 생성

전체 부트 이미지는 커널 이미지와 루트 파일 이미지를 필요로 하는데 이것은 위에서 언급 했듯이 변경된 커널 디렉토리의 Makefile 부분에 나타나 있다.

리눅스 소스는 다양한 플랫폼용으로 커널 이미지를 생성할 수 있는 규칙을 제공한다. 우리가 사용하는 시스템에서는 압축된 바이너리 커널 이미지인 vmlinux.out가 필요하며 생성 절차는 순서대로 설정, 컴파일과 링킹, 바이너리 포맷 이동 그리고 압축이다. 설정에서 램디스크 지원과 초기 루트 파일 시스템 지원이 선택되었는지를 확인한다.

vmlinux라는 이름을 갖는 ELF 실행 파일 형태로 커널을 컴파일하고 링크한다. 그리고 바이너리 포멧으로 구성한 뒤 압축하게 된다. 커널이 실행된 후 램에 초기 루트 파일 시스템을 마운트하도록 선택하기 때문에 rootfs.gz라 불리는 루트 이미지를 준비해야 하고 이 루트 이미지는 하나의 이미지에 묶여진다.

크로스 개발 플랫폼 상에 4MB 램 디스크를 만들어 EXT2 파일 시스템을 생성하여 이 작업을 하며 /etc, /dev, /bin 그리고 /lib 같은 서브 디렉토리를 만든다. 그 밖에 스크립트, 바이너리, 장치 노드, 설정 파일을 램 디스크 안으로 카피해 넣은 뒤 램 디스크 이미지를 압축한 후 rootfs.gz를 얻어 낸다. 초기 루트 램 디스크가 포함해야 하는 것은 요구에 따라 다르게 되며 최소한의 공유 라이브러리와 테스트를 위해 bash와 vi 같은 몇 가지 프로그램을 카피한다.

다음 쪽의 부팅 결과 화면은 램디스크로 구동된 것이 아니라 커널 이미지만 타겟에 적재후 실행뒤 부트 옵션을 주어 Remote boot (NFS 이용)를 수행한 것이다. 부팅 첫번째 라인에 NFS 마운트에 관한 부트 옵션이 들어간 부분을 볼 수 있다.

특히 시스템 부팅 동안의 버그를 발견하고 수정하여야 하는데 어려움이 있을 수 있다. 특정 하드웨어 디버깅 장비를 이용할 수 있겠지만 이러한 것에만 의존할 수는 없을 것이다. 많은 경우 printk와 gdb와 같은 메커니즘을 이용할 수 있다.

하지만 이들은 너무 많은 시스템 서비스를 필요로 하며 리눅스 커널 디버깅 지원 기능인 printk는 단지 시스템이 콘솔이나 파일 시스템에 쓰기 준비가 된 후에만 동작한다. 시스템이 준비되기 전에 크래쉬 된다면 printk가 동작 중에 이전 정보를 저장할 메모리 버퍼를 사용한다 해도 printk를 통해 얻을 수 있는 것은 없다.


애플리케이션 제작 실제

기본적으로 OS가 포팅되고 기본적인 디바이스 드라이버 작성이 되면 해당 임베디드 시스템에 요구되는 애플리케이션 개발 작업에 들어가게 된다. 임베디드 리눅스에서는 이후의 애플리케이션은 배포판에서 가져와 사용하게 되는데 특수한 경우를 제외하고는 이러한 방법으로 구성되고 있다.

여기서는 해당 임베디드용 애플리케이션을 개발하기 위하여 필요한 유틸리티나 툴을 이용하여 예제 애플리케이션을 구성하는 작업에 대하여 알아보도록 한다. 여기서 사용되는 유틸리티나 구성 방법은 고유한 방법이므로 배포판이나 일반 패키지에서는 제공이 안되는 특수한 툴이라는 것을 먼저 알린다.


 <리눅스 이미지 부팅 결과 화면>

Linux/PPC load: root=/dev/nfs nfsaddrs=

■211.53.73.163:211.53.73.172 nfsroot=211.53.73.172:/mbxroot

Uncompressing Linux...done.

Now booting the kernel

Linux version 2.2.13 (dan@pbdan.clearone.com) (gcc version egcs-2.90.52

#31 Mon Sep 7 18:14:20 EDT 1998Boot arguments: root=/dev/nfs nfsaddrs

=211.53.73.163:211.53.73.172 nfsroot=211.53.73.172:/mbxroot

time_init: decrementer frequency = 150000000/60

Memory: 10960k available (732k kernel code, 560k data, 36k init) [c0000000,c0c00000]

PCI: Probing PCI hardware

Calibrating delay loop... 39.73 BogoMIPS

POSIX conformance testing by UNIFIX

Swansea University Computer Society NET3.039 for Linux 2.1

NET3: Unix domain sockets 0.16 for Linux NET3.038.

Swansea University Computer Society TCP/IP for NET3.037

IP Protocols: ICMP, UDP, TCP, IGMP

Starting kswapd v 1.5

CPM UART driver version 0.02

ttyS00 at 0x0280 is a SMC

ttyS01 at 0x0380 is a SMC

ttyS02 at 0x0100 is a SCC

ttyS03 at 0x0200 is a SCC

CPM ENET Version 0.1, 08:00:3e:29:37:46

PPP: version 2.3.3 (demand dialling)

TCP compression code copyright 1989 Regents of the University of California

PPP line discipline registered.

Looking up port of RPC 100003/2 on 211.53.73.172

Looking up port of RPC 100005/1 on 211.53.73.172

VFS: Mounted root (nfs filesystem).

Freeing unused kernel memory: 36k init 28k prepbash#


Linux 커널 재설정

먼저 해당 애플리케이션에 맞는 커널을 설정해 재구성하여야 한다. 여기서는 간단한 설정파일(*.config) 내의 커널 구성 항목을 손쉽게 수정해 재설정이 가능하다. 일반적으로 커널 설정에 있어 다음의 사항을 고려하여 재설정하게 된다.


·기능상의 재설정

·하드웨어 디바이스에 대한 재설정

·사이즈에 대한 재설정

·성능에 대한 재설정


리눅스 소스 디렉토리에서 make config하는 일반적인 설정 방법과 같은 결과를 얻을 수 있지만 각각의 애플리케이션에 대한 커널 설정 내용을 별도로 관리할 수 있다는 점에서 의미가 있다.

이러한 커널 설정 파일들을 이용하여 커널을 재구성하기 위하여 mkkernel 이라는 스크립트를 만들었다. mkkernel 스크립트는 두가지 파라미터를 가지고 있는데 첫번째로 .config 파일이 /usr/src/linux 디렉토리에 카피되고 make oldconfig 및 make bzImage를 수행한다. 두번째로는 생성된 커널 이미지를 특정한 위치에 카피하도록 한다.


 <mkkernel script 파일 내용>

#!/bin/bash

echo  

echo  Building kernel

echo  ---------------

KDI_DIR=`pwd`

cp -f $1 /usr/src/linux/.config

cd /usr/src/linux

make oldconfig

make bzImage

cd $IMAGE_DIR

cp /usr/src/linux/arch/i386/boot/compressed/bvmlinux.out $2if [  $3  !=    ]

then

  cp /usr/src/linux/arch/i386/boot/bzImage $3

fi

# end of file


애플리케이션 개발 및 루트 파일 시스템 생성

크로스 개발환경에 맞는 적절한 애플리케이션을 구성한 뒤 루트 파일 시스템을 생성하는데 여기서는 mkrootfs라는 리눅스 루트 파일 시스템 생성 유틸리티를 이용한다. Mkrootfs는 다음의 두 가지 형식의 이미지를 생성한다.


·부팅 가능한 이미지 : Target 시스템의 RAM에서 적재되고 Ramdisk와 같은 기능을 수행하면서 부팅될 수 있는 이미지 생성

·설치 가능한 이미지 : Target 시스템의 물리적인 하드디스크와 같은 저장장치에 설치하여 실행 할 수 있는 이미지 생성


mkrootfs 유틸리티에서는 독특한 설정 파일(spec files)을 가지고 있다. 이 파일에서 일정한 형식에 맞추어 커널 이미지, 해당 애플리케이션 및 파일들을 등록만 하여 파일 시스템 이미지를 구성할 수 있다.


예제 애플리케이션

위에서 살펴본 방법으로 구현한 샘플 애플리케이션에 대하여 알아보도록 한다.


Ping demonstration


<요구사항>

ROM - kernel : 376KB, Rootfs : 741KB

RAM - 8MB

Network - 필요


<파일 구성>

Makefile  ping.config  ping.kernel*  ping.spec

local/    ping.disk    ping.rfs      ping.tar

위에서 ping.config 파일은 커널 설정 파일로서 해당 애플리케이션에서 필요한 커널 정보를 가지고 있으며 ping.spec 파일은 루트 파일 시스템에 생성에 관한 설정 파일이다. ping.kernel, ping.rfs는 각각 커널 이미지, 루트파일 시스템이다.


 <ping.config 파일 내용(일부분)>

#

# Automatically generated make config: dont edit#

#

# Code maturity level options

#

CONFIG_EXPERIMENTAL=y

#

# Processor type and features

#

CONFIG_M386=y

# CONFIG_M486 is not set

# CONFIG_M586 is not set

# CONFIG_M586TSC is not set

# CONFIG_M686 is not set

CONFIG_1GB=y

# CONFIG_2GB is not set

.....


<ping.spec 파일 내용>

# ping.spec

#

strip on


mkdir /dev

mknod /dev/console c 5 1


#SCSI specifics

mknod /dev/sda     b 8  0

mknod /dev/sda1    b 8  1

#IDE Specifics

mknod /dev/hda     b 3  0

mknod /dev/hda1    b 3  1

mknod /dev/hdb     b 3  64

mknod /dev/hdb1    b 3  65

mkdir    /lib

mkdir -p /usr/lib

mkdir    /bin

mkdir    /sbin

mkdir -p /etc/rc.d

mkdir    /proc

cp ./local/fstab ./local/inittab  /etc

cp ./local/rc.sysinit             /etc/rc.d

lcd /bin

cp ping mount bash /bin

ln -s /bin/bash /bin/sh


lcd /sbin

cp reboot init ifconfig route  /sbin

# End of File

위의 예제 애플리케이션은 간단하게 ping명령을 이용하여 네트웍 디바이스를 테스트해 보는 샘플 프로그램이다. 해당 이미지 파일을 적재후 성공적으로 부팅하게 되면 메시지와 함께 bash 프롬프트가 나타난다. 다음의 명령으로 애플리케이션이 정상적 동작 여부를 확인할 수 있다.


bash# ifconfig eth0 *.*.*.*

bash# route add default gq *.*.*.*

bash# ping *.*.*.*


다음은 위의 예제 애플리케이션을 가상의 Ta6get 머신에 탑재하여 부팅한 화면들이다. 여기서는 VMware라는 가상 머신 프로그램을 이용하였다.


임베디드 리눅스 개발 프로젝트

리눅스는 PC외에 다른 특수한 분야의 OS로 포팅되었는데, 이들은 주로 PC와는 다른 환경과 구조를 갖는 컴퓨터들이다. 대표적인 예로 산업 자동화와 군사용으로 쓰이는 VME 시스템용 OS로 리눅스가 사용되고 있다. MITRE는 군사용 장비 제조 업체로 탱크와 장갑차, 아파치 헬기 제어용으로 PowerPC603 CPU 기반의 VME 보드에 리눅스를 포팅했다. 또다른 예로 미국 NASA는 인텔 80960 CPU에 리눅스를 포팅해 네트웍 장비를 개발했다. 이외에도 리눅스는 제어계측, 게임기에도 활용되어 변용 리눅스로 포팅된 경우가 많다.

ELKS, uCLinux 등 슬림 사이즈 리눅스 들이 속속 발표 되고 있는데 이들은 주로 PDA 같은 휴대형 임베디드 장비를 타겟으로 하고 있다. PDA용 리눅스는 컴팩트한 커널에 디바이스 드라이버 사용과 기본적인 프로그래밍 환경과 PDA를 제어하고 애플리케이션을 개발할 수 있는 환경까지 제공한다. 이밖에도 etLinux, EMJLinux 등 x86 계열의 임베디드 리눅스 관련 프로젝트가 진행 중이며 Lynx Real-Time System사의BlueCat Linux, Lineo Embeddix, MontaVista  HardHat Linux 등 상용 임베디드 리눅스 시스템이 속속 출시되고 있다.

ELKS (http://www.elks.ecs.soton.ac.uk/)

대표적인 임베디드 리눅스 프로젝트로서 ELKS 커널 이미지는 대략 200K 정도이고 운용 시스템에서는 400K~512K 크기로 슬림화 하였다. ELKS 프로젝트는 다음을 적용 대상으로 진행되고 있다.


·8086 and 80286 class PC s

·Palmtop Computers

·Single board microcomputers

·Embedded controller systems

·Other old computers


ELKS는 배포되는 리눅스와는 약간의 차이점을 가지고 있는데 위의 대상에서와 같이 저성능의 프로세서와 제한된 자원을 가진 시스템에 포팅되었다. 기본 공유 라이브러리, 네트워킹 등을 제공하고 가상 콘솔, minix 파일시스템, 기본 시리얼 및 병렬 포트를 제공한다.

2000년 3월 3일에 ELKS 0.0.83 버전이 릴리즈 되었으며 네트워킹 및 새로운 디바이스에 대한 기능이 추가된 안정 버전인 ELKS 0.1.0이 곧 발표될 예정이다.


uClinux (http://www.uclinux.org/)

uClinux 프로젝트는 마이크로 콘트롤러 장비에 MMU(Memory Management Unit)를 이용하지 않는 Linux 2.0 버전을 적용하려 하고 있다. 현재 Motorola MC68000 계열의 CPU를 지원하고 있으며 3Com Pampilot에 포팅되어 Custom 부트 로더를 제공한다.

Hardware Kit 프로젝트로서 uCsimm module에 RTLinux 0.9J 를 포팅,  Real-Time 기능이 포함된 내용을 테스트하였다. 다음은 module 시스템 사양이다.


·16MHz 68EZ328 DragonBall Microcontroller

·2Mb FLASH ROM and 8Mb DRAM

·18 General Purpose I/O pins

·LCD panel QVGA resolution (320x240)

·10Base-T Ethernet

·RS-232 Serial


uClinux에서는 Linux 커널버전으로 2.0.38을 적용하였으며 이는 MMU를 지원하지 않는 RISC CPU를 대상으로 포팅하기 때문에 이러한 커널에 대한 제약이 따르고 있다. 또한 MMU가 없는 상태에서 메모리 영역을 작업과 공유하기 때문에 응용프로그램의 크기나 데이터 보호가 까다롭게 된다.


Etlinux (http://www.prosa.it/etlinux/)

Etlinux는 소형 임베디드 PC에 맞게 설계되었으며 최소사양으로 386SX 프로세서, 2MB DRAM, 2MB solid disk를 지원하고 있다. Eurotech사의 PC/104 CPU 모듈을 지원하며 CORBA 지원에 대한 내용도 포함하고 있다. Etlinux는 다음과 같은 특징을 가지고 있다.


·임베디드 WEB server (cgi)

·telnet server, email server

·CORBA 지원

·사용하기 쉬운 원격 파일 관리

·강력한 Tcl scripting language

·컴포넌트 위주의 소스 코드


Etlinux의 현재 버전은 1.2 로 커널 버전 2.0.38을 기반으로 구성하였으며 4MB DRAM을 요구한다. 특징으로는 IDE 환경의 개발 툴을 제공하는데 이 툴은 GUI 환경에서 구성 파라미터을 이용하여 간단히 설정하여 패키지 사이의 의존성을 자동으로 구성하여 주는 기능을 가지고 있다.


EMJlinux (http://www.emjembedded.com/)

EMJlinux는 EMJ Embedded System에서 만들어진 JUMPtec의 DIMM-PC에 포팅되어 있다. 부트 이미지는 1.44Mb 디스켓 한 장 사이즈로 제공되며 여기에는 설치할 수 있는 모든 환경이 구성되어 있다. v0.91버전은 약 5.7Mb의 크기를 가진다.

DIMM-PC의 16Mb 플래시 디스크 또는 IDE 디스크에 바로 다운로드되도록 설계되어 있으며 Ethernet, TCP/IP, Telnet, ft, WWW 등 다양한 네트웍 환경을 제공한다.


MicroWindows (http://microwindows.censoft.com/)

MicroWindows는 임베디드 시스템에 적용될 수 있는 저용량의 슬림 사이즈 X-Windows 시스템이며 오픈 소스 프로젝트로 진행 중에 있다. 현재 32bit 리눅스 시스템에 적용되고 있으며 16bit 리눅스인 ELKS에 포팅되어 활용되고 있다.

지원 CPU로는 Intel계열, MIPS R4000 및 ARM계열 플랫폼에 포팅되었고 최근에는 SH3에도 적용되었다. 현재 버전은 0.88pre6이며 Opera, Kaffe, GDK/GTK+ 및 FLTK가 포팅되어 지원되고 있다.


마치며

이러한 프로젝트 외에도 리눅스를 수많은 하드웨어에 포팅하려는 연구가 계속 생겨나고 있으며 우리 나라에서도 이러한 활발한 움직임이 시작되고 있다.

향후 새로운 하드웨어에 리눅스를 포팅하려는 독자는 현재 리눅스가 포팅된 플랫폼에 대한 다음의 사이트를 참고 하기 바란다.

Linux s Ports (http://linux-embedded.com/linuxports.php3)