AOSP build
이 문서는 책 Embedded.Android(2013.3)].Karim.Yaghmour 을 기반으로 Android Open Source Project 빌드 방법을 정리한 것 이다.
빌드 사양
하드웨어 빌드 사양
- 진저브레드 이상은 64비트 운영체제
- 저장장치용량은 코드 체크아웃을 위한 100GB, 빌드를 위해 추가 150GB 가 필요 함. 시간 단축을 위해 병렬 빌드를 한다면 추가 여유공간이 필요함.
- 가상머신을 사용한다면 최소 램 용량은 16GB/swap 이 필요
소프트웨어 빌드 사양
- Android 6.0 (Marshmallow)이상 - AOSP master: Ubuntu 14.04 (Trusty) 사용
- Java Development Kit (JDK)의 경우 AOSP:master는 배포되는 소스에 JDK를 포함하므로 추가 설치가 필요없다.
- Python 2.6 to 2.7 from python.org
- GNU Make 3.81 to 3.82 from gnu.org Android 4.0.x 이전의 경우 3.81을 사용해야 한다.
- Git 1.7 or newer from git-scm.com
툴체인
- Android NDK 와 레거시 커널 빌드를 위해 AOSP:master 브랜치는 AOSP/prebuilt에 gcc4.9를 포함한다.
우분투 14.04의 경우 필요한 추가적인 빌드 패키지 설치
- sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev libxml2-utils xsltproc unzip
우분투에서 prebuilt에 포함된 OpenJDK8 이용하기
- prebuilt에 포함된 JDK를 다른 안드로이드 버젼의 빌드시 사용하기 위해 적당한 디렉토리로 복사한다.
$ sudo cp -rf prebuilts/jdk/jdk8 /usr/lib/jvm/openjdk8
- 우분투에 설치된 기존 JDK를 확인한다.
$ sudo update-alternatives --config javac
[sudo] password for paul:
There is only one alternative in link group javac (providing /usr/bin/javac): /usr/lib/jvm/java-7-oracle/bin/javac
설정할 것이 없습니다.
|
- 새로운 java를 우선순위 2로 설정
$ sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/openjdk8/linux-x86/bin/java 2
update-alternatives: using /usr/lib/jvm/openjdk8/linux-x86/bin/java to provide /usr/bin/java (java) in 자동 모드
|
- 새로운 javac 우선순위 2로 설정
$ sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/openjdk8/linux-x86/bin/javac 2
update-alternatives: using /usr/lib/jvm/openjdk8/linux-x86/bin/javac to provide /usr/bin/javac (javac) in 자동 모드
|
- 새로운 javadoc 우선순위 2로 설정
$ sudo update-alternatives --install /usr/bin/javadoc javadoc /usr/lib/jvm/openjdk8/linux-x86/bin/javadoc 2
update-alternatives: using /usr/lib/jvm/openjdk8/linux-x86/bin/javadoc to provide /usr/bin/javadoc (javadoc) in 자동 모드
|
- install 확인
$ sudo update-alternatives --config java
대체 항목 java에 대해 (/usr/bin/java 제공) 2개 선택이 있습니다.
선택 경로 우선순위 상태
------------------------------------------------------------
* 0 /usr/lib/jvm/openjdk8/linux-x86/bin/java 2 자동 모드
1 /usr/lib/jvm/java-7-oracle/jre/bin/java 1 수동 모드
2 /usr/lib/jvm/openjdk8/linux-x86/bin/java 2 수동 모드
$ java -version
openjdk version "1.8.0_152-android"
OpenJDK Runtime Environment (build 1.8.0_152-android-4163371-1)
OpenJDK 64-Bit Server VM (build 25.152-b1, mixed mode)
|
repo 설치
- Git을 이용한 스크립트 파일로 여러개의 Git 저장소를 관리한다.
$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo |
소스 다운로드
픽셀, 넥서스
다운로드할 버젼 선택
아래 두 가지 방법으로 다운로드할 버젼의 브랜치를 확인 한 후 소스를 다운로드 한다.
- 안드로이드 웹을 통한 branch name 확인
아래 사이트를 통해서 구글에서 만드는 픽셀과 넥서스의 소스코드를 다운로드 할 수 있다. 또한 동일 페이지에서 코드네임과 API 버젼 테이블도 같이 제공한다.
- Repo manifest을 통한 branch name 확인
$ cd manifest
$ git branch -a
android-9.0.0_r8
* master
remotes/origin/HEAD -> origin/master
remotes/origin/adt_23.0.3
remotes/origin/afw-test-harness-1.5
remotes/origin/afw-test-harness-2.1
remotes/origin/afw-test-harness-marshmallow-dev
remotes/origin/afw-test-harness-nougat-dev
remotes/origin/android-1.6_r1
remotes/origin/android-1.6_r1.1
remotes/origin/android-1.6_r1.2
…
|
선택한 버전의 소스 다운로드
-b 옵션을 이용하여 각 버젼에 해당하는 브랜치를 다운로드한다.
다른 버전을 추가로 받기
AOSP:master branch를 이미 받은 경우, 다른 버젼을 추가로 다운로드를 한다면, --reference 옵션으로 master branch 에서 이미 받은 리소스를 참조하여 짧은 시간에 repo sync를 완료할 수 있다.
아래 명령은 master를 참조하여 oreo_r46을 다운로드 한다.
$ repo init -u https://android.googlesource.com/platform/manifest -b android-8.1.0_r46 --reference=~/work/android/aosp-master
$ repo sync -j24 |
비공개 바이너리 다운받기
그래픽 가속기, GPS등 하드웨어 관련 비공개 라이브러리는 AOSP에 포함되지 않으므로 따로 다운로드 받아야한다.
- 다운로드된 파일은 압축된 형태로 빌드파일과 라이브러리를 포함한다. 압축을 풀면 일반적으로 /vendor 디렉토리에 풀린다. 이 파일을 비공개 바이너리의 안드로이드 버전에 해당하는 AOSP에 추가하여 빌드를 하면 된다.
구글외 제품 빌드
- LG전자
안드로이드 와 리눅스를 다운로드 할 수 있다.
- AOSP 소스에 LG소스를 추가해서 빌드를 하도록 되어 있다.
아래는 F800_Nougat_Android_10v 빌드방법 이다.
- AOSP:android-7.0.0_r6 소스를 다운로드 하여 F800_Nougat_Android_10v 소스와 merge한다.
- $ source build/envsetup.sh
- $ lunch aosp_bullhead-userdebug
- $ make -j4
- 삼성전자
빌드
envsetup.sh와 lunch는 명령을 실행한 쉘만 적용되므로 새로운 쉘에서 빌드를 할땐 두 명령을 다시 수행해야 한다.
환경설정
현재 쉘에 빌드에 필요한 환경변수를 설정한다.
$ source build/envsetup.sh
|
빌드타겟 설정
빌드할 타겟은 BUILD-BUILDTYPE 형태로 표현된다.
- BUILD:
- BUILDTYPE:
- user : 제한된 접근권한이 적용, 제품적용 타겟 빌드시 사용한다.
- userdebug : user 타입과 비슷하나 root권한이 적용되고 디버깅이 가능하다.
- eng : 추가적인 디버깅 툴이 설치되고, 빌드시 최적화를 제거하여 디버깅을 용이하게 한다.
개발 타겟 빌드시 사용한다.
$ lunch aosp_arm-eng
|
빌드 수행
빌드시 -j옵션으로 병렬로 수행할 빌드 태스크의 개수를 지정할 수 있다.
예) 2 CPUs, 4 cores per CPU, 2 threads per core 이라면, -j16 ~ j32를 설정한다.
make -j4
|
빌드에러
jack server error
에러 메시지
jack-rsc.tmp: Is a directory
…
Communication error with Jack server (56). Try 'jack-diagnose'
ninja: build stopped: subcommand failed
|
솔루션
아래 명령으로 jack을 재실행 한다.
(참고: https://forum.xda-developers.com/chef-central/android/guide-android-rom-development-t2814763/page514)
$ ./prebuilts/sdk/tools/jack-admin kill-server
$ ./prebuilts/sdk/tools/jack-admin start-server
|
에러메시지
Out of memory error (version 1.3-rc7 'Douarn' (445000 d7be3910514558d6715ce455ce0861ae2f56925a by android-jack-team@google.com)).
GC overhead limit exceeded.
Try increasing heap size with java option '-Xmx<size>'.
Warning: This may have produced partial or corrupted output.
[ 43% 3920/8934] Compiling SDK Stubs with Jack: out/target/common/obj/JAVA_LIBRARIES/android_system_stubs_current_intermediates/classes.jack
ninja: build stopped: subcommand failed.
|
솔루션
참고: 컴파일시 사용되는 메모리 사용제한을 늘린다. https://stackoverflow.com/questions/35579646/android-source-code-compile-error-try-increasing-heap-size-with-java-option
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4g" ./prebuilts/sdk/tools/jack-admin kill-server
./prebuilts/sdk/tools/jack-admin start-server
|
빌드설정
보드 변경시 필요한 설정 참조: https://elinux.org/Android_Device#build.2Fbuildspec.mk.default
빌드아키텍쳐
Product Deivce Board 의 개념
Makefile 병함 과정
빌드는 envsetup.sh & lunch 명령의 조합이나 buildspeck.mk파일을 통해서 최종 빌드타겟을 설정한다.
buildspeck.mk 이용시 build/buildspec.mk.default를 참조하여 필요한 환경변수를 설정한 뒤 buildspeck.mk를 루트 디렉토리에 저장하면 된다.
아래는 make 명령시 설정된 타겟과 관련된 환경변수를 보여준다.
============================================
PLATFORM_VERSION_CODENAME=Q
PLATFORM_VERSION=Q
TARGET_PRODUCT=aosp_arm
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=generic
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-3.13.0-79-generic-x86_64-Ubuntu-14.04.4-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=PI
OUT_DIR=out
============================================
|
- 타겟 디바이스 설정은 build/make/target/product/, device/*/*/에 존재하는 AndroidProducts.mk에서 시작한다.
- lunch에서 표시되는 타겟리스트는 master:/device/*/*/AndroidProducts.mk 에서 COMMON_LUNCH_CHOICES와 /device/*/*/vendorsetup.sh 에서 add_lunch_combo()로 추가되는 LUNCH_MENU_CHOICES 에 저장된 리스트를 표시한다.
- add_lunch_combo()는 /device/*/*/vendorsetup.sh 에서 호출된다.
- 커널파라미터, 커널로딩 주소, CPU instruction set 등을 결정하는 BoardConfig.mk는 device/*/TARGET_DEVICE/BoardConfig.mk 에 존재한다.
envsetup.sh
소스 검색, 빌드 타겟 확인 등 여러가지 빌드 설정(lunch) 및 빌드 디버깅 기능을 제공한다. 이 스크립트에서 정의 된 명령은 vendorsetup.sh에서도 사용할 수 있다.
- 도움말: $ hmm
- 파일 검색 명령(AndroidProducts.mk)
~/work/android/aosp-master$ godir AndroidProducts.mk
[1] ./device/generic/arm64
[2] ./device/generic/armv7-a-neon
[3] ./device/generic/car
[4] ./device/generic/mini-emulator-arm64
[5] ./device/generic/mini-emulator-armv7-a-neon
[6] ./device/generic/mini-emulator-x86
[7] ./device/generic/mini-emulator-x86_64
[8] ./device/generic/qemu
[9] ./device/generic/uml
[10] ./device/generic/x86
[11] ./device/generic/x86_64
[12] ./device/google/atv/products
[13] ./device/google/cuttlefish
[14] ./device/google/marlin
[15] ./device/google/muskie
[16] ./device/google/taimen
[17] ./device/linaro/hikey
[18] ./device/linaro/poplar
[19] ./device/sample/products
Select one:
|
vendorsetup.sh
build/envsetup.sh에 의해 실행되며 주요 기능은 add_lunch_combo()를 이용해 envsetup.sh와 lunch에서 사용할 빌드 타켓을 설정한다.
- envsetup.sh에 정의된 모든 함수를 사용할 수 있다.
- 아래 처럼 호출하면 TARGET_PRODUCT=full_crespo, TARGET_BUILD_VARIANT=userdebug 으로 설정된다.
- 설치되는 각 모듈은 LOCAL_MODULE_TAGS변수에 user, debug, eng, tests, optional, samples 중 하나로 설정되며 TARGET_BUILD_VARIANT에 설정된 값에 매치되는 모듈이 빌드된다.
add_lunch_combo full_crespo-userdebug
|
AndroidProducts.mk
빌드 시스템에 전달할 makefile리스트인 PRODUCT_MAKEFILES을 설정한다. 이 파일이 적용시 LOCAL_DIR 외 다른 변수는 설정된 것이 없으므로 다른 변수를 이용한 조건문은 불가능 하다.
- 아래는 LG전자 bullhead의 설정이다.
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/aosp_bullhead.mk \
$(LOCAL_DIR)/aosp_bullhead_svelte.mk
|
device/company/*/PRODUCT_MAKEFILE
AndroidProducts.mk에서 작성한 제품별 빌드파일로 제품이름 인스톨 패키지등을 설정한다.
- PRODUCT_PACKAGES: 추가할 패키지를 지정한다.
- DEVICE_PACKAGE_OVERLAYS: 기본 패키지 리소스를 기기에 특화된 리소스로 대체한다.
- PRODUCT_COPY_FILES: 대상 파일시스템에 복사할 파일을 지정한다.
- PRODUCT_NAME: 사용자에게 노출되는 제품이름
- PRODUCT_DEVICE: 이 변수와 같은 폴더의 BoardConfig.mk를 적용한다.
- PRODUCT_MODEL: 사용자에게 노출될 모델이름.
- vendor prebuilt makefile 추가됨(아래 빨간색 글자 참고).
# Get the long list of APNs
PRODUCT_COPY_FILES := device/lge/bullhead/apns-full-conf.xml:system/etc/apns-conf.xml
# Inherit from the common Open Source product configuration
$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
PRODUCT_NAME := aosp_bullhead
PRODUCT_DEVICE := bullhead
PRODUCT_BRAND := Android
PRODUCT_MODEL := AOSP on BullHead
PRODUCT_MANUFACTURER := LGE
PRODUCT_RESTRICT_VENDOR_FILES := true
PRODUCT_COPY_FILES += device/lge/bullhead/fstab.aosp_bullhead:root/fstab.bullhead
$(call inherit-product, device/lge/bullhead/device.mk)
$(call inherit-product-if-exists, vendor/lge/bullhead/device-vendor.mk)
PRODUCT_PACKAGES += \
Launcher3 \
WallpaperPicker
|
build/core/main.mk
최상단 Makefile에 의해 호출되며 build/core/config.mk, build/core/definitions.mk 등 호출해 빌드에 필요한 변수 설정이나 빌드 템플릿을 설정한다.
build/core/config.mk
- include $(TOPDIR)buildspec.mk 을 수행하여 빌드타겟 설정을 하며 만약 파일이 없으면 환경변수를 이용한다.
- include $(BUILD_SYSTEM)/envsetup.mk 을 수행하여 envsetup.sh에서 설정한 환경변수를 적용한다.
build/core/envsetup.mk
아래를 호출하여 빌드 버젼과 빌드 타겟 (eng/user..)을 설정한다.
include $(BUILD_SYSTEM)/version_defaults.mk
include $(BUILD_SYSTEM)/product_config.mk
include $(BUILD_SYSTEM)/version_defaults.mk
아래 다양한 빌드 버젼 변수를 설정한다.
PLATFORM_VERSION
PLATFORM_SDK_VERSION
PLATFORM_VERSION_CODENAME
DEFAULT_APP_TARGET_SDK
BUILD_ID
BUILD_NUMBER
|
- include $(BUILD_SYSTEM)/build_id.mk 를 통해 BUILD_ID를 설정한다.
- BUID_ID가 아래처럼 안드로이드 빌드 아아디로 표시된다.
BUILD_ID=OPM6.171019.030.K1
|
build/core/Makefile
이 파일을 통해 여러가지 결과물이 생성되며 주요 사항은 아래와 같다.
- 속성파일들(/default.prop, /system/build.prop) 등
- 램디스크
- 부트 이미지(램디스크와 커널 이미지)
- 공지(NOTICE)파일들:아파치 라이센스 관련 파일
- OTA 키스토어
- 복구이미지
- 시스템 이미지
- 데이터 파티션 이미지
- OTA 업데이트 패키지
- SDK
BoardConfig.mk
각 디바이스에 해당하는 보드설정을 한다.
- device/*/TARGET_DEVICE/BoardConfig.mk 에 위치한다.
- TARGET_DEVICE는 AndroidProducts.mk에서 설정한 TARGET_PRODUCT.mk 에서 설정된다.
- 커널파라미터, 커널로딩 주소,
- CPU instruction set,
- sepolicy,
- 파일시스템 파티션 사이즈 등을 결정한다.
build/buildspec.mk.default
buildspec.mk의 템플릿으로 루트디렉토리에 buildspec.mk로 복사한 후 필요한 설정은 주석을 제거하여 적용이 되도록 수정하면 된다.
Makefile 디버깅
빌드시 GCC 명령 보기
- make showcommands
- 표준출력과 표준에러를 파일에 기록; make showcommands 2>&1 | tell build.log
개별 모듈 빌드하기
- 런처만 빌드: make Launcher2
- 런처만 초기화: make clean-Launcher2
- 갱신된 런치를 시스템이미지에 추가: make Launcher2 snod
새로운 기기 추가를 위한 설정
안드로이드 제공 문서 참조: https://source.android.com/setup/develop/new-device
- 새로운 기기들의 빌드 파일 리스트를 설정한 파일 AndroidProducts.mk를 생성한다.
$ mkdir -p device/mycompany/mydevice
$ vi device/mycompany/mydevice/AndroidProducts.mk
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/full_mydevice.mk |
- 새로운 제품의 빌드파일을 작성한다. 필요한 경우 inherit-product를 이용해 기존 빌드설정을 추가한다.
PRODUCT_DEVICE에 설정된 이름과 같은 디렉토리의 BoardConfig.mk를 적용하게 된다.
$ vi device/mycompany/mydevice/full_mydevice.mk
$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic/device.mk) # Overrides PRODUCT_NAME := full_mydevice PRODUCT_DEVICE := mydevice PRODUCT_BRAND := Android PRODUCT_MODEL := Full Android on mydevice |
- envsetup.sh와 lunch 메뉴에서 추가한 기기를 표시할 수 있도록 vendorsetup.sh를 작성한다.
$ vi device/mycompany/mydevice/vendorsetup.sh
add_lunch_combo full_mydevice-eng
$ chmod 755 vendorsetup.sh
|
- 새로운 기기의 보드에 해당하는 설정을 BoardConfig.mk에 작성한다.
$ vi device/mycompany/mydevice/vendorsetup.sh
|
- 빌드를 한다. 빌드된 이미지의 내용은 아래 폴더(out/target/product/product-name/에서 확인 할 수 있다.
- ramdisk.img: /root
- vendor.img: /vendor
- system.img: /system
- userdata.img: /data
- recovery.img: /recovery
빌드시 커널 폴더 추가하기
- 최상위 디렉토리에 커널을 추가한다.
- 아래 처럼 vendor폴더 추가 스크립트를 적용하는 스크립트를 작성한다.
#!/bin/bash
# Put here shell variables for your environment
#export JAVA_HOME=/usr/lib/jvm/openjdk8
#export ANDROID_JAVA_HOME=$JAVA_HOME
#export USE_CCACHE=1
LUNCH_MENU=full_bullhead-eng
source build/envsetup.sh
lunch $LUNCH_MENU
source vendor/lge/bullhead//build/envsetup.sh
|
- product envsetup에 커널 빌드 함수를 작성한다.
#!/bin/bash
export TOP=$ANDROID_BUILD_TOP
PATH=$ANDROID_HOST_OUT/bin/:$PATH
DATE=`date +%Y%m%d_%H%M`
CORE_NUM=`grep processor /proc/cpuinfo | awk '{field=$NF};END{print field+1}'`
function kernel_make()
{
#KERNEL_OUT="$OUT/obj/kernel"
KERNEL_TC_PREFIX=$TOP/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-
KERNEL_MAKE="make ARCH=arm CROSS_COMPILE=$KERNEL_TC_PREFIX "
if [ -z "$1" ] ; then
KERNEL_TARGET="zImage"
else
KERNEL_TARGET=$@
fi
pushd $TOP/kernel
$KERNEL_MAKE -j$CORE_NUM $KERNEL_TARGET
popd
}
function build_kernel()
{
### kernel ###
LOGFILE="build_${DATE}_kernel.log"
kernel_make distclean && \
kernel_make arndale_android_defconfig && \
kernel_make 2>&1 | tee ${LOGFILE}
notify-send ${LOGFILE} "`tail ${LOGFILE}`"
}
|
루트 디렉토리
- /acct : cgroup 마운트 디렉토리
- /cache : 진행중인 다운로드등 임시데이터 저장
- /charger : 배터리 충전상태를 알려주는 네이티브 앱.
- /config : configs 마운트 디렉토리
- /d : /sys/kernel/debug 심볼릭 링크
- /data : userdata.img 마운트 디렉토리
- /anr : ANR 트레이스
- /app : 앱의 기본 설치 디렉토리
- /app-asec : 암호화된 앱
- /app-private : forward locking된 앱의 설치 디렉토리
- /backup : Backup Manager 시스템 서비스가 사용한다.
- /dalvik-cache : dex바이트코드를 네이티브코드로 변환된 JIT캐시를 저장한다.
- /data : 각 앱의 홈 디렉토리
- /dontpanic : dumpstate가 사용, 발생된 패닉의 콘솔 출력과 스레드 상태를 저장한다.
- /drm : DRM 암호화된 데이터. 포워드 락킹 통제 파일.
- /local : shell에서 쓰기가 가능한 디렉토리.
- /mis : wifi, BT, VPN등 잡다한 데이터가 저장된다.
- /property : 영구적인 시스템 속성
- /resource-cache: 앱 자원 캐시
- /radio : 라디오 펌웨어
- /secure : 암호화된 파일시스템을 사용하는 기기에서 사용하는 사용자 계정정보 저장.
- /system : 계정 데이터베이스, 설치된 앱 목록 등 모든 시스템에서 사용하는 데이터
- /tombstones : 네이티브 바이너리가 비정상 종료될 때마다 관련정보를 저장
- /usr : 다중 사용자 시스템을 위한 사용자별 데이터
- /dev : tmpfs로 마운트 됨, 장치노트가 생성됨.
- /etc : /system/etc 심볼릭 링크
- /mnt : 임시 마운트 디렉토리
- /proc : procfs 마운트 디렉토리
- /root : root 사용자 홈 디렉토리, 보통 비어있음
- /sbin : 리눅스와 달리 ueventd, watchdogd 심볼릭 링크와 charger를 포함
- /sdcard : SD카드 마운트 디렉토리
- /storage : 외부 저장소 마운트 디렉토리
- /sys : sysfs 마운트 디렉토리
- /system : system.img 마운트 디렉토리, 읽기 전용
- /app : AOSP 기본 앱, BUILD_PACKAGE로 빌드된 모듈
- /bin : AOSP로 빌드된 네이티브 바이너리 및 데몬, BUILD_EXECUTALBE로 빌드된 모듈
- /etc : 유틸리티 및 데몬에서 사용하는 설정파일
- /fake-libs : art/libart_fake/README.md 말하길 일부 앱에서 잘못된 구현으로 링크가 필요한 라이브러리.
- /fake-libs64
- /fonts : 안드로이드용 폰트
- /framework: 프레임워크 jar파일
- /lib : 네이티브 라이브러리, BUILD_SHARED_LIBRARY로 빌드된 모듈
- /lib64
- /media : 부트 애니매이션 및 기타 미디어 관련파일
- /priv-app : signatureOrSystem 권한이 필요한 privileged app. app manifest에서 앱권한을 설정한다.
- /tts : 텍스트 음성 변환(Text-to-Speech)엔진 관련 파일
- /usr : 사용자 계정 디렉토리
- /xbin : tcpdump, strace등 시스템동작에 필요 없지만 빌드된 패키지가 생성한 바이너리
- /build.prop: 빌드 중 생성된 속성. 부팅시 init이 로드한다.
- /res : charger 앱의 리소스 파일
- /vendor : 심볼릭 링크(/ststem/vendor), vendor 독점 바이너리를 포함
- /init : init 실행파일
- /init.rc : init 설정파일
- /ueventd.rc : ueventd 설정파일
- /default.prop : 기본으로 설정되는 전역속성
init 프로세스
커널이 램디스크를 루트파일시스템으로 마운트를 한 후 램디스크에 포함된 init프로세스를 실행한다.
init프로세스 수행절차
- init은 udev의 핫플러그 이벤트 핸들러를 구현하고 있으므로, init이 /sbin/ueventd를 통해 호출이 됐으면 ueventd를 실행한다.
- /dev/, /proc, /sys를 생성하고 마운트한다.
- /init.rc, /init.기기명.rc를 시스템에 반영한다.
- 종료되었거나 재시작이 필요한 서비스를 다시 실행한다.
init.rc
- 전역속성 설정파일
- 실행시 stdout, stderr을 /dev/null로 전달하기 때문에 출력 메시지를 확인하려면 logwrapper를 이용해야 한다.
- /out/../system/defualt.prop에 핵심속성의 기본값을 포함한다. 빌드시 변경하려면 AndroidProducts.mk 에서PRODUCT_PROPERTY_OVERRIDES 를 통해서 변경한다.
ueventd
ueventd는 기본 init.rc가 실행하는 최초의 서비스 중 하나다, 설정파일을 읽어 들여 커널이벤트에 따라 /dev에 노드를 생성한다.
- ueventd의 설정파일 문법
/dev/<node> <mode> <user> <group>
|
- ㅇ
ToolBox
- init의 전역속성을 제어
- getprop <key> : 속성 확인
- setprop <key> <value> : 속성 변경
- watchprops : 실시간 속성 감시
- 이벤트 확인 및 전달
- getevent
- sendevent /dev/input/event0 1 330 1
- 서비스 제어
- start <servicename>
- stop <servicename> , ex) stop zygote
- 베이스벤트 프로세서 제어
- smd
- ramdisk.img 마운트하기
램디스크 이미지는 압축파일이므로 아래와 같이 압축을 풀면된다. /root 의 내용과 같다.
$ cd /Path/To/Folder/With/ramdisk.cpio.gz/File mkdir temp_directory && cd temp_directory
$ gunzip -c ../ramdisk.img | cpio -idm
|
기본권한 및 소유권
- 사용자/그룹 생성 설정
build/tools/fs_config 가 /system/core/include/private/android_filesystem_config.h를 참조하여 설정된다.
- 디렉토리와 파일권한
- system/core/libcutils/fs_config.cpp 아래 구조체에 따라 설정된다.
static const struct fs_path_config android_dirs[] = {
// clang-format off
{ 00770, AID_SYSTEM, AID_CACHE, 0, "cache" },
{ 00500, AID_ROOT, AID_ROOT, 0, "config" },
{ 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/ap
…
...
static const struct fs_path_config android_files[] = {
// clang-format off
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-ephemeral/*" },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" },
...
|
모듈 빌드 Android.mk
안드로이드 시스템 각 모듈의 빌드 파일로서 각 모듈을 실행파일 또는 동적 및 정적 라이브러리로 만들 수 있다.
- Module-Description 변수(LOCAL_XXX)
- LOCAL_로 시작하는 변수를 통해 동작과 결과물을 조절할 수 있다.
- 컴파일 결과물 설치위치는 빌드템플릿(BUILD_XXX)따라 정해진다. 설치 위치를 변경하려면 LOCAL_MODULE_PATH를 이용한다.
- 빌드템플릿과 출력경로
탬플릿
BUILD_EXECUTEABLE
BUILD_JAVA_LIBRARY
BUILD_SHARED_LIBRARY
BUILD_PREBUILT
BUILD_MULTI_PREBUILT
BUILD_PACKAGE
BUILD_KEY_CAHR_MAP
|
기본출력 경로
/system/bin
/system/framework
/system/lib
LOCAL_MODULE_CLASS/PATH로 설정해야 함
모듈의 유형에 따라 다름
/system/app
/system/usr/keychars
|
- 빌드 템플릿(BUILD_XXX)
- BUILD_STATIC/SHARED_LIBRARY : 빌드타겟용 공유/정적 라이브러리로 빌드한다.
- BUILD_EXECUTABLE : 빌드타겟용 실행파일로 빌드한다.
- ...
packages/apps/DeskClock/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_RESOURCE_DIR := packages/apps/DeskClock/res
LOCAL_MODULE_TAGS := optional
LOCAL_SDK_VERSION := current
LOCAL_PACKAGE_NAME := DeskClock
LOCAL_OVERRIDES_PACKAGES := AlarmClock
LOCAL_SRC_FILES := $(call all-java-files-under, src gen)
LOCAL_PROGUARD_FLAG_FILES := ../../../frameworks/support/design/proguard-rules.pro
LOCAL_PROGUARD_FLAG_FILES += ../../../frameworks/support/v7/preference/proguard-rules.pro
LOCAL_PROGUARD_FLAG_FILES += ../../../frameworks/support/v7/recyclerview/proguard-rules.pro
(소스 난독화 툴 프로가드 설정)
LOCAL_STATIC_ANDROID_LIBRARIES := \
android-support-design \
android-support-percent \
android-support-transition \
android-support-compat \
android-support-media-compat \
android-support-v13 \
android-support-v14-preference \
android-support-v7-appcompat \
android-support-v7-gridlayout \
android-support-v7-preference \
android-support-v7-recyclerview
LOCAL_USE_AAPT2 := true
(리소스 관리 툴 설정)
include $(BUILD_PACKAGE)
|
TIPS
- 안드로이드에 이더넷 기능 추가하기
- ICS 4.0.4 패치: https://github.com/gxben/aosp-ethernet
- 리나로 패치:
- 파일시스템 하나만 사용하기