Stop! 윈도우 임베디드 CE 시스템 개발!

글 : 라영호  / ratharn@naver.com

연재 차례

1. 윈도우 임베디드 시스템 테스팅
2. 부트로더를 통한 개발 준비  
3. 빌드이야기
4. 윈도우 임베디드 CE 6.0 커널 이야기 
5. 디바이스 드라이버 개발
 6. 디스플레이 디바이스 드라이버
 7. 원도우 임베디드 시스템, 3D의 세계로...
 8. 플래시 메모리를 저장 장치로
 9. GPS 디바이스 드라이버의 개발
 10. 선 없는 세상으로
 11. 멀티미디어 세상속으로-I
 12. 멀티미디어 세상속으로-II

/필/자/소/개/
필자는 윈도우 모바일 관련 스마트폰 개발과 윈도우CE 관련 장치를 개발하고 있다. 개인적으로 운영하고 있는 윈도우CE에 관한 블로그(www.embeddedce.com)를 통해 윈도우CE 개발에 대한 다양한 생각과 방법론을 함께 생각해 보고자 노력 중이다. 아울러 윈도우CE의 포팅 뿐만 아니라 개발에서부터 최종 제품이 나오기까지 거쳐야 할 다양한 테스트 및 신뢰성 문제에도 관심을 가지고 있다.


부트로더?

윈도우 임베디드 CE 운영체제를 이용한 시스템 개발자들이 처음 하는 작업은 "EBOOT를 동작시킨다", "EBOOT를 포팅 한다" 등 하는 말들이다. 부트로더는 부트스트랩 로더(Bootstrap Loader) 혹은 약자로는 부트로더(Boot Loader)라는 용어로 사용되고 있다. 윈도우 임베디드 CE 운영체제에서는 Eboot라는 용어로 불리고 있다. Eboot가 특별한 의미가 있는 것은 아니고 이더넷을 사용하는 부트로더라는 의미로 사용되고 있다.
최근의 경향은 이더넷을 사용하는 것뿐만 아니라 USB와 같은 통신 방법도 많이 사용되기 때문에 굳이 특별한 의미를 둘 필요는 없다. 윈도우 임베디드 시스템에서의 부트로더라는 것을 자세히 알기 위해서는 먼저 윈도우 임베디드 CE 시스템의 개발 방법 및 포팅에 대한 개념을 이해하고 접근해야 한다.

포팅, Porting

포팅의 개념을 이해하기에 앞서 하드웨어 개발 과정에 대해 먼저 이해해야 한다. PDA나 내비게이션과 같은 시스템을 만드는 것은 하드웨어를 설계하고 여기에 윈도우 임베디드 CE 운영체제를 탑재하고 내비게이션이나 동영상 재생 소프트웨어가 돌아가게 하는 일련의 과정이다. 이러한 과정 중에서 소프트웨어 엔지니어는 윈도우 임베디드 CE 운영체제가 개발한 보드에서 잘 동작할 수 있도록 만드는 작업을 해야 한다. 이러한 과정을 포팅이라는 이름으로 부르고 있다. 포팅의 과정이 필요한가에 대한 의문이 들 수 있다. 윈도우 임베디드 CE 운영체제는 이미 만들어진 운영체제이고 PC와 같이 설치하면 되는 운영체제가 아닌가? 하는 의문점을 가질 수도 있다. 윈도우 임베디드 시스템은 일반적인 PC용 운영체제와는 다른 임베디드 시스템용 운영체제다. 또한 PC와 같이 표준화된 하드웨어에 설치하는 운영체제가 아니라는데 있다. 임베디드 시스템은 제품의 사양 및 용도에 따라 다양한 하드웨어 구성이 존재한다.
이러한 하드웨어 구성에 맞추어 윈도우 임베디드 CE 운영체제를 동작하도록 만들어야 한다는 것이다.
이러한 작업은 윈도우 임베디드 CE 운영체제에서 자동으로 할 수 없는 부분이다. 이러한 부분을 동작시키도록 만드는 작업이 윈도우 임베디드 CE 운영체제의 포팅 작업의 시작이다. Eboot는 윈도우 임베디드 CE 운영체제의 포팅작업의 시작이고 운영체제를 개발하기 위한 기본 준비작업인 것이다. 그림 1은 윈도우 임베디드 CE 운영체제를 개발할 수 있는 플랫폼 빌더와 거기에서 동작하는 윈도우 임베디드 CE 운영체제의 동작 화면이다.

EBOOT는?

EBOOT는 Ethernet Boot loader의 약자다. 이더넷을 사용하는 부트로더 혹은 이더넷 기반 부트로더라는 의미로도 사용된다. 윈도우 임베디드 CE의 개발 환경을 살펴보면 이더넷을 통한 작업이 대부분이다. 이더넷을 통해 운영체제 이미지를 다운로드하고 다운로드 한 운영체제 이미지를 디버깅한다. 이제는 이더넷뿐만 아니라 USB 등과 같이 고속의 통신 방법을 통해서도 운영체제 이미지 및 디버깅이 가능하다. 윈도우 임베디드 CE 운영체제가 처음 나왔을 때는 시리얼이나 하드웨어 디버거를 통한 디버깅 방법이 대부분이었던 시절이라 이더넷을 통한 운영체제 개발은 획기적이었을 것이다. 물론 다른 임베디드 운영체제도 이더넷과 같은 통신 방법을 지원하기도 했었다. EBOOT의 가장 큰 역할은 운영체제 이미지를 개발 보드상에 다운로드 하고 디버깅 할 수 있는 환경을 제공하는데 있다. 여기에 아울러 개발 하드웨어에 대한 메모리 및 하드웨어에 대한 초기화 작업을 통해 윈도우 임베디드 CE 운영체제가 제대로 동작할 수 있는 환경을 제공하는데 있다. 하지만 현재 개발 환경은 낸드(NAND) 부팅 및 다양한 동작 환경을 지원하기 때문에 EBOOT의 역할이 점차 줄어들고 있다. 하지만 윈도우 임베디드 CE 운영체제를 개발하는데 있어서 중요한 요소를 차지하기 때문에 아직까지도 EBOOT는 중요한 요소 중에 하나다. 그림 2는 윈도우 임베디드 CE 운영체제의 전체 구조를 그림 3은 EBOOT의 구조를 설명하는 그림이다.

윈도우 임베디드 시스템의 개발 절차

EBOOT라는 부트로더를 살펴보기 전에 윈도우 임베디드 CE 운영체제 개발에 대한 전반적인 절차를 살펴보도록 하겠다. 윈도우 임베디드 CE 시스템 개발은 복잡한 단계를 거친다. 다른 임베디드 시스템 개발과 큰 차이는 없을 것이다. 본 절차는 하드웨어는 개발돼 있다는 가정하에 윈도우 임베디드 시스템의 개발 단계를 개략적으로 구분한 것이다.

딜레마(Dilemma)

윈도우 임베디드 CE 운영체제를 처음 개발하는 개발자들을 여러 종류다. 다른 운영체제를 개발하다가 윈도우 임베디드 CE 운영체제를 시작하는 경우, 하드웨어 엔지니어를 하다가 하는 경우 등 다양한 경우가 존재한다. 이제는 윈도우 임베디드 시스템에 대한 개발 과정 및 방법론이 어느 정도 체계가 잡혔지만 그렇다고 해서 특정한 누군가 전공한 사람이 해야 하는 것으로 정해지지는 않았다.
다만, 프로세서와 하드웨어에 대한 개념 및 이해가 있다면 좀 더 빨리 접근할 수 있다는 것이다. EBOOT와 같은 부트로더를 봐도 그렇다. 개발한 하드웨어에 포팅 작업을 해야 하기 때문에 메모리에 따른 설정 변경, 회로도의 이해, 하드웨어 부품들의 동작 이해가 필요하다. 따라서 PC에서와 같이 Win32 API나 C#과 같은 프로그래밍 지식만 가지고는 접근하기에는 쉽지가 않다. 하지만 시스템을 자세히 이해하고 개발하기 위해서는 윈도우 시스템에 대한 이해도 필요하다. 따라서 순수한 소프트웨어 엔지니어에게는 하드웨어 관련된 지식이 하드웨어 엔지니어에게는 윈도우 시스템에 대한 지식이 필요하다는 것이다.

부트로더의 자세한 기능

쪾하드웨어의 초기화 - 개발 보드가 정상적으로 동작 하도록 프로세서를 초기화 하고 메모리를 설정하고 부착된 장치를 초기화 한다. 초기화의 의미는 동작 하도록 전원을 인가하는 것부터 동작에 필요한 명령을 수행하는 작업을 하는 것이다. 보통 제공되는 BSP에 초기화 코드는 어셈블러 형태로 제공되며 개발 초기에 이루어지는 중요한 작업이다. 제공되는 BSP가 대부분 프로세서 검증용으로 프로세서 제조사에서 만든 개발보드용으로 만들어졌기 때문에 설계 시 변경된 하드웨어 맞추어 초기화 코드를 수정해 주여야 한다.

쪾하드웨어 설계 검증 및 회로 검증 - 초기 부트로더 개발 작업 중 대부분의 시간을 차지하는 부분일 것이다. 보드가 처음 나오면 잘 만들어 졌고 동작을 할 것이라는 기대를 할 수 있겠지만 그건 대부분 큰 오산이다. 대부분 개발자의 직접/간접적인 실수로 문제가 있을 경우가 대부분이고 보드 설계에 핵심인 PCB가 문제가 되는 경우 때문에도 문제가 발생하기도 한다. 이러한 문제를 조기에 찾아낼 수 있도록 하는 것이 부트로더 개발 중 하드웨어 설계 검증 및 회로 검증 단계이다. 시리얼 포트, LCD, LED를 통하여 개발자에게 문제점을 알려줌으로써 하드웨어 개발에 박차를 가할 수 있는 것이다.

쪾운영체제 개발 환경 제공 - 비록 운영체제의 대부분이 마이크로소프트사에 제공되지만 개발한 항목과 운영체제가 잘 돌아가는지, 문제가 발생한다면 어떤 문제인지 확인할 수 있는 방법이 필요하다. 부트로더 단계에서는 하드웨어 JTAG 디버거를 가지고 문제점 디버깅이 가능하지만 운영체제 단계에서는 JTAG 디버거로 할 수 있는 한계가 있다. 그래서 제공하는 것이 윈도 임베디드 CE가 제공하는 것이 KITL이라는 것이고 이것을 포팅 하는 작업을 부트로더에서 해야 한다. KITL(Kernel Independent Transport Layer)은 개발된 보드에 윈도 임베디드 운영체제가 동작할 때 운영체제를 디버깅하게 해주는 통신 채널이다. 이더넷, USB, 시리얼 등 보드가 제공하는 통신 포트를 이용하여 개발 PC와 통신을 하면서 운영체제가 제대로 동작하는지 디버깅 및 검사할 수 있게 해준다. 개발 보드에서 제공하는 것이 USB KITL이라면 보드에 있는 USB 장치 부분을 초기화 하고 PC의 플랫폼 빌더나 비주얼 스튜디오에서 인식하여 운영체제를 디버깅 할 수 있도록 환경을 만드는 작업이라고 하겠다.

쪾OS 다운로더 환경 제공 - 위의 두 항목이 윈도 임베디드 운영체제에서 제공되는 기본 기능에 대해 작업하는 것이라고 하면 지금부터 설명하는 두 가지 작업 내용은 개발 회사의 필요에 의해 추가 되는 작업으로 이해하면 좋을 것이다. 윈도 임베디드 CE의 운영체제 이미지는 PC로부터 KITL을 통해 다운로드 및 플래시에 저장이 가능하지만 제품으로 만드는 최종 제품에서도 그러한 방식으로 할 수는 없는 것이다. 그래서 부트로더에 운영체제 이미지를 다운로드 하여 업그레이드 기능을 제공하는 추가하기도 한다. 제품이 출시된 후 사용자가 업그레이드 할 수 있는 기능을 제공하기 위해서도 제공되는 기능이다. 업그레이드 방식은 USB 방식을 많이 구현하고 있고 일부 업체에서는 SD/MMC나 CF 카드를 통한 업그레이드 기능을 제공하는 경우도 있다. 최종 제품을 생산할 경우에도 업그레이드 기능이 있으면 양산시 도움이 되기 때문에 개발 시 구현해 놓으면 좋은 기능이다. 양산 때까지 모든 기능을 구현할 수 있는 회사는 드물기 때문에 양산 후 최종 수정된 운영체제 이미지를 업그레이드 하여 출시하는 방법도 고려해 두어야 한다.

쪾하드웨어 테스트 기능 제공 - 개발 중에 필요한 작업은 아니지만 최종 양산시를 고려하여 추가하는 작업이다. 생산된 제품이 자동 또는 수동으로 문제가 없는지 검사하는 기능을 추가하는 것이다. 생산이 되고, 생산된 보드를 케이스에 조립을 하고 전원을 넣으면 자동으로 자체 검사하는 화면이 나와 조립된 하드웨어의 문제가 없는지 리포트 해주는 기능을 구현하는 것이며 생산성을 향상시키기 위해 추가한다. LCD가 켜져 LCD의 불량 화소가 있는지 검사할 수 있게 하는 화면을 띠우고 사운드가 출력되어 스피커 조립은 이상이 없는지 등등 테스트를 하게 된다. 하드웨어 사양에 따라 다양한 테스트 방법 및 순서가 있을 것이므로 생산 시나리오에 따라 제작하는 것을 권한다. 빠른 생산성을 추구하며 개발하는 것이 하드웨어 테스트 기능 제공의 목적이기 때문이다.

EBOOT 구성 함수들

윈도우 임베디드 CE 운영체제를 구성하는 부트로더를 구성하는 함수들에 대해서 살펴보도록 하겠다. EBOOT를 구성하는 소스는 EBOOT 소스뿐만 아니라 윈도우 임베디드 CE 운영체제의 구성요소로 포함되는 공용 라이브러리를 포함하여 EBOOT 실행 이미지가 만들어진다. EBOOT는 통상 PlatformSrcEBOOT 디렉터리에 대부분의 소스가 있다. 그 밖의 파일들 PublicCommonOakDriversEthdbg Blcommon과 같은 디렉터리에 포함되어 있다.
EBOOT의 동작이나 구성을 이해하기 위해서는 각각의 함수에 대한 내용 및 소스를 분석하는 것이 중요하다. 표 2는 EBOOT를 구성하는 대표적인 함수에 대해 설명한 것이다.

EBOOT.BIB

EBOOT를 구성하는 파일 중에서 중요한 역할을 하는 것이 .BIB 형식의 파일이다. 이 BIB 파일은 앞으로 윈도우 임베디드 CE 운영체제 이미지를 구성할 때도 중요한 역할을 하기 때문에 자세히 살펴보도록 한다. BIB 파일은 EBOOT가 동작할 때 사용하는 메모리, 스택 및 미리 할당된 영역을 설정한 파일이다. RAM의 경우 EBOOT가 동작 중에 사용하는 RAM의 시작주소 및 크기를 지정할 때 사용한다. EBOOT는 EBOOT의 시작 위치 및 크기를 지정할 때 사용한다. BIB 파일에서 MEMORY 섹션은 EBOOT에서 사용하는 메모리의 위치 및 크기를 지정할 때 사용한다.

MEMORY
;   Name     Start     Size      Type
;   ----  -----  ----  ---
ARGS     80020800  00000800  RESERVED
RAM      83D8C000  00060000  RAM   
STACK    83DEC000  00004000  RESERVED
EBOOT    80038000  000A0000  RAMIMAGE
BINFS    800D8000  00021000  RESERVED
DISPLAY  80100000  00100000  RESERVED

CONFIG
// 중략
ROMSTART=80038000
ROMWIDTH=32
ROMSIZE=A0000

MODULES
;Name                  Path                               Memory Type
;---------     -----------          -----
nk.exe $(_TARGETPLATROOT)target$ (_TGTCPU)$(WINCEDEBUG)eboot.exe                                              
EBOOT

CONFIG 섹션은 EBOOT의 시작주소, EBOOT의 시작 주소를 지정할 때 사용한다. 위에서 지정한 EBOOT는 0x80038000의 시작주소를 가지고 0xA0000의 크기를 가진다.

StartUp.S

EBOOT에서도 시작이 있고 끝이 있다. 개발 보드에 전원 스위치를 통해 전원을 공급하면 리셋 동작에 의해 프로세서가 동작하기 시작하고 노어 플래시나 낸드 플래시에 기록되어 있는 EBOOT이 동작되기 시작한다. 이때 처음 동작하는 루틴이 StartUp 함수이고 이 함수를 통해 EBOOT의 동작이 시작된다. StartUp.S 소스의 기본적인 동작은 프로세서를 초기화하고 GPIO, 메모리 등을 초기화 하여 동작할 수 있는 환경을 설정하는 것이다. 또한 가장 중요한 작업중의 하나인 가상 메모리 맵을 설정하는 것이다. 윈도우 임베디드 CE 운영체제는 MMU를 사용하여 가상 메모리를 관리 운용하여 동작하는 운영체제이다. 따라서 동작의 중요한 요건은 가상 메모리를 설정하는 것이다. 그림 4는 윈도우 임베디드 시스템의 가상 메모리에 대해 설명한 그림이다.

LEAF_ENTRY StartUp

; Jump over power-off code.
1      b             ResetHandler
b %B1     ;HandlerUndef    ;handler for Undefined mode
b %B1     ;HandlerSWI     ;handler for SWI interrupt
b %B1     ;HandlerPabort   ;handler for PAbort
b %B1     ;HandlerDabort  ;handler for DAbort
b %B1     ;                 ;reserved
b %B1     ;HandlerIRQ  ;handler for IRQ interrupt
b %B1     ;HandlerFIQ  ;handler for FIQ interrupt

ResetHandler
; RESET 핸들러
mov    r0, #0
mcr    p15, 0, r0, c8, c7, 0    ; TLB를 초기화 한다
mcr    p15, 0, r0, c7, c5, 0    ; 명령어 캐쉬를 초기화 한다.
mcr   p15, 0, r0, c7, c6, 0    ; 데이터 캐쉬를 초기화 한다.

ldr  r0, =WTCON      ; 와치독 타이머를 끈다.
mov               r1,#0        
str r1, [r0]

    // 중략
; Compute physical address of the OEMAddressTable.
20   add r11, pc, #g_oalAddressTable - (. + 8)  ;
g_oalAddressTable를 통하여 가상 메모리 맵을 설정한다
ldr    r10, =PTs         (r10) = 1st level page table

VirtualStart
mov   sp, #0x80000000  ;have to be modefied. refer
oemaddrtab_cfg.inc, DonGo
add    sp, sp, #0x30000 ;arbitrary initial super-page stack pointer

b      main

Oemaddrtab_cfg.inc

앞에서 설명한 가성 메모리를 지정하는 소스는 보통 BSP의 PlatformSrcInc 디렉토리에 있는 oemaddrtab _cfg.inc 파일에 구성되어 있다. 프로세서에서 사용하는 실제 하드웨어의 주소와 가상 메모리 주소를 1대1로 설정하도록 구성할 수 있다. 가상 메모리에 대한 설정은 윈도우 임베디드 CE 운영체제에서 중요한 부분이다. 디바이스 드라이버 및 응용 프로그램에서 하드웨어에 대한 제어를 할 때 모두 가상 메모리를 통해 제어를 하기 때문에 가상 메모리에 대한 이해는 윈도우 임베디드 CE 운영체제를 사용하기 위한 중요한 내용이다.

EXPORT  g_oalAddressTable[DATA]

;---------------------------------------
;
; 설정 양식은 다음과 같다.
;       캐쉬된 가상 주소, 물리 주소, 크기
;---------------------------------------

g_oalAddressTable

DCD  0x80000000, 0x30000000, 64      ; 64 MB DRAM BANK 6
DCD  0x88000000, 0x10000000, 16   ; 32 MB SROM(SRAM/ROM) BANK 2
DCD  0x8A000000, 0x20000000, 48     ; 32 MB SROM(SRAM/ROM) BANK 4
                  // 중 략
DCD  0x92400000, 0x59000000, 1       ; SPI Port register
DCD  0x92500000, 0x5A000000,  1      ; SDI Port register
DCD   0x92600000, 0x5B000000,  1      ; AC97 Port register

DCD   0x93000000, 0x00000000,32   ; 32 MB SROM(SRAM/ROM) BANK 0
DCD     0x00000000, 0x00000000, 0      ; end of table

이더넷 초기화 함수

EBOOT에서 중요한 이더넷 초기화는 InitEthDevice() 함수를 통해 초기화 한다. 이 초기화 함수를 통해 이더넷 컨트롤러인 CS8900에 대한 제어 함수에 대한 포인터를 전달하게 된다. EBOOT는 CS8900DBG_Init(), CS8900DBG_Get Frame(), CS8900DBG_SendFrame() 함수를 통하여 이더넷 통신을 진행하게 된다.
BOOL InitEthDevice(PBOOT_CFG pBootCfg)
{
volatile S3C2443_SSMC_REG *s2443SSMC =(S3C
 2443_SSMC_REG *)
OALPAtoVA(S3C2443_BASE_REG_PA_SSMC, FALSE);
PBYTE  pBaseIOAddress = NULL;
UINT32 MemoryBase = 0; 
BOOL bResult = FALSE;

OALMSG(OAL_FUNC, (TEXT("+InitEthDevice.rn")));

memcpy(pBSPArgs->kitl.mac, pBootCfg->EdbgAddr
.wMAC, 6);

// Use the CS8900A Ethernet controller for download.
//
pfnEDbgInit             = CS8900DBG_Init;
pfnEDbgGetFrame   = CS8900DBG_GetFrame;
pfnEDbgSendFrame = CS8900DBG_SendFrame;
pBaseIOAddress   = (PBYTE)OALPAtoVA(pBSPArgs-
>kitl.devLoc.LogicalLoc, FALSE);
MemoryBase       = (UINT32)OALPAtoVA(BSP_BASE_
REG_PA_CS8900A_MEMBASE, FALSE);
   
//RETAILMSG(1,(TEXT("0x%X 0x%Xn"),pBaseIOAdd ress,MemoryBase));
// Initialize the Ethernet controller.
//
if (!pfnEDbgInit((PBYTE)pBaseIOAddress, Memory Base, pBSPArgs->kitl.mac))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: InitEthDe
vice: Failed to initialize Ethernet controller.rn")));
goto CleanUp;
}

// Make sure MAC address has been programmed.
//
if (!pBSPArgs->kitl.mac[0] && !pBSPArgs->kitl.mac[1] && !pBSPArgs->kitl.mac[2])
{
OALMSG(OAL_ERROR, (TEXT("ERROR: InitEthD
evice: Invalid MAC address.rn")));
     goto CleanUp;
}

bResult = TRUE;

CleanUp:

OALMSG(OAL_FUNC, (TEXT("-InitEthDevice.rn")));
    return(bResult);
}
EBOOT의 메뉴

EBOOT에서 사용자의 각종 명령을 시리얼 통신을 통해 처리하고 운영체제 이미지를 다운로드 및 실행에 설정을 할 수 있다. 이 기능은 MainMenu() 함수를 통해 이루어진다. 설정이나 명령은 디버그 시리얼 포트를 통해 PC와의 통신을 통해 이루어진다.

static BOOL MainMenu(PBOOT_CFG pBootCfg)
{
BYTE KeySelect = 0;
BOOL bConfigChanged = FALSE;
BOOLEAN bDownload = TRUE;

while(TRUE)
{
KeySelect = 0;

EdbgOutputDebugString ( "rnEthernet Boot Loader Configuration:rnrn");
EdbgOutputDebugString ( "0) IP address: %srn",inet_ntoa(pBootCfg->EdbgAddr.dwIP));
EdbgOutputDebugString ( "1) Subnet mask: %srn", inet_ntoa(pBootCfg->SubnetMask));
EdbgOutputDebugString ( "2) DHCP: %srn", (pBootCfg->ConfigFlags & CONFIG_FLAGS_DHCP)?"Enabled":"Disabled");
EdbgOutputDebugString ( "3) Boot delay: %d secondsrn", pBootCfg->BootDelay);
EdbgOutputDebugString ( "4) Reset to factory default configurationrn");
           // 중략
while (! ( ( (KeySelect >= '0') && (KeySelect <= '9') ) ||
( (KeySelect == 'A') || (KeySelect == 'a') ) ||
( (KeySelect == 'B') || (KeySelect == 'b') ) ||
( (KeySelect == 'D') || (KeySelect == 'd') ) ||
( (KeySelect == 'E') || (KeySelect == 'e') ) ||
                   // 중략
( (KeySelect == 'X') || (KeySelect == 'x') ) ))
{
KeySelect = OEMReadDebugByte();
}
switch(KeySelect)
{
case '0':           // Change IP address.
SetIP(pBootCfg);
pBootCfg->ConfigFlags &= ~CONFIG_FLAGS_DHCP;   // clear DHCP flag
bConfigChanged = TRUE;
break;
case '1':           // Change subnet mask.
SetMask(pBootCfg);
 bConfigChanged = TRUE;
break;

그림 5는 EBOOT의 실제 동작 화면이다. PC의 하이퍼터미널 프로그램을 통해 EBOOT의 각종 명령이 출력되고 제어할 수 있게 해준다.

NAND 부트로더

낸드 플래시 메모리가 가격 및 용량의 장점으로 널리 사용되는 추세이기 때문에 낸드 플래시 메모리를 이용한 부팅 방법이 윈도우 임베디드 CE 운영체제에서 사용되고 있다. 이러한 기능을 하는 것이 낸드 부트로더다. 낸드 부트로더의 경우 흔히 프로세서 내부에 있는 SRAM 영역에 낸드 부트로더로 동작할 영역이 저장되어 있는 0번 블록의 프로그램을 읽어 들여 실행시키는 역할을 한다. 윈도우 임베디드 CE 운영체제에서는 낸드 부트로더가 EBOOT를 읽어 들이거나 운영체제 이미지를 읽어 들여 실행하는 등의 구조로 변경돼 사용되고 있다.

부트로더 추가 기능

지금까지 EBOOT의 기능 및 구현에 대해 간략히 살펴봤다. EBOOT의 기능은 윈도우 임베디드 CE 운영체제를 개발하기 위한 개발환경을 만드는데 있다. 하지만 실제 제품의 개발 및 양산에는 제품을 테스트하기 위한 테스트 코드, 부팅할 때 제품의 로고를 보여주기 위한 LCD 초기화 및 로고 로드 코드 등 다양한 부가 기능이 추가가 된다. 다음은 EBOOT에서 인터럽트를 처리하기 위한 Isr_Init()는 함수이다. EBOOT에서는 대부분 인터럽트를 처리하는 방식이 아니라 폴링을 통한 처리 코드를 사용했었다. 다음 코드를 사용하여 인터럽트 서비스 루틴을 설치하고 인터럽트를 처리하도록 구성하는 소스이다.
 
void Isr_Init(void)
{
volatile S3C2443_INTR_REG *s2443INT = (S3C2443_INTR_REG *)
OALPAtoVA(S3C2443_BASE_REG_PA_INTR, FALSE);
s2443INT->INTMOD=0x0;               // IRQ 모드로 인터럽트를 설정한다.
s2443INT->INTMSK=BIT_ALLMSK;    // 모든 인터럽트를 마스크한다.

//  IsrHandler라는 인터럽트 처리 루틴을 다음 코드를 통해 설치한다.
pISR =(unsigned)(0xEA000000)+(((unsigned) IsrHandler - (0x80000000 + 0x18 + 0x8) )>>2);

if (s2443INT->SRCPND & BIT_USBD) s2443INT ->SRCPND  = BIT_USBD;
if (s2443INT->INTPND & BIT_USBD) s2443INT ->INTPND = BIT_USBD;
s2443INT->INTMSK &= ~BIT_USBD;  // USB 관련 인터럽트를 설치한다.
}

끝으로

지금까지 EBOOT 및 윈도우 임베디드 CE 개발에 관한 사항에 대해 살펴봤다. EBOOT는 단순한 부트로더라기 보다는 개발 환경을 준비하기 위한 개발 준비 항목이다. 윈도우 임베디드 CE 운영체제는 개발 자체보다는 디버깅이 더 중요한 운영체제이다. 어떻게 쉽게 문제점을 확인하고, 어떻게 문제점을 찾고 하는 문제가 더 중요하다는 것이다. 이런 것을 제대로 하기 위해서는 EBOOT가 제대로 동작해야 한다. 아쉽게 EBOOT에 대해 전체적인 내용만 살펴봤다.


회원가입 후 이용바랍니다.
개의 댓글
0 / 400
댓글 정렬
BEST댓글
BEST 댓글 답글과 추천수를 합산하여 자동으로 노출됩니다.
댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글수정
댓글 수정은 작성 후 1분내에만 가능합니다.
/ 400
내 댓글 모음
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지