06-29 06:14
Recent Posts
Recent Comments
관리 메뉴

너와나의 관심사

ARM FVP 환경 동작 안정화를 위한 에러 분석 및 개발 계획 본문

카테고리 없음

ARM FVP 환경 동작 안정화를 위한 에러 분석 및 개발 계획

벤치마킹 2026. 5. 10. 21:26

FVP 환경 동작 안정화를 위한 에러 분석 및 개발 계획

1. 개요

ARM FVP 환경에서 AOSP 또는 Android 기반 코드를 실행할 때는 일반적인 실제 디바이스나 Cuttlefish 환경보다 에러가 많이 발생할 수 있다.

그 이유는 FVP가 실제 양산 단말이 아니라 가상 하드웨어 모델 기반의 플랫폼이기 때문이다.
즉, CPU, 메모리, 인터럽트, SMMU, GPU, 디바이스 트리, 부트로더, 커널, HAL, APEX, Android Framework가 모두 실제 제품 환경과 다르게 동작할 수 있다.

따라서 FVP bring-up 작업은 단순히 코드를 빌드하고 실행하는 수준이 아니라, 다음 항목들을 함께 맞추는 작업이다.

  • 하드웨어 모델 설정
  • Device Tree / 커널 설정
  • Android init / SELinux 설정
  • APEX / linker namespace 구성
  • HAL / native service 구성
  • Zygote / ART / SystemServer 부팅 안정화
  • Graphics / Display / GPU 경로 검증
  • Framework service 초기화 순서 검증

2. FVP 환경에서 에러가 많이 발생하는 주요 이유

2.1 실제 디바이스와 FVP의 하드웨어 차이

실제 Android 디바이스는 SoC, GPU, display controller, storage, interrupt controller, power domain, secure firmware 등이 제품에 맞게 통합되어 있다.

반면 FVP는 ARM이 제공하는 가상 플랫폼이므로 실제 디바이스와 다음 차이가 있다.

구분실제 디바이스FVP 환경
CPU 실제 SoC CPU 모델링된 CPU
GPU 실제 Mali/Adreno 등 제한적 모델 또는 SW rendering
Storage UFS/eMMC 실제 장치 가상 block device
Display 실제 DPU/DSI/Panel 가상 framebuffer/display
Power/Clock 실제 PMIC/clock tree 단순화 또는 미구현
Secure world TrustZone/TEE 연동 제한적 또는 별도 설정 필요
HAL vendor HAL 제공 직접 구성 필요
디버깅 로그 + trace 제한 상세 trace 가능하지만 느림

이 차이 때문에 Android가 기대하는 하드웨어 기능이 FVP에서 완전히 제공되지 않으면 부팅 중 에러가 발생한다.


2.2 AOSP는 “완성된 제품 보드” 기준으로 동작하지 않는다

AOSP는 기본적으로 범용 Android 소스이지만, 실제 부팅을 위해서는 board-specific 설정이 필요하다.

특히 다음 항목이 정확히 맞아야 한다.

  • BoardConfig
  • product makefile
  • device tree
  • kernel config
  • vendor partition 구성
  • system/vendor/product partition 구성
  • HAL service 등록
  • VINTF manifest
  • init rc
  • fstab
  • SELinux policy
  • linkerconfig
  • APEX dependency

FVP에서는 이 중 일부가 없거나 불완전한 경우가 많기 때문에, 단순히 AOSP를 빌드했다고 해서 Android Framework까지 정상 부팅되지는 않는다.


2.3 Android 부팅 경로가 길고 의존성이 많음

Android 부팅은 다음과 같이 여러 단계로 진행된다.

Bootloader
  ↓
Kernel
  ↓
init
  ↓
ueventd / servicemanager / hwservicemanager
  ↓
native daemons
  ↓
APEX activation
  ↓
linker namespace 구성
  ↓
zygote 실행
  ↓
ART / Java Runtime 초기화
  ↓
system_server fork
  ↓
SystemServer.main()
  ↓
PackageManagerService / ActivityManagerService 등 Framework 서비스 초기화
  ↓
Launcher / SystemUI
  ↓
boot_completed
 

각 단계가 다음 단계의 전제 조건이 되기 때문에, 초반 설정 하나가 잘못되면 후반에서 전혀 다른 형태의 에러로 나타날 수 있다.

예를 들어:

APEX 설정 오류
  → linker namespace 오류
  → app_process64 실행 실패
  → zygote 실행 실패
  → system_server 미실행
  → framework 부팅 실패
 

또는:

Device Tree의 SMMU 설정 오류
  → GPU DMA mapping 실패
  → display/HWC 초기화 실패
  → SurfaceFlinger 오류
  → SystemUI 표시 실패
 

3. 에러가 많이 발생하는 주요 영역

3.1 Bootloader / Kernel / Device Tree 영역

FVP에서 가장 먼저 문제가 발생할 수 있는 영역이다.

주요 에러 유형은 다음과 같다.

영역대표 문제원인
Device Tree 장치 인식 실패 DT node 누락 또는 주소/IRQ 불일치
Memory map kernel panic reserved-memory, RAM base, initrd 위치 오류
Interrupt device timeout GIC 설정 불일치
SMMU/IOMMU DMA fault stream ID, domain, mapping 설정 오류
Storage rootfs mount 실패 fstab, block device path 오류
Console 로그 미출력 UART 설정 오류

이 단계의 문제는 Android Framework까지 올라가기 전에 kernel panic, mount 실패, init failure 형태로 나타난다.


3.2 init / rc / fstab / SELinux 영역

Kernel 이후 Android init 단계에서 문제가 자주 발생한다.

주요 문제는 다음과 같다.

영역대표 문제설명
init.rc service 미실행 서비스 이름, path, class, user/group 오류
fstab partition mount 실패 system/vendor/product/apex mount 실패
ueventd device node 생성 실패 권한 또는 device path 오류
SELinux permission denied policy 미정의 또는 context 불일치
property 부팅 property 미설정 init trigger 미동작

특히 FVP 초기 bring-up 단계에서는 SELinux를 enforcing 상태로 두면 원인 분석이 어려울 수 있다.
초기에는 permissive로 원인 범위를 좁히고, 이후 단계적으로 policy를 보완하는 방식이 효율적이다.


3.3 APEX / linker namespace / native library 영역

AOSP 최신 버전에서는 ART, i18n, runtime, media 등 핵심 기능이 APEX 단위로 분리되어 있다.

FVP에서 이 영역이 맞지 않으면 다음과 같은 문제가 발생한다.

CANNOT LINK EXECUTABLE "/system/bin/app_process64"
library "libnativeloader.so" not found
 

또는:

libicu.so not found
needed by libharfbuzz_ng.so
 

이런 문제는 단순히 so 파일 하나가 없는 문제가 아니라, 대부분 다음 원인과 연결된다.

  • APEX mount 실패
  • linkerconfig 생성 오류
  • namespace 간 library link 누락
  • system/product/vendor partition 구성 불일치
  • runtime APEX dependency 불일치
  • 32bit/64bit library path 불일치

이 영역은 zygote 실행 전에 매우 중요하다.

APEX 활성화
  ↓
linker namespace 구성
  ↓
app_process64 실행
  ↓
zygote 시작
 

따라서 linker/APEX 오류가 있으면 Android Java Framework로 진입하기 전에 부팅이 멈춘다.


3.4 Zygote / ART / Java Runtime 영역

zygote가 실행되면 ART Runtime, boot image, class preloading, JNI library loading 등이 수행된다.

이 단계에서 발생 가능한 문제는 다음과 같다.

영역대표 문제원인
app_process64 실행 실패 linker / native library 문제
ZygoteInit preload 중단 classpath, framework jar, resource 문제
ART SIGABRT boot image, oat/vdex, JNI load 문제
JNI libicu_jni.so 등 로딩 실패 dependency, namespace, symbol 문제
Dex/OAT dex open 실패 bootclasspath 또는 oat mismatch

예를 들어 libicu_jni.so 로딩 중 SIGABRT가 발생한다면 다음 지점을 나누어 확인해야 한다.

JavaVMExt::LoadNativeLibrary()
  ↓
OpenNativeLibrary()
  ↓
FindSymbol()
  ↓
JNI_OnLoad()
 

각 단계에 marker를 넣으면 실제 실패 위치를 좁힐 수 있다.


3.5 SystemServer / Framework Service 초기화 영역

zygote가 system_server를 fork하고 SystemServer.main()까지 진입하면 Android Framework 초기화 단계에 들어간다.

이후 다음 서비스들이 순차적으로 초기화된다.

SystemServer.main()
  ↓
startBootstrapServices()
  ↓
Installer
  ↓
DeviceIdentifiersPolicyService
  ↓
ActivityManagerService
  ↓
PowerManagerService
  ↓
PackageManagerService
  ↓
UserManagerService
  ↓
startCoreServices()
  ↓
BatteryService
  ↓
startOtherServices()
  ↓
WindowManagerService
  ↓
InputManagerService
  ↓
SystemUI
 

이 단계에서는 특히 PackageManagerService에서 문제가 많이 발생할 수 있다.

대표적으로 다음 함수 흐름에서 문제가 발생할 수 있다.

PackageManagerService 초기화
  ↓
InstallPackageHelper.addForInitLI()
  ↓
scanPackageNewLI()
  ↓
scanPackageOnlyLI()
  ↓
ScanPackageUtils.collectCertificatesLI()
  ↓
APK parsing / signature / overlay / shared library 처리
 

이 영역에서 에러가 나는 이유는 다음과 같다.

  • framework-res.apk 문제
  • overlay APK 문제
  • product/vendor overlay 불일치
  • certificate parsing 실패
  • shared library dependency 누락
  • system/product partition의 package 구성 오류
  • bootclasspath / systemserverclasspath 불일치

특히 FVP에서는 실제 단말 vendor 구성이 없기 때문에 package scan 단계에서 예상하지 못한 오류가 나올 수 있다.


3.6 Graphics / SurfaceFlinger / HWC / GPU 영역

Android Framework가 어느 정도 올라간 뒤에도 화면 표시 단계에서 문제가 발생할 수 있다.

주요 문제는 다음과 같다.

영역대표 문제원인
SurfaceFlinger 실행 실패 display HAL/HWC 문제
HWC composer service 미실행 HAL manifest 또는 binary 누락
GPU SMMU fault DMA/IOMMU 설정 오류
minigbm buffer allocation 실패 gralloc 설정 문제
SystemUI 화면 미표시 SurfaceFlinger/WindowManager 문제

예를 들어 다음과 같은 service가 필요한 경우가 있다.

android.hardware.graphics.composer@2.4-service
hwcomposer.drm_minigbm.so
 

FVP에서 GPU를 실제 Mali path로 쓸지, software rendering으로 쓸지에 따라 설정이 달라진다.

초기 bring-up 단계에서는 graphics path를 단순화하기 위해 software rendering 또는 최소 framebuffer 기반으로 먼저 부팅을 확인하고, 이후 GPU/HWC를 붙이는 방식이 안정적이다.


4. 에러 발생 위치 요약

전체적으로 보면 FVP bring-up에서 에러가 많이 발생하는 구간은 다음 순서로 정리할 수 있다.

우선순위에러 발생 영역영향도주요 증상
1 Kernel / DT / fstab 매우 높음 mount 실패, panic, init 실패
2 APEX / linker namespace 매우 높음 app_process64 실행 실패
3 Zygote / ART 매우 높음 SIGABRT, preload 실패
4 PackageManagerService 높음 framework boot 중단
5 SELinux 높음 permission denied, service 실패
6 Graphics / HWC / GPU 중~높음 SurfaceFlinger 실패, 화면 미표시
7 SystemUI / Launcher 중간 boot_completed 미도달
8 성능 / timing 중간 timeout, deadlock처럼 보이는 현상

5. 해결 전략

5.1 전체 전략

FVP 환경에서는 모든 문제를 한 번에 해결하려고 하면 분석이 어렵다.
따라서 다음 원칙으로 접근해야 한다.

1. 부팅 단계를 명확히 나눈다.
2. 각 단계별 성공 기준을 정의한다.
3. 실패 지점을 marker/log로 고정한다.
4. Cuttlefish 또는 reference 환경과 비교한다.
5. FVP 전용 차이를 하나씩 제거한다.
6. workaround와 정식 fix를 분리한다.
 

5.2 단계별 성공 기준 정의

단계성공 기준
Kernel boot kernel panic 없이 init 실행
init stage system/vendor/product/apex mount 성공
APEX stage runtime/i18n/art apex 활성화 성공
linker stage app_process64 실행 가능
zygote stage zygote 정상 실행
system_server stage SystemServer.main() 진입
PMS stage PackageManagerService scan 완료
AMS/WMS stage ActivityManager/WindowManager 초기화
Graphics stage SurfaceFlinger/HWC 정상 실행
Final stage sys.boot_completed=1 도달

이 기준을 잡으면 현재 작업 위치가 명확해진다.

예를 들어:

SystemServer.main()까지 진입했지만 PackageManagerService scan 중 중단된다
 

라고 표현하면, 문제 범위가 kernel이나 linker가 아니라 framework package scan 영역으로 좁혀진다.


5.3 디버깅 방식

Marker 기반 디버깅

FVP는 느리기 때문에 반복 실행 비용이 크다.
따라서 의심 지점에 marker를 촘촘히 넣어서 한 번의 실행으로 실패 위치를 최대한 좁히는 것이 중요하다.

예시:

 
ALOGE("FVP_MARKER: before OpenNativeLibrary");
ALOGE("FVP_MARKER: after OpenNativeLibrary");
ALOGE("FVP_MARKER: before FindSymbol");
ALOGE("FVP_MARKER: after FindSymbol");
ALOGE("FVP_MARKER: before JNI_OnLoad");
ALOGE("FVP_MARKER: after JNI_OnLoad");
 

이런 방식은 다음 영역에서 특히 효과적이다.

  • JavaVMExt::LoadNativeLibrary()
  • DexFile_openDexFileNative()
  • OatFileManager::OpenDexFilesFromOat()
  • SystemServer.main()
  • PackageManagerService
  • InstallPackageHelper.addForInitLI()
  • scanPackageNewLI()
  • ScanPackageUtils.collectCertificatesLI()

5.4 비교 기준 환경 확보

FVP 단독 분석은 어렵기 때문에 비교 기준이 필요하다.

추천 비교 대상은 다음과 같다.

비교 대상목적
Cuttlefish AOSP 정상 boot 기준
QEMU/Goldfish emulator 계열 기준
AVB 또는 다른 reference board 이미지 구성 비교
실제 Android 디바이스 Framework/HAL 동작 비교
FVP 목표 환경

비교 항목은 다음과 같다.

  • init log 차이
  • mounted partition 차이
  • linker namespace 차이
  • APEX activation 차이
  • zygote log 차이
  • SystemServer service init 순서 차이
  • PackageManager scan 대상 차이
  • HAL service 등록 차이
  • SELinux denial 차이

6. 개발 Plan

Phase 1. 기준 환경 구축

목표는 “재현 가능한 FVP 부팅 환경”을 만드는 것이다.

작업 항목:

  • FVP 실행 script 정리
  • kernel image / dtb / ramdisk / system image 버전 고정
  • 실행 option 문서화
  • 로그 저장 방식 통일
  • clean boot 기준 log 확보
  • 실패 시점 자동 추출 script 작성

산출물:

- FVP 실행 가이드
- baseline boot log
- image version matrix
- known issue list
 

Phase 2. Boot 단계 안정화

목표는 kernel과 init 단계까지 안정화하는 것이다.

작업 항목:

  • device tree 검증
  • memory map 검증
  • fstab 검증
  • system/vendor/product/apex mount 확인
  • SELinux permissive 기준 boot 확인
  • init service 실행 여부 확인

확인 log:

init: starting service
fs_mgr: mounted
apexd: activated
ueventd: created device node
 

산출물:

- Kernel/init boot checklist
- fstab/device tree 수정 내역
- SELinux denial 초기 목록
 

Phase 3. APEX / linker namespace 안정화

목표는 zygote 실행 전 native dependency 문제를 제거하는 것이다.

작업 항목:

  • /apex mount 확인
  • runtime APEX 확인
  • i18n APEX 확인
  • ART APEX 확인
  • linkerconfig 생성 결과 분석
  • namespace link 누락 확인
  • app_process64 dependency 확인

중점 확인 사항:

/system/bin/app_process64
libnativeloader.so
libandroid_runtime.so
libicu.so
libicu_jni.so
libharfbuzz_ng.so
 

산출물:

- linker namespace 분석표
- missing library list
- APEX dependency map
- 수정된 linkerconfig 정책
 

Phase 4. Zygote / ART 안정화

목표는 zygote가 정상 실행되고 system_server를 fork하는 것이다.

작업 항목:

  • app_process64 실행 확인
  • zygote init log 확인
  • preloadClasses() 위치 확인
  • JNI library load 경로 확인
  • libicu_jni.so loading marker 추가
  • boot image / oat / vdex mismatch 확인
  • system_server fork 확인

성공 기준:

zygote started
system_server forked
SystemServer.main() entered
 

산출물:

- Zygote/ART boot flow 분석표
- JNI loading failure point
- preload 관련 workaround 검토서
 

Phase 5. Framework Service 안정화

목표는 SystemServer 이후 핵심 Android service를 정상 초기화하는 것이다.

작업 항목:

  • SystemServer.main() marker 추가
  • startBootstrapServices() 단계 분석
  • PackageManagerService scan 흐름 분석
  • overlay package 검증
  • certificate parsing 오류 확인
  • framework-res.apk / product overlay 검증
  • ActivityManagerService / PowerManagerService 초기화 확인

중점 함수:

SystemServer.main()
PackageManagerService.<init>()
InstallPackageHelper.addForInitLI()
scanPackageNewLI()
scanPackageOnlyLI()
ScanPackageUtils.collectCertificatesLI()
 

성공 기준:

PackageManagerService scan complete
ActivityManagerService ready
WindowManagerService ready
 

산출물:

- Framework service boot sequence
- PMS scan failure report
- overlay/package dependency table
 

Phase 6. Graphics / Display 안정화

목표는 SurfaceFlinger, HWC, SystemUI 표시까지 확인하는 것이다.

작업 항목:

  • SurfaceFlinger 실행 확인
  • graphics composer HAL 확인
  • gralloc/minigbm 확인
  • software rendering fallback 검토
  • GPU path 사용 여부 결정
  • SMMU/IOMMU fault 분석
  • WindowManager / SystemUI 표시 확인

초기 전략:

1차 목표: software rendering 또는 최소 display path로 boot_completed 확인
2차 목표: HWC/minigbm 적용
3차 목표: GPU/SMMU path 안정화
 

산출물:

- Graphics boot path 분석
- HWC/HAL dependency list
- GPU/SMMU fault 분석표
 

Phase 7. boot_completed 및 안정화

목표는 Android boot 완료 상태를 만드는 것이다.

성공 기준:

getprop sys.boot_completed
=> 1
 

추가 확인:

SurfaceFlinger alive
system_server alive
zygote alive
PackageManager ready
ActivityManager ready
SystemUI running
Launcher visible
 

산출물:

- boot_completed 성공 log
- 최종 patch list
- known limitation
- 재현 절차 문서
 

7. 우선순위 기반 해결 방향

단기 해결 방향

단기 목표는 “일단 framework boot를 최대한 앞으로 진행시키는 것”이다.

우선순위:

  1. mount / fstab / apex 활성화 확인
  2. linker namespace 오류 제거
  3. app_process64 실행 성공
  4. zygote 실행 성공
  5. system_server 진입 확인
  6. PackageManagerService scan 완료
  7. SurfaceFlinger/SystemUI는 이후 단계에서 해결

단기에는 graphics/GPU보다 zygote와 system_server 안정화가 더 중요하다.


중기 해결 방향

중기 목표는 Android Framework service를 안정화하는 것이다.

주요 작업:

  • PackageManagerService 오류 제거
  • overlay / certificate / shared library 문제 해결
  • SELinux denial 정리
  • HAL service manifest 정리
  • native daemon lifecycle 정리

장기 해결 방향

장기 목표는 FVP를 반복 가능한 Android bring-up 플랫폼으로 만드는 것이다.

주요 작업:

  • 자동화된 boot harness 구축
  • boot 단계별 log parser 작성
  • Cuttlefish/FVP diff tool 구성
  • 실패 유형별 DB화
  • regression test 구성
  • Android version upgrade 대응 체계 구축

8. 리스크 및 대응 방안

리스크영향대응
FVP 실행 속도 느림 디버깅 반복 비용 증가 marker 기반 one-shot 분석
하드웨어 모델 미지원 특정 HAL 동작 불가 SW fallback 또는 stub HAL 적용
GPU/SMMU fault 화면 표시 실패 초기에는 SW rendering 우선
APEX/linker 오류 zygote 실행 불가 linkerconfig/APEX mount 우선 검증
SELinux denial service 실행 실패 초기 permissive 후 policy 보완
Framework package scan 실패 system_server 중단 PMS 함수 단위 marker 추가
Android 버전 변경 기존 patch 무효화 version matrix 관리

9. 발표용 핵심 메시지

보고서나 발표에서는 아래 메시지를 중심으로 정리하면 좋다.

FVP 환경의 에러는 단순 코드 버그라기보다,
Android가 기대하는 하드웨어/커널/HAL/APEX/Framework 구성과
FVP 가상 플랫폼 구성 간의 차이에서 주로 발생한다.
 
따라서 해결 전략은 개별 에러를 임시 수정하는 방식이 아니라,
부팅 단계를 분리하고 각 단계의 성공 기준을 정의한 뒤,
marker 기반으로 실패 위치를 좁히고,
Cuttlefish 또는 reference 환경과 비교하여 차이를 제거하는 방식으로 진행해야 한다.
 
단기적으로는 zygote와 system_server 진입을 안정화하고,
중기적으로 PackageManagerService와 Framework service 초기화를 안정화하며,
장기적으로는 FVP boot harness와 regression 체계를 구축하는 것이 목표이다.
 

10. 발표 자료 구성안

Slide 1. 제목

ARM FVP 기반 Android/AOSP 실행 안정화 개발 계획
 

Slide 2. 배경

- FVP 환경에서 AOSP/Android boot bring-up 진행 중
- 실제 디바이스 대비 하드웨어/커널/HAL 구성 차이 존재
- 부팅 과정 중 linker, zygote, ART, framework, graphics 영역에서 다수 오류 발생
- 체계적인 원인 분류 및 단계별 해결 계획 필요
 

Slide 3. 왜 에러가 많이 발생하는가

- FVP는 실제 제품 보드가 아닌 가상 하드웨어 모델
- Android는 board/vendor/HAL/APEX/SELinux 구성이 정확히 맞아야 정상 동작
- 하나의 설정 오류가 zygote, system_server, framework 오류로 연쇄 전파
- FVP는 실행 속도가 느려 반복 디버깅 비용이 높음
 

Slide 4. 에러 발생 주요 영역

1. Kernel / Device Tree / fstab
2. init / SELinux / service
3. APEX / linker namespace
4. Zygote / ART / JNI
5. SystemServer / PackageManagerService
6. Graphics / SurfaceFlinger / HWC / GPU
 

Slide 5. 현재 분석 관점

부팅 흐름을 단계별로 분리하여 현재 실패 위치를 명확히 정의

Kernel
 → init
 → APEX
 → linker
 → zygote
 → system_server
 → PackageManagerService
 → SurfaceFlinger/SystemUI
 → boot_completed
 

Slide 6. 해결 전략

- 단계별 성공 기준 정의
- marker 기반 실패 위치 고정
- Cuttlefish/reference 환경과 비교
- FVP 전용 설정 차이 제거
- workaround와 정식 fix 분리
- 재현 가능한 boot harness 구축
 

Slide 7. 개발 Plan

Phase 1. 기준 환경 구축
Phase 2. Kernel/init 안정화
Phase 3. APEX/linker 안정화
Phase 4. Zygote/ART 안정화
Phase 5. Framework service 안정화
Phase 6. Graphics/display 안정화
Phase 7. boot_completed 및 regression 구축
 

Slide 8. 기대 효과

- FVP boot 실패 원인 체계화
- 반복 디버깅 시간 감소
- AOSP version upgrade 대응력 확보
- FVP 기반 trace/performance 분석 기반 확보
- Cuttlefish/실제 디바이스/FVP 비교 분석 가능
 

11. 한 줄 결론

FVP에서 발생하는 에러는 대부분 코드 자체의 단일 버그가 아니라,
Android 플랫폼 구성 요소와 FVP 가상 하드웨어 환경 간의 불일치에서 발생한다.
따라서 단계별 boot 기준, marker 기반 분석, reference 환경 비교, 자동화 harness 구축을 통해
반복 가능한 bring-up 개발 체계로 전환하는 것이 핵심이다.
Comments