HAL 안드로이드에서 다양한 H/W 연결을 지원하기 위한 방법으로 HAL 인터페이스를 정의하고 벤더사에서 해당 인터페이스에 맞춰 드라이버 H/W제작을 하도록 함으로써 user 단에서 H/W 고려없이 H/W 접근 통제가 가능하도록 한다.

 

기본적인 HAL 구현 방법이 Android Developer 정의되어있으며 Android 8 이상은 해당 HAL 요건을 충족시켜 개발을 진행해야 한다.

 

1. HAL 모듈 (Android 8.0 이전)

HAL 빌드는 모듈형태로 .so파일에 포함되며 이를 로드함으로써 안드로이드가 H/W 인식하고 정상적으로 사용이 가능하다. 해당 .so파일에 모듈로써 정의하기위해서는 반드시 지켜야 하는 부분들이 있는데 해당 개발 필수조건은 아래와 같다.

 

HAL 이용하기 위해서는 기본적으로 HAL 구조체인 hw_module_t 구현이 필수적이다. 여기서 해당 구조체는

hardware/libhardware/include/hardware/hardware.h의 경로에 저장되어 있으며 H/W 구조체를 정의할 반드시 멤버로 해당 구조체를 선언해주어야 한다. 또한 함수 네이밍에있어 규칙이 존재한다.

 

ex)

struct audio_module {
     hw_module_t hw;

     int read;

     int write;

}

같이 반드시 hw_module_t 포함되어야 하는 HAL 인터페이스 필수 요건으로 기본적으로 HAL 버전 등을 멤버변수로 가지고 있다.

 

1) 모듈 생성 과정

  • hardware/libhardware/include/hardware 경로에 000_0000_.h 모듈 헤더파일을 생성
  • hardware/libhardware/modules 경로에 모듈 폴더를 만들고 폴더 안에 000_0000.cpp 모듈 파일을 생성한다.
  • 모듈 폴더에 Android.mk 파일을 만들어 중간 파일을 생성하도록 한다.

 

결국 HAL 모듈파일은 .so파일로 참조되므로 중간에 mk파일을 통해 중간 파일을 생성하는 과정이 필요하다.

위에서 모듈 헤더 모듈 코드 파일을 만들고 Android.mk파일을 만드는 이유가 바로 모듈 파일들을 바탕으로 중간 파일을 생성하는 과정이다.

 

  • 생성된 모듈 중간파일을 참조할 있는 JNI 파일을 만든다.
  • JNI파일을 등록하여 사용하는 framework 파일을 만든다.

API 통해서 framework - (jni) - HAL - Hardware 로의 접근이 가능하고 결과적으로 H/W통제를 진행할 있다.

 

 

2. HAL 유형 (Android 8.0 이상)

HAL 패스스루와 바인더 가지 유형이 존재하며 Android 8.0이상 출시된 단말의 경우 반드시 바인더 유형으로 진행해야 한다. 또한 HIDL언어를 통해 유형을 코딩할 있으며 Android 11버전이상에서는 AIDL 통해서 바인더 유형 HAL 작성이 가능하다.

 

HAL 개발 과정의 변천사를 보면... 기존에는 Legacy HAL 이용했으며 HIDL 통한 패스스루 그리고 HIDL 통한 바인더로 변화했으며 현재는 AIDL 통해서도 바인더화가 가능하도록 되었다.

 

1) 바인더

바인더란 프로세스 apk에서 다른 apk 함수 등을 호출할 별개의 apk 연결해주기 위한 도구이다. 이러한 바인더는 안드로이드에서 서로 다른 apk간의 통신에서 많이 사용하고 있으며 Android API에서 vendor HAL 연결하는데 역시 이러한 바인더를 이용한다.

 

여기서 패스스루 방식과 바인더 방식의 차이는 패스스루의 경우 같은 동일한 프로세스 내에서 클라이언트/서버를 만들고 주고받는 관계라면 바인더의 경우 다른 프로세스의 관계를 클라이언트/서버로 하여 data 주고받는 방식을 말한다.

 

현재 Android 11버전 기준으로 바이너가 하나 추가되어(AIDL 통해 HAL 연결하는 바인더) 3개의 바인더를 지원한다.

  • /dev/binder : AIDL 인터페이스를 통한 framework - App IPC
  • /dev/hwbinder : HIDL 통한 framework - vendor process IPC혹은 vendor process - vendor process 통신
  • /dev/vnbinder : AIDL 통한 vendor process - vendor process 간의 통신

 

2) 패스스루

동일한 프로세스내 서버/클라이언트를 두어 진행하는 방식으로 현재는 사용하지 않는다.(Android 8 OS upgrade되는 단말에 대해서만 지원한다)

 

 

3. HIDL

HIDL /dev/hwbinder 이용하며 프레임워크와 벤더사 프로세스 그리고 벤더사 프로세스간의 통신을 담당하는 인터페이스를 정의하기 위한 언어이다. HIDL 이용해 Binder함으로써 vendor 프로세스와의 통신을 가능하게 한다.

 

이는 jni 통한 HAL모듈과 같은 동작을 의미하며 HIDL언어를 통해 모듈과 연결 송수신을 있도록 진행한다.

 

기본적으로 HIDL 통해 작성한 .hal파일을 hidl-gen 통해 generate하고 이렇게 만들어진 .cpp, .h 파일 등을 구현하여 원하는 동작을 있도록 한다. 추가적으로 hal 인터페이스의 추가 제거 build 통하여 항상 결과물을 최신상태로 유지해주어야 한다.

 

HIDL 서버/클라이언트 구조로 되어있으며 클라이언트는 함수를 호출하는 입장 서버는 호출 신호를 수신하여 응답하는 역할로진행된다. 여기서 하나의 프로세스는 어떤프로세스와의 관계에서는 서버가되고 다른 어떤 프로세스와의 관계에서는 클라이언트가 있다.

그림에서와 같이 hidl-gen 통해 생성된 .h 헤더파일을 include함으로써 클라이언트/서버 부분을 각각 구현을 진행하면 된다.

 

실제로 서버 클라이언트 구조의 바인더 통신을 위해서는 각각 클라이언트 서버에 stub 존재한다. (결과적으로 서버/클라이언트는는 통신할 각각 stub 통해 상대편의 stub 요청을진행하는 것이다 마치 자신 소스코드내 포함된 함수를 호출하듯 동작을 위해 stub 이용)

이러한 stub동작 등을 지원하는 헤더파일이 BnHwFoo.h, BpHwFoo.h, iHwFoo.h 등이며 해당 헤더 파일들을 참조하는 헤더파일이 iFoo.h 것이다. 다만 여기서 개발자는 직접 BnHwFoo.h, BpHwFoo.h, iHwFoo.h include 통해 선언해서는 안되며 iFoo.h 선선해서 해당 함수들의 동작들을 사용하도록 규칙이 되어있다.

 

이렇게 서버/클라이언트 구현을 진행하고 결과적으로 패키지 android.hardware.samsple.Ifoo@1.0 공유 라이브러리에 포함시켜 사용할 있도록 한다. 이렇게 되면 공유 라이브러리를 통해 HIDL 작성된 /dev/hwbinder 사용할 있고 실제적으로 hw 접근 통제가 가능하다.

 

 

4. AIDL

안드로이드에서 기본적으로 여러 곳에서 내장되어 사용된 HIDL보다 오래된 안드로이드 언어로 안정성을 담보로 하고 있다. vendor 프로세스간의 통신에서 기존의 HIDL에서 추가적으로 Android 11버전부터 AIDL 지원한다.

 

해당 부분의 경우 HIDL 베이스로 작성된 코드에서 빌드 설정 등을 수정하여 AIDL 지원가능하도록 재빌드하여 사용가능하며 HIDL C++ 유사한 것과 달리 AIDL java 유사한 성격을 지니고 있다.

 

하지만 framework vendor 간의 통신은 미지원으로 해당 통신이 포함되는 경우에는 반드시 HIDL 작성해야 한다.

 

ref)

source.android.com/devices/architecture/hal-types?hl=ko

 

HAL 유형  |  Android 오픈소스 프로젝트  |  Android Open Source Project

 

+ Recent posts