U-Boot & 부트로더의 이해

부트로더는 시스템을 초기화하고 운영체제를 탑재하거나 실행하기 위해 시스템 초기화코드, 하드웨어 제어 프로그램, 네트워크, USB등의 프로토콜과 일부 파일 시스템을 관리한다.(BIOS와 비슷하다)



1.1 부트로더의 역할


(1) Target 초기화

전원이 입력되면 하드웨어와 소프트웨어 환경을 설정한다.

불필요한 하드웨어의 동작 중지, 시스템 클록 설정, 메모리 제어기 설정, MMU/MPU 설정 등

하드웨어 설정이 완료된 후 실제 프로그램 동작에 필요한 재 배치와 스택 영역 설정 및 C에서 사용하는 변수 영역을 설정하고 C로 작성된 함수를 호출 한다.


(2) Target 동작 환경 설정

BIOS CMOS 설정과 유사하다.(부트 방법, 네트워크 설정, IP 주소 설정 등)


(3) 시스템 운영체제 부팅

임베디드 시스템의 운영체제는 플래시 메모리에 탑재되어 있으므로 부팅시 주메모리에 탑재한 후 실행됨.

부트로더는 플래시 메모리에 있는 OS DRAM에 복사하고 제어권을 OS의 시작점으로 넘겨주는 기능을 함.


(4) 플래시 메모리 관리

보통 플래시 메모리에는 OS이미지와 부트로더가 탑재된다.


(5) 모니터 기능

시스템의 동작 상태 감시, 하드웨어 정상 동작 여부 검사, 메모리 검사와 POST(Power-On Self Test) 등의 기능


1.2 부트로더의 특징

부트로더는 하드웨어 의존성이 강하다.

부트로더를 작성하려면 프로세서의 구조와 특징 및 사용법을 알아야 한다.

부트로더의 시작 부분은 어셈블리어로 작성되기 때문에 명령어 사용법을 알고 있어야 한다.

플래시 메모리의 부트 섹터에 저장되어 유지되므로 크기가 작아야 한다.

좋은 오픈소스가 많으니 오픈 소스 부트로더를 사용하자.


1.3 부트로더의 종류

LILO, GRUB, Loadlin, EtherBoot, Blob, PMON, RedBoot, U-Boot

 

U-Boot 빌드와 설치

U-Boot는 다양한 기능을 가지는 부트로더로 하드웨어 초기화, 하드웨어 검사, 소프트웨어 다운로드 및 실행, 플래시 메모리 관리, 운영체제 부팅등의 기능을 제공한다.

U-Boot는 리눅스와 유사한 구조를 가지고 있으며, 일부는 리눅스 소스를 사용했다.


2.1 U-Boot 소스 설치

ftp://ftp.denx.de/pub/u-boot

소스를 받아 개발하고자 하는 보드에 맞게 포팅해야 한다.


2.2 U-Boot 소스 구성

u-boot top : U-Boot의 최상위 디렉토리. Makefile, board.cfg 등의 주요 파일을 가지고 있으며, 모든 U-Boot의 빌드 동작을 실행하는 디렉터리

arch : arm, mips, powerpc 등 프로세서 아키텍처별로 서로 다른 디렉터리를 구성하고 있다. 각 아키텍처에 따른 소스를 구성하는 디렉토리.

board : 각 제조사별 보드 관련 소스를 구현하는 디렉토리

common : U-Boot에서 공통적으로 사용되는 소스를 구현하는 디렉토리.

disk : DISK를 관리하기 위한 소스

doc : U-Boot 관련 문서를 가지고 있는 디렉토리

drivers: U-Boot에서 지원되는 다양한 장치들에 대한 드라이버를 구현한 디렉토리

examples : U-Boot에서 독립적으로 프로그램을 실행시키는 샘플코드를 포함한 디렉토리

fs : U-Boot에서 지원하는 다양한 파일시스템에 대한 소스를 구현한 디렉토리

include : U-Boot에서 사용되는 헤더 파일을 정리한 디렉토리. 특히 configs 디렉토리는 보드별 동작에 필요한 설정 헤더 파일을 가지고 있음

lib : U-Boot에서 사용되는 각종 라이브러리를 구현한 디렉토리

net : U-Boot에서 지원되는 UDP, IP, TFTP 등 네트워크 프로토콜을 구현한 디렉토리

post : POST를 구현한 디렉토리

tools: U-Boot 사용에 필요한 각종 호스트 유틸리티를 구현하는 디렉토리

 

2.3 U-boot 포팅에 필요한 디렉토리 및 소스 구성

u-boot top/Makefile : 빌드용 Makefile

/board.cfg : 지원되는 보드에 대한 각 옵션. 타겟 이름, 이키텍쳐, CPU, 보드이름, 벤더, SoC

arch/arm/config.mk : ARM 아키텍처에 대한 크로스 컴파일러 및 빌드 옵션을 지정함.

/cpu :  ARM 프로세서 디렉토리를 구현함

/include : ARM 프로세서 및 타겟 SoC 관련 헤더를 정의함

/lib : ARM 프로세서에서 일반적으로 사용되는 기능을 라이브러리로 구현함

board/samsung/dtk4412 : DTK4412 타겟 보드용 소스가 구현됨. 프로그램이 탑재되는 메모리의 위치 및 메모리의 배치를 지정하는 파일을 가지고 있음.

board/ti/beagle : beagle 보드에 대한 파일을 구현

drivers/block : 블록 디바이스 드라이버를 구현함

/mmc : mmc 드라이버를 구현

/mtd : NAND, OneNAND 등 메모리 장치를 블록 디바이스로 사용하기 위한 MTD 드라이버를 구현함.

/net : 각종 네트워크 장치 드라이버를 구현

/serial : 시리얼 디바이스 드라이버가 구현되어 있는 디렉토리.

/usb : usb 장치 드라이버를 구현

/..... : 기타 장치 드라이버가 있음

include/configs/dtk4412.h : configs/dtk4412.h 파일은 대상 보드가 동작하기 위한 각종 하드웨어 및 소프트웨어 설정값을 가짐. U-Boot를 포팅하는데 있어 매우 중요한 정보를 가짐.


U-Boot 포팅

3.1 U-Boot 포팅에 필요한 소스 및 타겟

u-boot top/boards.cfg, arch/arm/cpu, arch/arm/include, board/samsung/dtk4412, driver/mmc, driver/net, driver/serial, driver/usb, include/configs/dtk4412.h


3.2 U-Boot 초기화 동작의 이해

U-Boot는 시스템 리셋 키가 입력되거나 전원이 인가되면 실행되는 부트 코드 이다.

일반적으로 부트코드가 NOR 플래시에 저장되어 사용되는 경우 바로 플래시에서 동작하게 구현할 수 있다.

하지만, 대부분의 시스템은 NAND플래시나 SD/MMC와 같은 장치에 저장되어 있다. 이런 경우,대부분 저장장치의 부트코드를 실행 가능한 주 메모리(DRAM)으로 복사한 후 실행한다.

주메모리 초기화는 초기 설정이 필요없는 칩 내부의 SRAM에서 담당한다. 하지만 SRAM에 비해 U-Boot 코드가 상당히 크기 때문에 모든 코드를 SRAM으로 복사해서 사용할 수 없다. 따라서 클록이나 메모리 장치 초기화를 담당하는 코드와 메인 부트로더 코드를 복사하는 코드를 SRAM에 복사하여 사용한다. 이후 나머지 부트로더 코드를 복사하여 사용한다. 이에따라 BL1과 주U-Boot 코드로 나뉜다.


U-Boot 사용하여 시스템이 부팅되는 과정

전원인가 또는 리셋신호 구동 후 내부 ROM 코드 BL0 실행

BL0에서는 외부 핀 OM(Operating Mode)에 따라 부트 디바이스 선택

선택된 부트 디바이스의 초기 부트코드(BL1)을 내부 SRAM에 복사

SRAM BL1에서 U-Boot 부트 코드를 DRAM에 복사

제어권을 복사된 DRAM U-Boot 영역으로 변경, 변경 후에는 U-Boot 코드 실행


Exynos4412 U-Boot 소스는 어셈블리 파일 arch/arm/cpu/armv7/start.S로부터 시작된다. 이 파일의 앞부분에는 ARM 프로세서의 예외 처리 벡터가 있고 처음 시작은 reset 핸들러로 분기하여 실행된다. reset 핸들러는 SVC32 모드로 전환하고, 캐시 및 MMU의 사용을 중지한 다음에 보드 초기화를 실행한다.

 

 




원문 : ARM으로 배우는 임베디드 리눅스 시스템

+ Recent posts