안녕하세요 Fast Booting 블로그 게시물 시리즈의 세 번째 파트입니다. 첫 번째 게시물에서는 1.56 초 만에 클러스터 데모 부팅을 보여 주었으며 두 번째 게시물에서는 Qt 애플리케이션의 최적화 방법을 안내했습니다. 이번 파트에서는 데모에서 사용 된 NXP i.MX6 SABRE 개발 보드의 부트 로더 및 커널 최적화에 중점을 둘 것입니다.

Fast Booting 최적화를 시작하기 전에 무작위로 시간을 측정한 최적화 되지 않은 부팅 시간은 22.8 초였습니다. 측정 후 2 초 이내에 부팅 시간을 얻으려는 목표를 세웠습니다. 이제 목표가 설정되었고 우선 가장 확실한 곳부터 최적화를 시작했습니다 : root-fs. 기존의 root-fs 에는 시동 데모에 필요하지 않은 많은 내용이 포함되어 있었습니다. 나는 전체 root-fs 를 500MB에서 24MB로 줄였습니다. buildroot를 사용하여 장치 및 크로스 컴파일 툴 체인(Tool Chain)에 최소한의 root-fs를 만들었습니다.

루트 fs 를 줄인 후에 부팅시간은  15.6 초 로 단축됐습니다. 이 15.6 초 에서 커널의 시작 부분이 약 6 초가 걸리고 U-Boot 부트 로더와 수정되지 않은 응용 프로그램이 나머지 부분을 차지했습니다. 다음으로 커널에 집중했습니다. 애플리케이션에서 요구하는 기능을 이미 알고 있었기 때문에, 거의 필요없는 모든 것을 제거하여 5.5 MB에서 1.6 MB로 커널을 쉽게 제거 할 수있었습니다. 이 후 부팅 시간을 9.26 초로 만들었습니다. 커널 시작은 1.9 초입니다.

이 시점에서도 우리는 여전히 u-boot를 전혀 건드리지 않았습니다. 즉, 기본 1 초 대기 시간과 커널의 무결성 검사가 제대로 수행되었음을 의미합니다. 그래서 U-Boot가 다음 목표였습니다. U-Boot 내부에는 다른 U-Boot 또는 특별히 구성된 커널을 부팅 할 수있는 보조 프로그램 로더(secondary program loader)라는 특별 프레임 워크가 있습니다. SPL 모드를 활성화하고 명령 줄 인수를 포함하도록 커널을 수정하고 장치 트리를 커널에 추가했습니다. 또한 장치 트리를 47KB에서 14KB로 줄이고 콘솔을 비활성화했습니다. 부팅 시간은 커널이 0.61 초 로 단축 됐고 나머지 U-Boot + 응용 프로그램 은 3.42 초로 떨어졌습니다.

이제 기본 시스템 (u-boot 및 커널)이 적절한 시간으로 부팅되었으므로 클러스터 응용 프로그램을 최적화했습니다. 응용 프로그램의 시작은 클러스터 프레임을 먼저 로드 한 다음 게이지에서 애니메이션을 적용하고 이전 게시물에서 설명한대로 3D 자동차 모델을 마지막으로 변경했습니다. 부팅 시간은 여전히 2 초 타겟에서 상당히 멀었으므로 시스템에서 더 자세한 분석을했습니다. 클래스 10 SD 카드로 바꾸기 전에는 클래스 4 SD 카드를 사용하고 있었습니다.

내 Qt 라이브러리는 여전히 동적(Daynamic) 라이브러리 였으므로 Qt를 정적(Static) 라이브러리로 컴파일하고 정적 버전의 Qt를 사용하여 클러스터 데모를 다시 컴파일했습니다. 또한 root-fs 에서 동적 라이브러리를 제거 할 수 있었습니다. 정적 링크를 사용하면 운영 체제가 동적 라이브러리의 Symbol 을 해석 할 필요가 없으므로 응용 프로그램을 보다 빠르게 시작할 수 있습니다. 정적 링크를 사용하면서 클러스터 응용 프로그램을 19 MB 크기의 하나의 바이너리로 만들 수 있었습니다. 여기에는 데모에서 요구하는 모든 assets(3D 모델, 이미지, 글꼴) 및 모든 Qt 라이브러리가 포함됩니다. 실제로 Qt 빌드에 적절한 최적화 플래그를 사용 외에 크기 최적화를 설정하고 fpic을 제거하여 실행 파일 크기를 15MB로 줄였습니다. 나는 또한 eMMC에서 root-fs를 사용하는 것이 SD 카드를 사용하는 것보다 빠르다는 것을 알게되었습니다.

 

그러나 SD 카드에 u- 부팅 및 커널 이미지를 사용하는 것이 eMMC에서보다 더 빠르기 때문에 CPU가 SD 카드에서 u-boot 및 커널을 로드하고 커널이 eMMC에서 root-fs를 사용하는 약간 이상한 조합으로 끝났습니다 . 커널은 여전히 gzip으로 압축되었습니다. UPX, LZO 및 LZ4를 테스트 한 후 패킹 알고리즘을 내 하드웨어에서 가장 빠른 LZO로 변경했습니다. 하드웨어에 따라 다른 알고리즘을 테스트하거나 패킹이 전혀 없을 수도 있습니다. 패킹 알고리즘을 변경하고 시리얼 콘솔을 제거한 후 커널 이미지 크기는 1.3 MB로 떨어졌습니다. 이러한 변경으로 부팅 시간이 1.94 초로 단축되었습니다.

이것이 프로덕션 소프트웨어라면 메모리 구성 영역에서 아직 수행해야 할 작업이 있습니다. 전원을 켜고 SD 카드가 아닌 eMMC에서 커널 이미지를로드하는 데 시간이 더 걸리는 이유를 이해하려면 U-boot를 디버깅해야합니다. 일반적으로 빠른 시작 시간이 핵심 요구 사항이라면 하드웨어를 그에 맞게 설계해야합니다. CPU가 직접 액세스하는 u-boot 및 커널을 포함하는 작은 초고속 플래시를 사용할 수 있으며 eMMC와 같이 root-fs를 약간 느리게 사용할 수 있습니다.

 

어렵게 2초 이내 부팅에 성공한 이후에도 나는 더 빠르게 할 수 있는지 궁금했습니다. 첨부 된 장치 트리가있는 1.2 MB 커널까지 네트워크 스택을 제거하여 커널을 조금 더 줄였습니다. 또한 Vivante 드라이버가 모듈로 제공되기 때문에 사전에 루트 링크를 실행 했으므로 정적 root-fs를 만들 수 없었습니다. 나는 또한 u-boot spl 부분을 약간 줄무늬로 만들었는데, 처음에는 31KB 였고 원하지 않는 부분을 제거한 후에는 23KB 부트 로더 가 만들어졌습니다. 이 마지막 변경 사항으로 시스템을 1.56 초 만에 부팅 할 수있었습니다.

아래 이미지는 작업 방법에 따른 부팅 시간 단축 결과입니다.

boot-time

 

마지막으로 부팅 시간에 영향을주는 것은 하드웨어의 선택입니다. 정확히 동일한 CPU를 사용하는 경우에도 보드간에 차이가 있습니다. 아마도 나중에 이것에 대한 자세한 내용이 있을 것입니다.

 

Do(해야 할 것):

> 측정 시간 및 소요 시간 분석
> 목표를 가능한 한 빨리 설정하십시오.
> 개발 초기에 목표를 달성하고 개발 단계에서 목표 수준을 유지하십시오.
> 소프트웨어 아키텍처를 설계 할 때 시작 타겟을 고려하십시오.
> 쉬운 부분을 먼저 최적화 한 다음 세부 사항을 계속 진행하십시오.
> SW & HW 구성에서 더 나은 결과를 제공하는 경우 정적 링크를 활용하십시오.
> 하드웨어 제한을 고려하여 Fast Booting 시간을 허용하도록 하드웨어를 설계하는 것이 바람직합니다.

 

하지 말아야 할것(Do not):

> 선택한 하드웨어의 성능을 과대 평가하십시오. i.MX28은 iPad와 같은 성능을 제공하지 않습니다.
> 소프트웨어 아키텍처를 복잡하게 만듭니다. 보다 단순한 아키텍처가 더 빠르게 실행됩니다.
> 필요하지 않은 것을 로드하십시오. 미리 만들어진 이미지에는 많은 Use Case 의 기능이 포함되어 있으므로 일반적으로 최적화가 필요합니다.
> 프로젝트 종료시에 최적화를 시작하십시오.
> 마지막 밀리 초(milliseconds)를 최적화하는 데 필요한 노력을 과소 평가하십시오.

 

필자는 3 개의게시물에서 Qt가 실제로 어떻게 과제를 수행하고 있는 지를 보여주었습니다. 업계 표준을 충족시키기면서 Qt 기반의 장치를 매우 빠르게 부팅 할 수 있었습니다. 이는 여러가지 기술을 조합한 결과 입니다: 훌륭한 아키텍처 SW 디자인, Qt 의 빠른 팁, 하드웨어 및 여러 시스템 이미지의 최적화 .

 

본 문서는 qt.io 의 “Fast-Booting Qt Devices, Part 3: Optimizing System Image” 을 번역한 블로그 입니다.