본문 바로가기

CS/[Embedded]Embedded System Software

[Embedded] Android Architecture

Android architecture

Android architecture에 대해서 알아보도록 하자.

 

안드로이드는 구글에 의해 2007년에 개발된 모바일 os 이다.

 

위 표는 안드로이드의 역사를 나타낸 표이다.

 

ANDROID SDK

 

안드로이드 SDK(software development kit) 는 말 그대로 안드로이드 소프트웨어를 개발하기 위한 툴 킷을 의미한다.

 

ANDROID NDK

 

안드로이드 NDK(Native Development Kit) 란 안드로이드에서 C, C++ 코드를 사용할 수 있게 해주는 일련의 도구 모음이다.

리눅스 system call을 사용할 수 있으며, ndk는 일반적으로 게임이나 물리 시뮬레이션 같은 집약적 연산 intensive operations 의 경우에 사용하면 유용하다.

 

ANDORID ARCHITECTURE

안드로이드의 아키텍쳐는 다음과 같다.

파란색으로 칠해진 영역이 java 코드로 이루어진 part,

초록색과 빨간색으로 이루어진 영역은 c, c++ 코드로 이루어진 part 이다.

 

둘 사이를 연결 시켜 주는 부분이 바로 노란색 part 이다.

 

Application path using SDK

위 그림은 sdk를 이용한 application의 작동 경로 이다.

java application이 실행되게 되면, application framework 단을 거쳐, android runtime을 거쳐, library를 거쳐, kernel에 접근하게 된다.

 

Application path using NDK

위 그림은 ndk를 이용한 application의 작동 경로 이다.

java application이 실행되게 되면, application framework 단을 거치지 않고,  android runtime을 거쳐,ndk 코드를 이용하여

library를 거쳐, kernel에 접근하게 된다.

 

그럼 각 계층에 대해서 구체적으로 알아보면 다음과 같다.

 

Android Kernel

빨간색으로 칠해져 있는 part 가 바로 linux kernel 영역이고 , 안드로이드는 이 linux kernel을 기반으로 설계되었다.

그렇다고 안드로이드가 linux인 것은 절대 아니라는 것을 기억해야 한다.

 

표준 linux 기능들이 모두 포함되어 있지 않다.

리눅스는 module 형태로 기능들이 구현되어 있는데, 결국 linux의 기본 골격만 존재하고 내부 module 내용들은 많이 바뀐형태가 안드로이드인 것이다.

 

Why Linux Kernel?

그렇다면 안드로이드는 왜 linux kernel에서 설계된 것일까?

일단 리눅스는 memory와 process 관리가 매우 잘 되어 있다. 이러한 이유로 많은 플랫폼들도 모두 linux 기반으로 개발이 되어 있다.

 

Kernel Enhancements

기존 리눅스 커널에서 바뀐 부분들은 많이 있는데 다음과 같은 부분들이 변경되었다.

alarm 기능의 경우 안드로이드의 alarmmanager를 지원하기 위한 것으로 user space에서 kernel space에 wake up 해주고 싶을 때 사용하도록 한다.

 

ashmem 기능의 경우 새로운 기존의 POSIX SHM과 다르게 새로운 shared memory를 나타낸다.

모바일 기기의 경우 memory가 작은 device이자 전력을 최소화 해야 하는 경우가 많기 때문에 이에 최적화된 shared memory API 인 것이다.

 

binder의 경우 RPC 형태의 IPC mechanism으로 binder를 통해 모든 것을 통신할 수 있게 한다.

 

power management에 경우 기존 리눅스의 power management에 안드로이드에 필요한 기능이 더 추가 되었다.

 

low memory killer의 경우, 보통 리눅스 커널에서 메모리 관리와 다르게 안드로이드에 특징적인 메모리 관리 기능을 한다.

OOMK(Out Of Memory Killer) 모듈이 돌아가는 것이 리눅스이고, LMK가 안드로이드에서 돌아가는 것이다.

 

결론적으로 리눅스의 구조(껍데기)를 가지고 있지만 내용은 많이 바뀌어 있는 것이 안드로이드라고 생각할 수 있다.

LIBRARY

 

 

Native Library

open source software를 기반으로 만들어진 것이고 주로 c, c++로 이루어져 있고, 특정 하드웨어 별로 특화되어 있다.

안드로이드는 GNU library libc를 쓰는 것이 아닌 Bionic libc를 사용한다.( 더욱 휴대폰에 적합하도록)

 

Bionic libc

구글이 만들어 놓은 c의 라이브러리 들인데, 안드로이드와 같은 임베디드 시스템에 적합하도록 만들어 놓은 라이브러리이다.

 

GNU libc는 gcc를 쓰는 경우 사용하는 라이브러리,

Bionic libc는 안드로이드 쓰는 경우 사용하는 라이브러리 라고 생각하면 된다.

그렇기 때문에 c 코드 작성시 기본적인 GNU libc 사용할 때의 코드 처럼 작성하면 안 돌아갈 수도 있는 것이다.

 

안드로이드 상에서 새로 만든 c 코드 들은 bionic libc에서 제공하는 API를 써야하고 bionic libc 와 함께 컴파일 되어야 한다.

 

주로 사이즈 줄이고, 빠르게 돌 수 있게 하는 것이 bionic libc의 특징이다. 

Function Libraries/Native Servers

기능별 라이브러리로는 webkit(WEB), media framework(MEDIA), sqlite(DB), freetype(FONT)등이 있다.

native server 로는 surface manager, audio manger 가 대표적이다.

 

Surface Flinger/ Audio Flinger

안드로이드 사용자 인터페이스 구성 요소들은 SurfaceFlinger를 통하여 리눅스 커널에 위치한 LCD 디스플레이 드라이버인 프레임 버퍼 드라이버를 통해 그림을 그리게 된다. 

 

왼쪽 그림은 surfaceflinger의 전체적인 역할을 나타낸 그림이다. surfaceflinger는 커널에 위치한 프레임 버퍼 드라이버와 연동하여 생성된 최종 이미지를 프레임 버퍼 드라이버를 통해 LCD에 출력할 수 있도록 프레임 버퍼와 연동하는 역할을 한다.

여러 surface를 합성하여 부드럽게 화면에 표시할 수 있게 해주는 것이다.

 

audio flinger는 모든 오디오 output device를 manage 한다.

 

 

HAL(Hardware Abstration Layer)

library 밑에 hardware abstraction layer가 들어가 있는데, 이는 device driver 이다.

user level c/c++ library에 있는 driver라고 보면 된다.

linux의 device driver와 상당히 유사한 구조로 되어 있는데, 하필 유저 레벨에 만든 이유는 무엇일까

 

서로 다른 디바이스를 연결 했을 때, device driver를 open, read, write 하는 방식은 동일할 것이다.

하지만 입력하는 값도 동일할까? 그렇지 않다. 디바이스마다 요구 하는 값이 다를 수 도 있다.

그렇게 되면 library에서 driver를 사용할 때, hw 마다 개별적으로 library를 만들어야 하는 문제점이 생기게 된다.

 

이러한 문제를 해결하기 위해 HAL이 등장하게 된 것이다. 하드웨어를 별 차이 없이 다룰 수 있도록 한다.

 

작성한 코드를 kernel level에 올리면 공개해야함, user level에 올리면 공개하지 않아도 됨

 

Android Runtime/ DVM(Dalvik Virtual Machine)

안드로이드 실행 환경에 대해 알아보자.

일반적으로 JVM은 java code를 byte code로 바꿔주는데 이 바이트 코드는 플랫폼에 독립적이고 한번의 빌드로 여러 플랫폼에서 실행할 수 있게 된다.

하지만 이러한 JVM은 모바일 기기 환경에는 최적화 되어 있지 않았고, 이에 모바일 기기 환경에 최적화 되어 가상 머신이 나오게 되었다.

이것이 바로 dalvik virtual machine 이다.

 

DVM의 특징으로는 다음과 같다.

안드로이드 실행환경은 각 프로세스 마다 dalvik virtual machine을 갖고 그 DVM에서 실행되도록 되어 있는 것이다.

즉, DVM은 다중 인스턴스로 실행되도록 설계되어, application 마다 process가 생성되고 각 프로세스마다 개별적 VM가 제공되는 형식으로 작동되는 것이다.

 

DVM에서 .apk가 만들어 지는 과정은 JVM에서 실행되는 자바 바이트 코드로 변환 되는 동일한 과정을 거치지만 마지막 두 단계가 다르다.

Dex컴파일러는 class파일을 dex파일로 변경하여 DVM에서 실행가능하게 만든다. 여러개의 class파일이 하나의 dex파일로 변경되며 최종적으로 dex, 리소스를 포함한 기타 라이브러리 등이 압축되어 APK(Android application package)가 완성되게 된다.

 

또한 해당 DVM의 경우는 just in time(JIT) 컴파일러를 가지고 있어, 과거 실시간으로 자바 바이트 코드를 cpu에 맞게 변환하였던 것과 달리

어플리케이션을 바이트 코드를 가상머신에서 기계어로 번역한 결과를 캐시에 저장하기 때문에 해당 바이트 코드를 다시 실행하는 경우 캐시에서 내용을 불러오기 때문에 성능이 개선되었다.

하지만, 별도의 메모리 캐시가 필요하다는 점에서 더 많은 메모리 공간이 필요하였으며, 하드웨어 전체적으로 상당한 부하가 생기며 배터리 시간이 저하되는 문제가 발생하였다.

 

왼쪽이 JVM을 설명하는 그림이고 오른쪽과 아래 그림은 dalvik virtual machine을 상세히 나타낸 그림이다.

 

 

이러한 문제를 해결하기 위해 구글에서 새로 개발한 것이 ART(Android Runtime)이다.

ART는 AOT(ahead of time compilation) 컴파일러를 가짐으로서 DVM의 JIT와는 달리 어플리케이션이 설치되는 시점에 전체 바이트 코드를 기계어로 번역하기 때문에, 설치시간이 오래 걸린다는 단점이 있지만, 런타임에서 바이트 코드를 해석하는 시간을 제거했기 때문에 전체적인 성능이 좋아지고 배터리 수명이 향상되었다.

 

Application Framework

application framework는 안드로이드 아키텍처에서 다음에 해당하는 부분이다.

이는 component의 재사용을 가능하게 하고 단순화 시키는 역할을 한다.