ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BootROM,Blcommon.c
    WINCE 2012. 1. 2. 11:06
    Boot ROM 이란걸 정리하면, CPU 가 처음 켜지고 어떻게 동작할것인지 미리 정의 해놓은 ROM 영역이다.
    저 Boot ROM 은 CPU 마다 모두 다르며, CPU 가 만들어 질때부터 만들어져 나오게 된다. 그렇기 때문에, 저 영역을
    개발자가 건드리는 부분은 아니다.
    언제든지 프로세서는 리셋벡터로 점프하기 위한 파워 전이를 통해서 가게되며, Boot ROM 은  하드웨어 메커니즘에 따라 물리영역으로 분기하기도 하고, 가상영역으로 분기하기도 한다. 

    0x0000_0000 - 0x0000_BFFF - 물리메모리 영역
    0x5E00_0000 - 0x5E01_FFFF - 가상메모리 영역

    분기하고 난뒤에, 저 영역에 있는 어셈코드를 읽고나서 플레쉬에 있는 Bootloader 부분을 RAM 으로 복사를 해오게 된다.
    그렇게 되고 난뒤에, RAM 에 올라와 있는 startup() 코드를 읽게 되고, 다시 그부분에서  main() 영역으로 분기하게 된다.
    startup 코드에선 이셉션 벡터를 설정하고, 인터럽트 disable, PLL(Phase Locked Loop : 출력 주파수 및 위상을 차참조 입력신호와 동기 시킨다.) 셋팅을 하게 된다.
    (exception vector 에 대해서 -   http://recipes.egloos.com/5035801  )
    main() 코드에선 다시 Bootloadermain() 함수를 호출하게 되고, 특별한 동작을 main() 함수에선 동작하지 않는것으로 판단되어 진다. 

    왜 부트로더가 시작할때, 굳이 start.s 부분과 main.c 부분을 나누어 놨을까? 
     - 이부분은 start.s 의 특성에서 찾을수 있다.arm 어셈블러로 작성되어 있고, 스택이 없기 때문에 다중호출도 안되며
       main.c 이 존재하는 절대값 주소로 호출(부트로더 프로세스 와 main 프로세스는 다른 프로세스 이므로 심볼릭 참조가 불    가능)을 지정을 해줘야 한다.
       그렇기 때문에 Bootloader 가 수행될때, start.s 부분과 main.c 부분이 모두 플레쉬 메모리에서 램 영역으로 모두 복사가      이루어진다. 부트로더 영역은 대부분 램 영역에서 수행이 된다. 이유는 ROM 영역에서 읽고 쓰기의 시간이 RAM 영역에      비해 많이 느리기 때문에,시스템 수행시간상 RAM 영역에서 이미지를 올려놓고 동작을 하게 된다. 



    PPT 관련해서 시나리오
    Wince 의 기본이 되는 동작을 먼저 살펴 보겠다. Blcommon 의 레이어를 쉽게 이해를 하면 start.s 는 발,main.c 는 허리, Blcommon.c 는 머리에 해당한다. 그렇기 때문에 발에서 걷기 위한 설정을 하게 되고, Main.c 는 머리를 건너가기 위한 중간 매체가 된다. 역할로는 여러가지 머리가 있을때, 알맞는 머리로 가기 위한 다리이다.그리고 Blcomon.c 는 머리로서, 머리가 동작하기 위한 동작을 Blcommon.c 에서 하게 된다.

    이렇게 큰 그림을 그리고 나서, start.s 먼저 살펴보겠습니다. startup.s 에서 하는동작은 우선 다음과 같습니다. 발생하게 되는 인터럽트 처리를 위한 이셈션 벡터를 먼저 설정하고(여기에는 CPU 내부에서 동작하는 레지스터 세팅들도 들어가게 됩니다. 이후에 큰 과정을 설명할때도, 내부적으로 레지스터를 설정하게 됩니다.) 그 다음에 불필요한 인터럽트를 모두 죽입니다.그리고 이후에 허리를 건너가기 위한 환경설정을 합니다.
    함수가 수행되기 위한 스택포인터를 설정을 하고, WINCE 에서 가상메모리를 사용하기 위해서 메모리 컨트롤러도 설정을 하게 됩니다. 그 다음에 하드웨어 특성에 맞게 정의해놓은 환경변수를 사용하기 위해 변수를 초기화 하게됩니다.

    여기 까지 하게 되면 일단 최소한의 main.c 함수가 수행될 환경이 준비가 됩니다. 여기 내용에는 없지만, WatchDog 이라고 이후에 수행하게 되는 동작을 감시하기 위해 디버그 UART 설정도 하게 됩니다.

    그럼 해당 조건이 모두 만족하게 되면 main.c 로 분기를 하게 됩니다. 그럼 main.c 로 들어오게 되면, 여기서는 단순하게 BootloaderMain 함수를 다시 호출하게 됩니다. 딱히 하는일이 없습니다. 단순히 BootloaderMain 을 호출하는 역할만 하게 되는데, 그래서 책에 보면 이 main.c 을 거치치 않고, 바로 다음에 호출될 BootloaderMain 을 호출하는게 더 자연스러울지 모르겠다고 하지만, 딱히 이유를 설명하고 있지는 않습니다. 유추를 해보면, 나중에 어떤 설정을 하기 위한 확장성을 위해서 들어가있는것으로 일단 판단이 되어집니다.

    이제 그 이후에 Blcommon.c 가 호출이 되고, 여기서부터 실제로 OEM 들이 구현하게 될 코드 부분이 됩니다.Blcommon 이 이미 만들어놓은 내용을 살펴보면 보시는 바와 같은 큰 기능들을 수행합니다. 디버그 설정, 플랫폼 설정, 이미지 다운로드 , 다운받은 운영체제로의 제어 이행. 이렇게 구동을 하게 됩니다. 다운받은 운영체제로의 이행을 하게 되면, 본격적으로 커널이 올라가게 되고 OS 가 구동이 시작하게 되겠죠.

    각 함수들에 대해서 간략하게 말씀드리면, OEMDebugInit 은 디버깅에 사용될 포트들에 대한 각종설정을 합니다. 그리고 OEMPlatforInit 선 pci 환경설정,PCMCIA 콘트롤 초기화, 그리고 전역 환경변수 로드를 하고 전역함수로 사용할 함수 포인터를 설정을 하게 됩니다.그렇게 설정을 하게 된뒤에, 다운로드 정책에 따라 HOST 에서 바이너리를 다운받거나 ROM 에서 바이너리를 램으로 옮겨지게 됩니다.그리고 OEMMapMemaddr 는 BootloaderMain 함수와 DownloadImage 함수에서 호출되는 엔트리로서, 이미지 안에 포함된 가상주고 값이 플래쉬 메모리 주소인경우, 일정량 만큼의 버퍼를 할당해 개발자가 제공하도록 유도하기 위해서 호출합니다.그리고 나중에 적당한 시기에 플래시에 기록을 하게 됩니다. 그리고 OEMLaunch 가 분기할 주소로 분기를 하게 되고, 이때 다운로드된 이미지를 플래쉬에 기록하는 작업을 하게 됩니다.

    ================
    여기 Blcommon.lib 도식화된 부분 설명
    ===============
    그럼 지금까지 살펴본 내용을 토대로 저희 코드를 살펴보겠습니다.
    저희 소스를 살펴보면 크게 AtoB 부분과 ATBoot 라는 부분을 살펴보겠습니다. 간혹 AtoB 를 MOBM 이라고 부르기도 하며, ATBoot 를 ATBT 라고 부르기도 합니다.MOBM 같은 경우는 Mini OEM B(여기 마저 채울것) 라는 뜻을 가지고 있습니다.간단하게 역할을 정의하면, AtoB 는 CPU 안에 있는 주변 콘트롤들을 셋팅을 합니다.그리고 ATBoot 는 실제로 OEM 영역으로 저희가 가지고 회로에 따라, 특정 셋팅들 을 해줍니다.
    먼저 ATOB 부분을 살펴보면 콘트롤별로 클럭셋팅을 해주고, 스택포인터를 설정해 줍니다. 클럭셋팅의 경우 CPU 클럭 정책에 따라, 주변 장치들의 클럭들을 어떻게 설정을 할지를 정의합니다.그리고 스택포인터는 현재 startup.s 이후에 실행하게 될 main.c 함수를 호출해주기 위해서 스택영역을 잡아주게 됩니다.그리고 그 외에 확장될수 있는 PCCARD 설정, 그리고 내부 코프로세서 레지스터 설정, 그리고 SDRAM 등을 계속해서 리프레쉬 해주는 셋팅을 하게 됩니다. SDRAM 의 특성상 계속해서 REFRESH 를 해주어야 데이터가 유지 되기 때문에, 해당 리프레쉬 셋팅도 해줍니다.그리고 레지스터중 디버깅 메지시를 출력해주는 CP15번 레지스터를 셋팅해줍니다. 여기까지 하게 되면 하드웨어적으로 주변 장치들에 대한 하드웨어 셋팅을 하게 됩니다. 이렇게 한뒤에 main.c 로 분기를 하게 됩니다.
    여기에서 하는 일을 크게 현재 사용되고 있는 하드웨어 버젼에 따른 전역변수를 초기화를 해주고, 그리고 atbt 부트를 램으로 카피를 해주게 됩니다. 현재 여기까지는 MMU가 셋팅이 안되어 있습니다. 그렇기 때문에 현재까지 사용하는 주소는 모두 물리주소를 사용하게 됩니다. 그 다음에 ATBOOT 영역에서 MMU 가 셋팅이 되게 디고,그때부터 이제 가상주소를 사용할수 있게 됩니다.
    그럼 ATBOOT 영역으로 넘어가면 여기 또한 startup.s로 들어가게 됩니다.여기에서 이제 실제 OS 에서 사용하게 될 OEMpageTable 를 이용하여 MMU 를 셋팅을 해주게 되빈다. 여기서 MMU 를 어떻게 설정을 해주느냐에 따라 1레벨,2레벨,3레벨등으로 나누어집니다. 저희가 사용하는 MMU 레벨을 1레벨을 사용하여 사용하고 있습니다.이것이 TTB 라고 해서 OEMpageTable 에 정의되어 있는 주소를 토대로 MMU 셋팅해주게 됩니다(여끼 다시 추가해주어야 함)
    그리고 CPU 가 가지고 있는 모드중 IRQ,SVC 모드에 따라서, 사용하게 될 sp 등을 설정을 해주게 됩니다.
    이렇게 하고 나서 부트로더 단계의 마지막이라 할수 있는 atbt 의 main.c 수행을 합니다. 여기에서는 사용자에게 부트메뉴를 출력하고, 사용자가 선택을 하게 되면, USB Download 기능, 업데이트 기능등이 수행을 하게 됩니다.그리고 내부적으로는 사용하게 될 전역변수등을 램으로 카피를 하고,주변장치들의 파워를 ON 하게 됩니다.

    'WINCE' 카테고리의 다른 글

    제어판에 등록하기 위한 cpl.h 헤더파일  (0) 2012.06.19
    XLLP 와 XLLI  (0) 2012.06.07
    image 의 Load View 와 execution view  (0) 2012.02.21
    비트논리연산 자료  (0) 2012.01.27
    용어  (0) 2012.01.25
Designed by Tistory.