SW 개발

winCE / kernel / 부트로더 / 부트로더의 역할과 실행순서

. . . 2009. 4. 22. 01:50
반응형

Xeno's Study Blog (http://XenoStudy.tistory.com)
- 글쓴이 : xeno
- 출처 : 나 + http://uloveus.tistory.com/177 + W.E.E.G
- 기타사항 : 여러가지 자료를 종합해서 정리;; 틀린사항은 댓글 부탁드려요

Windows Embedded CE에서의 부트로더는 호스트에서 개발 보드로, 혹은 개발 보드 내의 외부저장 공간에서 메모리로 운영체제 이미지 로딩 작업을 수행한다. 이를 하기 위하여 다음의 작업들을 수행하게 된다.

Windows Embedded CE 부트로더가 하는 일..

 

1. 개발보드 플랫폼의 디바이스들을 초기화.

2. 이더넷, 페러렐 또는 USB등의 통신 포트 초기화

3. 위의 통신 포트를 사용하여 운영체제 이미지 다운로드

4. 다운로드한 이미지를 플래시 메모리 공간에 저장

5. 부팅과정에 대한 통제 및 디버깅 설정 수행

6. 운영체제 이미지를 메모리 공간에 로딩한 후 실행

 

부트로더는 2가지 요소로 구성된다.

1. 플랫폼 빌더가 제공하는 요소

    $(_PublicRoot)\Common\oak\Drivers\ETHDBG\BLCOMMON

2. 개발자가 작성해야 하는 요소

    $(_Platformroot)\<BSP>\SRC\BOOTLOADER

 

부트로더에는 다음과 같은 함수들이 사용된다.

clip_image001[4]

 

BootloaderMain(), DownloadImage()는 플랫폼 빌더가 제공하는 함수이고, StartUP 및 OEMxxx()는 개발자가 작성해야 하는 함수이다.

부트로더의 동작 흐름을 간략하게 설명하면 다음과 같다.
StartUp -> Main() -> BootloaderMain() -> 시스템 초기화-> 운영체제 이미지 다운로드 -> 플래시 메모리 관련작업 -> 운영체제 이미지 실행

시스템 초기화 함수 : OEMDebugInit()  /   OEMPlatformInit()   /   OEMPreDownload()
운영체제 이미지 다운로드 함수 : OEMReadData() /  OEMMapMemAddr()  /  OEMShowProgress()
플래시 메모리 관련 함수 : OEMIsFlashAddr() / OEMWriteFlash() / OEMStartEraseFlash()  /
                       OEMFinishEraseFlash()  / OEMContinueEraseFlash()
운영체제 이미지실행 함수 : OEMLaunch()

앞에서 언급했던 부트로더에 사용되는 각 함수들이 하는 작업에 대해서 간략하게 설명하고자 한다.

 

Startup

  시스템이 켜진 , 처음으로 실행되는 S/W 루틴으로 개발자가 작성해야 하는 부분이다.

  함수는 CPU 초기화 하고, MMU, 캐시 등을 초기화해 가상메모리 사용이 가능하도록 한다.

  어셈블러로 작성되어 있으며, 작업이 완료되면 C언어로 구현된 Main()함수로 점프한다.

 

main()

  개발자가 작성해야 하는 부분으로 단순히 플랫폼빌더가 제공하는 BootloaderMain()을 호출한다.

void main(void)

{

    // Common boot loader (blcommon) main routine.

     BootloaderMain();

      // Should never get here.

      SpinForever();

}

 

BootloaderMain()(blcommomn.c)

  부트로더 전반적인 제어흐름을 통제하는 함수로 플랫폼 빌더가 제공하는 함수이다.

void BootloaderMain (void)

{

    ...

    // Init debug support. We can use OEMWriteDebugString afterward.

    if (!OEMDebugInit ())

    {      ...

    }

     // initialize platform (clock, drivers, transports, etc)

    if (!OEMPlatformInit ())

    {     ...

    }

    //  call OEM specific pre-download function

    switch (dwAction = OEMPreDownload ())

    {

    case BL_DOWNLOAD:

        // (5) download image

        if (!DownloadImage (&dwImageStart, &dwImageLength, &dwLaunchAddr))

        {        ...

        }

        bDownloaded = TRUE;

        // Check for pTOC signature ("CECE") here, after image in place

        if (*(LPDWORD)OEMMapMemAddr(dwImageStart, dwImageStart +

                                             ROM_SIGNATURE_OFFSET)==ROM_SIGNATURE)

        {       ...

        }

        // fall through

    case BL_JUMP:

        if (g_bBINDownload && g_pOEMCheckSignature)

        {

            if (!g_pOEMCheckSignature(dwImageStart, g_dwROMOffset,

                                     dwLaunchAddr, bDownloaded))

               HALT(BLERR_CAT_SIGNATURE);

        }

       

        //  final call to launch the image. never returned

        OEMLaunch (dwImageStart, dwImageLength, dwLaunchAddr,

                  (const ROMHDR *)dwpToc);

       ...

    }

}

 

 

DownloadImage() (blcommon.c)

  호스트로부터 이미지를 레코드 단위로 읽어들이는 역할을 수행한다. 플랫폼 빌더가 제공하는 함수이다.

 

OEMDebugInit()

  BootloaderMain() 함수로 부터 호출되는 엔트리로서, 시용될 디버그 포트를 초기화하는 역할을 수행한다.

  

OEMPlatformInit()

  BootloaderMain() 함수로 부터 호출되는 엔트리로서, 사용될 다운로드 포트를 초기화 하는 역할을 수행한다. 필요하다면 사용자의 입력을 받을 수도 있다. 이더넷 포트를 사용하기 위해 타겟을 위한 IP주소, 서브넷 마스크 등이 필요하다.

 

OEMPredownload()

  BootloaderMain() 함수로 부터 호출되는 엔트리로서, 다운로드를 주도할 호스트를 찾는 역할을 수행한다. 과정에서 디바이스는 Broadcast 패킷을 만들어, 적당한 호스트가 타겟의 부팅과정을 주도해 주기를 원한다. BOOTME 패킷을 요구하게 된다.

 

OEMMapMemAddr()

  BootloaderMain(), DownloadImage() 함수로 부터 호출되는 엔트리로서, 이미지 안에 포함된 가상주소 값이 플래시 메모리 주소인경우, 일정량 만큼의 버퍼를 할당해 개발자가 제공하도록 유도하기 위해 호출한다. 다운로드 과정이 레코드 단위이므로, 다운로드 시 플래시에 기록하는 오버헤드가 커지게 된다. 이때문에 버퍼를 요구하게 되고, 나중에 다시 적당한 시기에 플래시에 실제 기록하게 된다.

LPBYTE OEMMapMemAddr(DWORD dwImageStart, DWORD dwAddr)

{

    if (g_ImageType & IMAGE_TYPE_STEPLDR)

    {

       dwAddr = (FILE_CACHE_START + (dwAddr - STEPLDR_RAM_IMAGE_BASE));

       return (LPBYTE)dwAddr;

    }

    else if (g_ImageType & IMAGE_TYPE_LOADER)

    {

       dwAddr = (FILE_CACHE_START + (dwAddr - EBOOT_RAM_IMAGE_BASE));

       return (LPBYTE)dwAddr;

    }

    else if (g_ImageType & IMAGE_TYPE_RAWBIN)

    {

       OALMSG(TRUE, (TEXT("OEMMapMemAddr 0x%x  0x%x\r\n"),dwAddr,

            (FILE_CACHE_START + dwAddr)));

       dwAddr = FILE_CACHE_START + dwAddr;

       return (LPBYTE)dwAddr;

    }

    return (LPBYTE)dwAddr;

}

 

OEMLaunch()

  BootloaderMain() 함수로 부터 호출되는 엔트리로서, OEM으로 하여금 다운로드된 운영체제 이미지로 제어를 이행시킨다. 다운로드된 이미지를 실제로 플래시 메모리에 기록하는 작업을 시도한다.

반응형