본문 바로가기

Linux

u-boot

U-boot

U-boot Universal Boot Loader 약자로서 리눅스를 탑재하는 임베디드 시스템에서 가장 많이 사용되는 부트로더다다양한 시스템에서 사용 가능하고시리얼네트웍, USB, 플래시를 지원하는 등의 많은 기능을 가지고 있다. U-boot 역시 오픈 소스로서 아래 사이트에서 소스코드를 다운로드 할수 있다.

 

http://www.denx.de/wiki/UBoot

 

현재의 최신 버전은 1.3.0 버전이고안정 버전은 1.2.0 이다여기서는 1.2.0 버전을 기준으로 설명하기로 하겠다물론 어떤 버전을 사용해도 대동소이하다.

U-Boot 부트로더는 보통 NOR나 NAND 플래시의 가장 앞부분 즉어드레스 0번지에 저장이 된다. ARM CPU에서 리셋이 걸리면 PC값이0번지로 초기화되는데 이는 메모리맵에서

어드레스 0번지가 시작된다는 의미이다그러나 NOR 플래시와는 다르게 NAND플래시의 경우에는 읽기 동작시 블록단위로 동작을 하기 때문에 순차적인 실행 즉부팅 동작을 할 수 없다.

 

따라서 최신 CPU들은 이러한 NAND플래시 부팅을 지원하기 위해 별도의 기능들을 추가했다. 2410 CPU의 경우 리셋이 걸리면 DMA제어에 의해 4KB만큼 내부 SRAM으로 복사되고 SRAM의 시작 주소를 0번지로 할당하여 부팅동작을 하게한다하지만 U-Boot의 크기는 보통160KB 정도 되는데 4KB를 훨씬 넘는 크기이다이러한 문제를 해결하기 위해 부트코드의 4KB 이내 코드의 동작은 아주 중요한 기본동작만 하고나머지는 시스템의 주메모리 즉, SDRAM에서 동작하게 PC(Program Count)의 위치를 SDRAM 메모리 영역으로 넘겨준다.

 

이렇게 하기 위해서 우선부트코드는 두 가지 방식으로 분리된다.

 

1.     시스템의 기본동작을 위한 초기화를 하고, NAND 플래시에 저장된 U-Boot의 전체 이미지를 SDRAM으로 복사한다이 동작은 간단하게 어셈블러 언어의 리터럴 풀(상수값 지정동작방식으로 메모리 접근이 가능하다.

 

2.     주메모리로 복사된 후 PC SDRAM으로 넘겨줄 때는 주로 복잡한 부팅기능을 지원하기 위해 프로그램으로 작성되어 실행이 되는데 이때는 자동변수를 위한 스택과 전역변수 그리고 다양한 라이브러리들이 링크될 수 있는 선형적인 메모리 접근이 용이하도록 절대주소방식을 사용한다.

 

따라서 메모리 용량이 작은 SRAM에서의 초기 부팅처리는 어셈블러로 코딩이 이루어져 있고 그 뒤 SDRAM으로 복사된 후의 복잡한 처리는C프로그램으로 작성되어 있다.

 

어셈블러로 작성된 start.S의 코드는 CPU의 동작을 위해 비교적 간단하면서도 중요한 초기화 과정을 처리하고 있다먼저, CPU동작 모드를 유저모드에서 수퍼바이저(SVC32)모드로 전환하고 동작에 영향을 미칠 수 있는 인터럽트와 기타 하드웨어 기능을 중지하고 시스템 클럭을 설정한다또한 메모리 컨트롤러를 설정하고 NAND 플래시에 존재하는 부트코드를 SDRAM의 부트영역으로 복사하고 PC를 넘겨준다. C 프로그램의 실행을 위해 필요한 스택에 대한 설정이 이루어지고 나면 C로 구현된 부트로더의 시작함수를 호출한다.