Bootloader and u-boot
이전 시간에는 임베디드 디바이스의 부팅타입에 대해 간단히 살펴보았습니다. 이번 시간에는 실제 부팅과정과 해당 기능을 담당하는 부트로더, 그리고 리눅스/안드로이드 플랫폼에서 사용되는 부트로더인 u-boot에 대해 살펴보기로 하겠습니다.
우선 용어 정리부터 하죠.
다 같은 말입니다. 시스템이 맨처음 켜지는 동작을 책임지는 소프트웨어라고 보면 됩니다. 펌웨어(Firmware)라는 말을 들어본적이 있을텐데, 부트로더가 100% 펌웨어라고 보면 됩니다. 원래 펌웨어는 업데이트가 가능하지 않은 작은 소프트웨어를 가리키는 말이었는데, 요즘은 그냥 업그레이드 가부 여부에 상관없이 펌웨어란 말을 그냥 막 쓰더군요. 임베디드 디바이스에 들어가는 소프트웨어를 통칭해서 펌웨어라고 지칭하기도 합니다.
어찌되었든 부트, 부트스트램, 부트코드는 시스템에 전원이 들어오면 가장 먼저 수행되는 소프트웨어 코드입니다. 시스템의 초기화를 담당하죠.
스마트폰으로 게임을 실행하면 로딩중이라고 뜨지 않습니까? 소프트웨어를 로딩, 그러니까 말그대로 불러들여서 실행시키고 있다는 건데요. 다른 소프트웨어를 읽어서 실행시키는 소프트웨어 모듈을 통상 로더라고 합니다.
자, 그럼 부트로더는 부트와 로더가 합쳐졌으니 시스템의 부팅을 담당하고, 시스템의 기본 부팅이 끝나면 다른 소프트웨어(통상적으로 메인 소프트웨어라고 하죠)를 실행시키는 소프트웨어라고 쉽게 이해할수 있겠죠. 부트로더도 한 분야의 소프트웨어인만큼 그 종류와 기능은 엄청나게 다양합니다. 운영체제(OS)가 들어가는 부트로더부터 OS없이 순차적(sequential)으로 실행되는 가벼운 부트로더, 각 칩셋(SoC) 벤더에서 제공하는 부트로더, 또는 각 운영체제별로 사용되는 부트로더 등등 매우 많습니다. 결론은 현업에 맞는 부트로더만 알면 됩니다.
리눅스나 안드로이드를 운영체제로 사용하는 거의 모든 임베디드 디바이스의 부트로더는 u-boot라고 보면 됩니다. 간혹 예외도 있는데 이마저도 u-boot를 차용하여 변형시킨 부트로더들이 대부분입니다. 일부 보안(Security)에 관련된 요구사양을 위해 특수한 부트로더를 개발하는 경우도 있습니다.
u-boot가 널리 사용되는 한가지 이유는 작지만 강력한 툴(Tool)을 제공해주기 때문입니다. 그 덕분에 u-boot는 대다수의 플랫폼에 포팅이 되어 요즘 나오는 대부분 임베디드 기기에서 사용가능합니다. u-boot가 제공해주는 툴은 CLI(Coomand Line Interface)로 시리얼 연결 콘솔(Ch.4-4를 참조)상에서 여러가지 명령어를 사용할 수 있습니다. 디스크나 플래쉬를 읽고 쓸수 있고, USB나 이더넷 네트워크 통신(DHCP, TFTP 등)도 가능합니다. 그래서 임베디드 소프트웨어 개발을 하는데 아주 유용합니다.
실제 코드나 코드가 실행되는 순서는 u-boot 버전이나 플랫폼 별로 다를수 있겠습니다만, 기본적으로 하는 일은 같습니다. 맨처음 실행되는 u-boot 코드는 최소한의 기본적인 시스템 초기화를 한 다음, 나머지 코드의 실행을 위해 메모리(DRAM)을 초기화합니다.
그 다음 메모리로 코드를 적재하고(relocate_code), 후반부의 시스템 초기화작업(board_init_r)을 마무리합니다.
main_loop에서는 환경변수(enviroment variable이라고 하지요)에 따라 메인 소프트웨어(리눅스 커널과 같은)를 실행할 것인지, 아니면 사용자 입력을 받아들여(CLI) 특정기능을 수행할 것인지를 결정합니다.
환경변수(u-boot environment)는 통상 디스크나 플래쉬의 특정 partition에 저장하여 사용합니다.