ARM System Developer's Guide  

- Designing and Optimizaing System Software




#####

Firmware and BootLoader

Example : SandStone




### 10.1. 펌웨어와 부트로더


# 펌웨어

: 하드웨어OS/Applications 레벨의 소프트웨어 사이의 인터페이스를 제공하는 하위 레벨 소프트웨어

- ROM에 상주, 시스템전원이 공급될 때 실행됨

- 시스템초기화가 된 후에도 실행 가능한 상태로 남아있을 수 있으며 기본적인 시스템 동작을 지원

- 주요 목적 : OS를 롣하여 부팅하기 위한 안정적인 mechanism을 제공


# 부트로더

: OS나 응용프로그램을 하드웨어 타겟 메모리로 다운로드 후 해당 소프트웨어로 pc 제어권을 넘기는 작업을 수행하는 작은 application

- OS나 응용프로그램이 시행되고 있는 시점에서 존재하며 일반적으로 펌웨어에 통합되어 있음


# 펌웨어 실행과정


1. Set up target platform

- 운영체제를 부팅하기 위한 환경을 준비

- 플랫폼이 초기화가 잘 되었는지 확인하는 작업도 수행

- 같은 실행 이미지를 다른 코어나 플랫폼 상에서 동작시키므로 정확한 코어의 종류와 플랫폼을 검색할 수 있어야 함

코어의 종류는 보통 코프로세서 0번째 레지스터에 저장되어 있음. (프로세서의 종류, 제조사 , ...)    

플랫폼의 종류는 특정 주변장치의 존재 여부를 체크, 칩에 저장된 정보를 읽기 등 다양한 방법이 존재

- 진단소프트웨어는 하드웨어의 불량 여부를 알아내는 유용한 방법을 제공하며 특성상 특정 하드웨어에 의존적임

- 디버깅 기능은 하드웨어 타겟에서 실행되는 디버깅 코드를 위한 소프트웨어를 제공해주는 모듈이나 모니터 형식으로 제공됨

RAM에 breakpoint 설정

메모리 상태를 표시하고 수정하기(peek and poke방식을 사용)

현재 프로세서의 레지스터 내용 표시

메모리를 ARM이나 Thumb 명령어로 역 어셈블하기


- CLI나 타겟 플랫폼에 연결되어있는 전용 호스트 디버거를 통해 명령어를 입력

펌웨어가 내부 디버그 회로에 접근할 수 없는 경우에는 RAM이미지만 SW Debug mechanism을 통해 디버깅 됨

- 호스트와 타겟간의 통신은 보통 시리얼이나 네트워크 연결을 통해 이루어짐


2. Abstract the Hardware 

- HAL(Hardware Abstract Layer) : 일련의 정의된 프로그래밍 인터페이스를 제공하여 하드웨어를 숨겨주는 소프트웨어 레이어

- 특정 하드웨어 주변장치와의 통신 역할을 담당하는 HAL Software를 "Device Driver"라 함함

Device Driver는 특정 주변 장치에서 데이터 read/write을 위한 API를 제공공


3. Load a bootable image

- 모든 OS/Applications은 RAM에 복사되어 실행되야하는 것은 아니며 ROM에서 직접 실행될 수 있음

-> 펌웨어 기능은 이미지를 저장하는데 사용될 미디어의 유형에 따라 달라짐

- FFS(Flashrom File System) : ARM 프로세서는 보통 플래시롬을 포함하며, FFS는 여러 실행 이미지를 저장하도록 함

- 로드하는 과정은 이미지 포맷을 고려해야 함

2진 이미지 : 헤더나 디버깅정보를 포함하지 않는 형식의 이미지

ELF(Excutable and Linking Format) : UNIX에서 개발되어 COFF라는 이미지 포맷을 대체하게 됨

-> 재배치 오브젝트 파일, 실행 가능한 오브젝트 파일, 공유오브젝트의 3가지 형식으로 구성

COFF : Common Object File Format의 약자로 ELF이전에 사용하던 포맷

- ELF 파일을 로드하는 과정에서 표준 ELF 헤더 정보를 분석하는 작업이 필요(이미지는 암축, 암호화될 수 있음)

* ELF 헤더 정보 : 실행주소, 유형, 크기 등


4. relinquish control 

- 펌웨어에서 OS/applications에게 플랫폼의 제어권을 넘기는 작업을 수행 (경우에 따라 펌웨어가 제어권을 유지하는 경우도 있음)

- OS가 제어권을 갖지 못한 경우 펌웨어의 일부인 MIL이나 HAL이 활성화되어,

SWI mechanism을 통해 특정 하드웨어 장치를 위한 표준 어플리케이션을 표시

* MIL : Machine Independent Layer


* 일반적으로 사용하되는 2가지의 firmware suite 

ARM Firmware Suite(AFS)

redhat ReadBoot



## 10.1.1. ARM Firmware Suite

- ARM에서 개발한 Firmware Package

- ARM기반의 임베디드 시스템을 위해 설계되어   XScale(Intel), StrongARM 프로세서를 포함한 많은 보드들과 프로세서들을 지원

- 두가지 중요 기술 : μHAL, Angel


μHAL

- 마이크로 HAL

- 서로 다른 통신장치들 사이에서의 동작이 가능하돌 해주는 하웨레벨 디바이스 드라이버를 제공

- 표준 API 제공

- port를 사용하는 경우라면 하드웨어에 영햐을 받는 부분들은 반드시 μHAL API로 구현현

- 표준 함수 프레임워크도 제공하며 상대적으로 포팅작업이 수월


μHAL의 중요한 기능들

 시스템 초기화

 타겟 플랫폼과 프로세서 코어를 셋업

 타겟 하드웨어의 복잡도에 따라 작업의 복잡도에 영향을 미침 

 폴링방식의 시리얼 드라이버  

 호스트와의 기본적인 통신을 위해 사용 

 LED 지원 

 간단한 사용자 피드백을 위한 LED 지원. application에게 동작상태를 표시

 타이머 지원

 추가적인 인터럽트를 설정할 수 있음

 context switching기능을 필요로하는 선점형 OS에서 필수적인 기능 

 인터럽트 컨트롤러 다양한 인터럽트 컨트롤러를 지원 


μHAL의 부트모니터는 CLI를 포함하고 있음


# Angel

- 호스트 디버거와 타겟 플랫폼 사이의 통신을 구현

* 호스트 디버거 상에서의 작업들

- 메모리의 값을 알아내 수정하거나 이미지를 다운로드하여 실행할 수 있음

- 브레이크포인트를 잡거나 프로세서 렐지스터 안의 내용을 표시하는데 사용할 수 있음

=> Angel 디버그 모니터는 SWI 벡터와 IRQ, FIQ벡터에 접근이 가능해야 함

- 프로그램이 호스트 파일 시스템을 열어 데이터 read/write이 가능하도록 API를 제공

* API는 SWI 명령어를 사용

- IRQ/FIQ 인터럽트는 호스트 디버거와의 통신 목적을 위해 사용



## 10.1.2. Red Hat, RedBoot

- redhat에서 개발된 펌웨어 툴

- 오픈소스 라이센스

- ARM, MIPS, SH등 다양한 CPU을 지원

- GDB(GNU Debugger)를 이용한 디버그 기능과 부트로더 기능을 제공

- RedBoot 소프트웨어는 HAL 기반


> RedBoot의 기능

- 통신 : 직렬통신 및 이더넷을 선택적으로 사용할 수 있음

직렬통신 : XModem protocol이 GDB와의 통신을 위해 사용

ethernet : TCP를 GDB와의 통신을 위해 사용


* RedBoot은 bootp, telnet, tftp와 같은 다양한 네트워크 표준 프로토콜을 지원


- 플래시 메모리 관리 장치

: 플래시롬 안에 이미지를 다운로드하거나 업데이트하고 지우는데 사용될 수 있는 파일시스템 루틴을 제공

이미지 압축/해제 기능도 제공


- 완전한 운영체제 지원

: 임베디드 리눅스, 레드햇 eCos, 기타 많은 유명한 운영체제들의 로딩과 부팅을 지원

임베디드 리눅스인 RedBoot은 부팅시 커널로바로 보내게 될 파라미터들을 정의하는 기능도 지원



### 10.2.  Example. SandStone


"SandStone이라는 시스템의 설계 예제"


- 타겟 플랫폼의 환경 설정

- 부팅이미지 로드

- OS에게 제어권 넘기기


- 타겟 : ARM7TDMI코어를 포함하는 ARM Evaluator-7T

- 목표

1. 간단한 플랫폼이 셋업되는 방법을 이해

2. 소프트웨어 페이로드가 메모리로 로드되어 부팅되는 과정을 이해

* payload는 applications 이미지 혹은 OS 이미지


* SandStone은 정적인 설계 과정으로 빌드 과정이 완료된 후에는 재설정이 불가능


- ARM 어셈블러로 완전히 작성되어 있음

- ARM Evaluator-7T에 대한 타겟 하드웨어를 초기화하고 소프트웨어의 일부를 부팅해주는 일련의 작업코드로 되어있음

- 웹에서 다운로드 가능


# SandStone의 기본적인 특징



## 10.2.1. Sandstone 디렉토리 구조

: 소스코드의 위치, 다른 빌드파일의 위치


 [Sand] 

 makefile

 

 

 readme.txt       ; ARM Evaluator-7T를 위한 바이너리 이미지를 빌드하는 방법에 대한 설명

 [buid]

 [src]

 sand.s 

 [obj]               ; 어셈블러에 의해 생성된 오브젝트 파일들

 

 [image]          ; 오브젝트 파일들이 링킹되어 만들어진 최종 이미지 파일들

                       ; 이미지는 Sandstone 코드와 페이로드 이미지를 포함

 

 [log]               ; 

 

 [payload]    ; 페이로드 이미지들 

 slos.bin 

 



## 10.2.2. Sandstone 코드 구조

- Sandstone 코드는 하나의 어셈블리 파일로 구성

- 파일 구조는 여러 단계로 분리할 수 있음. 각 단계는 각 실행과정을 의미함



* 플랫폼에 상관없이 시스템 레지스터 설정이나 메모리 리매핑과 같은 특정 부분은 반드시 펌웨어에 포함되어야 함


* Sandstone의 초기 목표 ? 

펌웨어가 동작중이며 플랫폼의 제어권을 가지고 있는가에 대해 알려줄수있는, 일종의 피드백 기능을 제공하는 타겟 플랫폼 환경 구축


# 10.2.2.1. 1단계 : Reset exception 처리


- 가장 먼저 Reset Exception이 실행

- 실행될 첫 명령어가 Reset 명령어 이므로 default vector table에 "Reset vector"만 있으면 됨

- 코드에서 reset vector 이외의 vector들은 모두 무한루프를 수행하는 더미 핸들러로 분기

(SandStone의 동작 중에는 어떠한 익셉션이나 인터럽트로 발생하지 않는다고 가정)

- Reset vector는 두번째 단계로 이동하기 위해 사용

- sandstone_start의 초기주소는 0x00000000

> 1단게 정리 < 

1. 더미 핸드러가 셋업

2. 하드웨어 초기화를 위한 코드로 제어가 넘어가게 됨


# 10.2.2.2. 2단계 : 하드웨어 초기화


- 하드웨어 초기화의 기본단게는 시스템 레지스터를 셋업하는 것 (시스템 레지스터는 하드웨어를 액세스하기 전 셋업되어있어야 함)


ARM Evaluator-7T의 "세븐 세그먼트 디스플레이 장치"

: 펌웨어의 활성화 여부를 가리키기 위한 피드백 장치로 사용

해당 장치의 셋업 전 시스템 레지스터의 Base Address를 정해진 주소에 위치해야함. (0x03ff0000로 설정)

=> 하드웨어 시스템 레지스터가 ROM/RAM에서 떨어진 위치에 올 수 있도록 하여 주변장치와 메모리를 분리시켜 줌 ????


- 모든 마이크로 컨트롤러 메모리맵 레지스터는 0x03ff0000에서의 오프셋에 위치



* r3 : 디폴트 시스템 레지스터 베이스 주소를 포함. 캐시와 같이 특정 속성과 새로운 디폴트 주소를 설정하는데 사용


- 상위 16-bit는 새로운 시스템 레지스터 베이스 주소 0x03ff를 포함하며, 하위 16-bit는 새로운속성값  0xffa0을 포함

0x03ff0000을 r3 주소로 메모리에 로드

0x03ffffa0을 r4 주소로 메모리에 로드

r4가 가리키는 메모리 주소의 내용을 r3이 가리키는 주소에 저장


- 시스템 베이스 주소를 셋업 후, 세그먼트 디스플레이 장치를 설정할 수 있음

* 세그먼트 디스플레이 하드웨어 : sandstone의 과정을 보여주기 위해 사용


> 2단게 정리 <

1. 0x03ff0000이라는 베이스 주소를 기준으로 시스템 레지스터들이 설정됨

2. 그 과정의 디스플레이를 위해 세그먼트 디스클레이 장치가 설정


# 10.2.2.3. 3단계 : 메모리 리맵핑


- SRAM을 초기화, 메모리 재배치를 수행


*플랫폼은 초기메모리 상태에서 시작


- 플랫폼에 전원공급 시, 플래시롬만 메모리맵에 할당.

2개의 SRAM bank 0,1은  초기화되지 않아 사용이 불가능 함



- 리매핑이 일어나기 전, sandstone_init2 루틴의 절대 주소를 계산

=> 새로운 리맵환경에서 다음 루틴으로 분기하기위해 사용


LDR    r14,    =sandstone_init2

LDR    r4,    =0x01800000


- 메모리 리매핑의 수행. 새로운 메모리맵 데이터는 memorymaptable_str이 가리키는 구조체를 r1에서 r12쪽으로 로드

- 레지스터를 이용하여 이 구조체는 시스템 컨트롤 레지스터부터의 메모리 컨트롤러 오프셋 0x3010에 쓰여짐


- 이 작업이 완료되면 새로운 메모리맵이 활성화 됨

- SRAM 뱅크가 현재 활성화 되어있음

- 플래시롬은 상위주소로 설정되어 있음


- 펌웨어의 다음 단계로 분기. ARM 파이프라인을 이용하여 구현

=> 새로운 메모리 환경이 활성화 되었더라도 다음 명령어는 이미 파이프라인안에 로드되어 있음.

=> r14의 내용(sandstone_init2의 주소)을 pc에 복사하여 다음 루틴을 호출할 수 있음

=> "MOV" 명령어로 구현


> 3단계 정리 <

1. 메모리 재배치 수행

2. pc는 다음 단계를 가리킴. 이 주소는 새로 리맵된 플래시롬에 위치


# 10.2.2.4. 4단계 : 통신 하드웨어 초기화

- 통신 초기화는 시리얼 포트를 설정하고 표준 배너를 출력하는 작업을 포함

- 배너 : 펌웨어가 완전히 기능적이고 메모리가 성공적으로 리매핑 되어있다는 것을 보여주기 위해 사용


- 시리얼포트 : 9600bps

- 패리티비트 없음

- 정지비트 하나

- 흐름제어 없음

* 시리얼 케이블이 보드에 연결되어 있다면, 호스트 터미널 역시 이러한 설정값으로 설정이 되어야 함


> 결과

- 위의 설정대로 시리얼 포트가 초기화 됨

- 시리얼 포트를 통해 보내진 Sandstone 배너


# 10.2.2.5. 5단계 : 부트로더 - 페이로드 복사 및 제어권 양도

- 페이로드를 복사하여 pc의 제어권을 복사된 페이로드로 넘김

- 블록 복사에 사용될 레지스터 r12, r13, r14 셋업

 * 부트로더 코드는 페이로드가 암호화나 압축이 불필요한 간단한 2진 이미지라고 가정


> 아래의 레지스터를 사용하여 페이로드가 SRAM으로 복사

- r13 : SRAM의 시작 주소. 0x00000000

- r12 : 페이로드 시작 

- r14 : 페이로드 끝


- pc가 복사된 페이로드의 엔트리 주소를 가리키게 하여 pc의 제어권을 페이로드에게 넘김

- 특정 페이로드에 대한 엔트리 포인트의 주소. 0x00000000

=>  페이로드는 시스템을 제어할 수 있는 상태가 됨


> 5단계 정리 <

1. 페이로드가 SRAM에 복사. 0x00000000

2. pc의 제어권이 페이로드로 넘어감. pc = 0x00000000

3. 시스템이 완전히 부팅되면 시리얼 포트를 통해 메시지 출력







'System > Embedded' 카테고리의 다른 글

[ARM] 캐시 2  (0) 2015.11.12
[ARM] 캐시  (0) 2015.11.12
[ARM] 익셉션과 인터럽트 처리 2  (0) 2015.11.10
[ARM] 익셉션과 인터럽트 처리  (0) 2015.11.10
[ARM] 최적화된 C프로그래밍  (0) 2015.11.10

+ Recent posts