Android Architecture
먼저 안드로이드의 구조이다. 여기서 시스템 아키텍처인 Binder IPC에 대해 정리하고자 한다.
https://source.android.com/devices/architecture
Binder IPC(Binder Inter Process Communcation)
모든 시스템 서비스가 서버 프로세스 형태로 제공되기 때문에 다른 프로세스로 요청과 응답을 보내는 메커니즘이 필요한데, 이 메커니즘이 바인더(Binder)이다.
예를 들어 시스템 서비스와 어플리케이션의 상호작용에서 음악 애플리케이션에서 음악을 들으면 오디오 Flinger 서비스에서 제공하는 play() 기능을 사용할 것이다. 하지만 이 오디오 Flinger 서비스는 '미디어 서버'에서 동작하고 음악 애플리케이션은 자신의 프로세스에서 동작 중이기 때문에 이 둘 사이에 play() 함수호출을 전달하는 Binder IPC가 필요하다.
Binder IPC를 사용하는 이유는 성능 때문이다. Android의 모든 시스템 기능은 서버 프로세스로 제공되기 때문에 프로세스 사이에 최적화된 통신 방법이 필요하고 그 결과가 바인더이다. 바인더는 모든 프로세스가 공유하는 커널 메모리를 참조하게 함으로써 메모리 복사 오버헤드를 최소화한다. 뿐만 아니라 C++을 이용해 작성된 RPC(Remote Procedure Call) 프레임워크를 제공하여 생산성이 높다.
RPC : RPC는 Remote Procedure Call , 원격 호출 개념이다, 네트워크상에 있는 함수등을 직접 호출한다. 간단한 예로 A, B 2개의 프로세스가 있고 foo() 라는 Interface를 공유한다고 할때, A Process에서 foo()함수를 호출하면 B Process의 foo() 함수가 호출되어 실행하는것을 말한다.
이정도로 정리할 수 있다.
바인더 드라이버의 커널 공간은 모든 프로세스들이 공유한다. 바인더 드라이버의 역할은 각 프로세스가 매핑해 놓은 메모리 주소와 커널 공간의 메모리 주소를 변환하여 참조해 사용할 수 있도록 하는 것이다.
Linux에서 사용하는 표준 방법인 ioctl 시스템 함수를 이용해 바인더 드라이버를 사용할 수 있다. 이와 같은 일련의 메커니즘을 바인더 IPC라고 한다.
바인더 IPC를 이용해 주고받는 데이터를 가공해서 RPC(Remote Procedure Call)로 만들어 주는 C++ 프레임워크가 제공되고 시스템 서비스를 만들 때 사용한다. 다른 프로세스에서 제공하는 함수를 마치 내 함수처럼 사용할 수 있게 되는 것이다.
위의 Context Manager는 시스템 서비스의 위치를 관리하는 프로세스이다. 서비스 등록, 검색 등의 기능을 구현하고 있으며, servicemanager 프로세스로 동작하는 서비스이다.
service manager는 서비스를 등록하고 검색하는 기능을 제공한다.
그렇다면 위 과정중, Binder driver 호출과정을 직접 코드로 살펴보자.
/framework/native/libs/binder/ProcessState.cpp
함수 선언부에 보면 mVMStartFD와 mVMStart(open_driver(driver)를 바로 호출하고 있다.
그리고 이후 여러 함수를 호출하고 if() 이후에 mmap(...) 함수를 호출하고 있다. mmap(...)는 커널 내에서 Binder 데이터를 수신하기 위한 공유 공간을 확보한다.
open_driver() 함수는 binder의 file descriptor을 반환하며. 이 함수를 통해 Binder가 호출된다.
mDriverFD(open_driver(driver))
:: processState 바로 위로 가면 위의 함수를 만날 수 있다. 여기서 ioctl() 함수를 호출하는것을 볼 수 있다. 이 함수를 통해 이제 Binder Binder가 호출된다.
status_t result = ioctl(fd, BINDER_VERSION, &vers)
이 함수로 Binder의 입출력 설정을 바꾸어준다.
BINDER_VERSION에 관한 내용은 bionic\libc\kernel\uapi\linux\android 에서 확인할 수 있다.
ioctl에 관한 헤더파일은 bionic\libc\kernel\uapi\asm-generic
cpp 파일은 bionic\libc\bionic\ioctl.cpp 에서 확인할 수 있다.
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
Binder의 최대 쓰레드 수를 BINDER_SET_MAX_THREADS의 값인 15개로 한 후 이를 ioctl을 통해 설정한다.
Reference
https://d2.naver.com/helloworld/47656
도서 : 안드로이드 미디어 프레임워크
'Ubuntu, Android' 카테고리의 다른 글
[Ubuntu] 성능평가: perf 사용하기 (0) | 2022.10.17 |
---|---|
[Android] Exoplayer (0) | 2020.05.07 |
[Ubuntu] 삼바(Samba)로 윈도우에서 ubuntu 파일 쓰기 (0) | 2019.10.09 |
[Android] 기기연결을 통한 풀 소스코드 빌드 및 부분빌드 (0) | 2019.09.25 |
[Android] android 풀 소스 코드 및 Ubuntu 용량 수정 (0) | 2019.09.25 |