ARM Core - 5. ARM 기반의 OS와 임베디드 시스템 개발 (1. ARM에서 리눅스 커널 실행)

2025. 3. 7. 13:42정보기술/하드웨어

1. ARM에서 리눅스 커널 실행

ARM 아키텍처는 임베디드 시스템, 모바일, 서버 등 다양한 환경에서 리눅스 커널을 실행하는 데 널리 활용된다.
특히 Device Tree를 통해 하드웨어 구성을 동적으로 설정하며, 안드로이드에서는 JIT/AOT 컴파일을 활용하여 성능을 최적화한다.


1. Device Tree 구조 분석

1) Device Tree란?

ARM 기반 시스템은 x86과 달리 하드웨어 구성이 정형화되어 있지 않기 때문에,
커널이 실행될 때 하드웨어 정보를 직접 인식하지 못한다.
이를 해결하기 위해 **Device Tree(DT, 기기 트리)**가 도입되었으며,
하드웨어 구성을 별도의 데이터 구조로 저장하고 커널이 이를 참고하여 초기화하는 방식이다.


2) Device Tree의 필요성

  • 기존 방식: 커널 내에서 보드별 하드웨어 정보를 소스 코드에 직접 하드코딩
  • 문제점: 새로운 보드를 추가할 때마다 커널 소스를 수정해야 하는 비효율성
  • 해결 방법: Device Tree 사용 → 커널과 하드웨어 정보를 분리하여 유연한 시스템 구성이 가능

3) Device Tree 기본 구조

Device Tree는 트리(Tree) 형태의 데이터 구조를 가지며,
각 노드는 특정 하드웨어 구성 요소를 나타낸다.

Device Tree 예제 (example.dts)

/dts-v1/;
/ {
    compatible = "example,board";
    model = "Example ARM Board";

    memory {
        device_type = "memory";
        reg = <0x80000000 0x10000000>;  // 시작 주소: 0x80000000, 크기: 256MiB
    };

    cpus {
        #address-cells = <1>;
        #size-cells = <0>;

        cpu@0 {
            device_type = "cpu";
            compatible = "arm,cortex-a53";
            reg = <0>;
        };
    };

    soc {
        compatible = "simple-bus";

        uart@10000000 {
            compatible = "ns16550";
            reg = <0x10000000 0x1000>;
            clock-frequency = <24000000>;
        };
    };
};

4) Device Tree 파일 확장자

  • .dts (Device Tree Source) → 사람이 읽을 수 있는 소스 파일
  • .dtb (Device Tree Blob) → .dts 파일을 컴파일한 바이너리 형태로, 커널이 이를 직접 로드

5) Device Tree 컴파일 및 실행

1️⃣ Device Tree 소스를 바이너리(.dtb)로 변환

dtc -I dts -O dtb -o example.dtb example.dts
  • -I dts → 입력 파일 형식 (DTS)
  • -O dtb → 출력 파일 형식 (DTB)
  • -o example.dtb → 변환된 출력 파일

2️⃣ U-Boot에서 Device Tree 적용

setenv fdtfile example.dtb
bootm 0x80000000 - 0x81000000
  • setenv fdtfile → 사용할 Device Tree 설정
  • bootm → 커널과 함께 Device Tree 로드하여 부팅

2. 안드로이드 시스템의 ARM 활용 (JIT/AOT 컴파일 및 PGC 최적화)

안드로이드는 ARM 아키텍처에서 실행될 때 JIT(Just-In-Time), AOT(Ahead-Of-Time) 컴파일 및 최신 Profile-Guided Compilation(PGC)를 활용하여 성능을 최적화한다.


1) JIT (Just-In-Time) 컴파일

  • 앱 실행 시점에 바이트코드를 기계어로 변환하여 실행하는 방식
  • 실행 중 성능 최적화 가능 (실시간 코드 최적화)
  • 하지만 앱이 처음 실행될 때 속도가 느림 (초기 변환 필요)

JIT 컴파일의 장점

장점 설명
즉시 실행 가능 APK 설치 후 바로 실행 가능
CPU 아키텍처 최적화 가능 실행 중인 ARM CPU에 맞춰 최적화
적응형 최적화 실행 중 성능을 분석하고 최적화 가능

2) AOT (Ahead-Of-Time) 컴파일

  • 앱 설치 시점에 바이트코드를 기계어로 변환하여 저장
  • 안드로이드의 ART(Android Runtime)에서 사용됨
  • ARM64 아키텍처에서 실행 속도를 더욱 최적화

AOT 컴파일의 장점

장점  설명
빠른 실행 속도 실행 시점에서 추가적인 변환 없이 실행 가능
배터리 절약 CPU 부하 감소로 전력 소비 절감
캐싱 가능 미리 컴파일된 코드가 저장되어 실행 속도 향상

3) 안드로이드 12+의 Profile-Guided Compilation (PGC)

Android 12 이상에서는 JIT/AOT의 장점을 결합한 프로파일 가이드 컴파일(Profile-Guided Compilation, PGC)이 추가되었다.

  • 실행 중 JIT으로 성능을 분석한 후, 자주 실행되는 코드 패턴을 수집하여 AOT로 최적화
  • AOT처럼 빠른 실행 속도를 유지하면서도, JIT처럼 적응형 최적화 가능

PGC의 장점

장점  설명
JIT의 유연성과 AOT의 속도를 결합 실행 패턴을 기반으로 최적의 코드 생성
배터리 효율 향상 불필요한 JIT 컴파일 감소
성능 최적화 CPU 리소스 사용을 줄이고 자주 실행되는 코드만 AOT 적용

4) JIT/AOT/PGC 설정 확인

안드로이드에서 현재 실행 중인 앱이 JIT, AOT, 또는 PGC로 실행되는지 확인할 수 있다.

ADB 명령어를 이용한 확인

adb shell getprop dalvik.vm.usejit

출력 값:

  • true → JIT 컴파일 활성화
  • false → JIT 비활성화 (AOT 또는 PGC 사용 가능)

Profile-Guided Compilation (PGC) 상태 확인

adb shell dumpsys package com.example.app | grep -i "compilation"

출력 예제:

compilationReason=profile-guide
  • profile-guide → PGC 적용됨
  • speed-profile → AOT 최적화됨

3. ARM 기반 리눅스 및 안드로이드 실행 최적화 요약

기능 설명
Device Tree ARM 시스템의 하드웨어 정보를 커널에 전달하는 방식
JIT 컴파일 실행 시점에서 코드 변환 (적응형 최적화)
AOT 컴파일 설치 시점에서 미리 코드 변환 (빠른 실행)
Profile-Guided Compilation (PGC) 실행 패턴을 분석하여 AOT로 최적화
NDK 최적화 네이티브 코드 실행을 통해 ARM 성능 최적화

4. 결론

  • Device Tree는 ARM 기반 리눅스에서 하드웨어 구성을 동적으로 설정할 수 있도록 한다.
  • 안드로이드에서는 JIT/AOT 및 최신 PGC를 활용하여 ARM CPU에서 성능을 최적화한다.
  • Profile-Guided Compilation(PGC)은 Android 12+에서 JIT과 AOT를 결합한 최적화 방식으로 도입되었다.
  • NDK를 활용하면 ARM CPU에서 네이티브 코드를 실행하여 성능을 더욱 개선할 수 있다.
  • 임베디드 리눅스 및 안드로이드 시스템 개발에서 ARM 최적화 기법을 활용하면 성능과 전력 효율을 향상시킬 수 있다.