'porting'에 해당되는 글 2건

  1. 2013.06.18 Porting Android to Devices
  2. 2007.11.06 uC/OS-II를 linux에 porting하기

Porting Android to Devices

Android 2013. 6. 18. 10:06

안드로이드 포팅하기

안드로이드는 개발자(you를 뭐라고 써야 하나..)에게 디바이스 드라이버를 자유롭게 구현할 수 있도록 해준다.  HAL (하드웨어 추상화 계층)은 안드로이드 플랫폼 스택과 개발자의 하드웨어를 연결할 수 있는 표준화된 방법을 제공한다.  추가로, 안드로이드 OS는 오픈소스이기 때문에 개발자가 자신의 device를 bringup하는데 도움이 된다.

Android provides you with the freedom to implement your own device specifications and the drivers to support them. The hardware abstraction layer (HAL) gives you a standard way to create software hooks in between the Android platform stack and your hardware. In addition, the Android operating system is open-sourced to help you through your device's bringup.

개발자는 사용자에게 일관된 인터페이스를 제공하고 높은 수준의 품질을 유지하기 위해서 CTS (호환성 테스트 수트)를 반드시 패스하여야 한다.  CTS는 누가 디바이스를 만들어도 안정적으로 동작할만한 표준화된 품질을 보장한다.  자세한 사항은 "호환성" 섹션을 참고한다.

To ensure that your devices maintain a high level of quality and offers a consistent experience for your users, they must must also pass the tests in the compatibility test suite (CTS). CTS ensures that anyone building a device meets a quality standard that ensures apps run reliabaly well and gives users a good experience. For more information, see the Compatibility section.

Android Low-Level System Architecture


개발자가 하드웨어에 안드로이드를 포팅하기 전에 안드로이드가 high level에서 어떻게 동작하는지 이해하고 있는 것이 중요하다.  왜냐하면 드라이버와 HAL은 안드로이드의 많은 계층과 상호작용을 하고, 이것에 대한 이해는 어떻게 AOSP의 많은 계층을 뚫고 자신의 길을 찾아야할지 도와주기 때문이다.  아래의 다이어그램은 안드로이드가 어떻게 동작하는지를 system level 관점에서 보여준다:

Before you begin porting Android to your hardware, it is important to have an understanding of how Android works at a high level. Because your drivers and HAL code interact with many layers of Android code, this understanding can help you find your way through the many layers of code that are available to you through the AOSP (Android Open Source Project) source tree. The following diagram shows a system level view of how Android works:

Figure 1. Android System Architecture

Application framework

많은 어플리케이션 개발자들이 신경을 쓰는 계층(맞나?)이다.  개발자는 API들이 HAL 인터페이스의  아래와 1:1로 매핑될 수 있으며 드라이버를 어떻게 구현하는지에 대한 것과 같은 정보를 제공하는 것을 알고 있어야 한다.

This is the level that most application developers concern themselves with. You should be aware of the APIs available to developers as many of them map 1:1 to the underlying HAL interfaces and can provide information as to how to implement your driver.

Binder IPC

바인더 IPC (프로세스간 통신) 기법은 어플리케이션 프레임워크가 프로세스 경계를 가로지르는 것과 안드로이드 시스템 서비스들의 코드를 호출하는 것을 가능하게 한다.  이것은 기본적으로 high level 프레임워크 API들이 안드로이드의 시스템 서비스들과 상호작용하도록 해준다.  어플리케이션 프레임워크 level에서 이러한 모든 통신은 개발자에게 보이지 않고, 단순히 동작하는 것처럼 보여지도록 한다.

The Binder Inter-Process Communication mechanism allows the application framework to cross process boundaries and call into the Android system services code. This basically allows high level framework APIs to interact with Android's system services. At the application framework level, all of this communication is hidden from the developer and things appear to "just work."

System services

어플리케이션 프레임워크 API들을 통해 보여지는 대다수의 기능들은 하드웨어 아래부분에 접근하기 위해 몇몇 시스템 서비스와 통신해야만 한다.  서비스들은 윈도우 매니저, 검색 서비스 또는 알림 매니저와 같이 주요한 기능들로 나누어진다.  시스템 서비스들은 시스템과 미디어 2가지 그룹으로 분류된다.  시스템 서비스들은 윈도우와 알림 매니저 같은 것들을 포함한다.  미디어 서비스들은 미디어의 재생과 기록(녹화라고 쓰려고 했으나 녹음이나 캡춰도 이에 포함될 것으로 생각되기에)에 수반되는 모든 것을 포함한다.

Most of the functionality exposed through the application framework APIs must communicate with some sort of system service to access the underlying hardware. Services are divided into modular components with focused functionality such as the Window Manager, Search Service, or Notification Manager. System services are grouped into two buckets: system and media. The system services include things such as the Window or Notification Manager. The media services include all the services involved in playing and recording media.

Hardware abstraction layer (HAL)

HAL은 드라이버와 하드웨어의 아랫단 구현부(...)를 전혀 모르더라도(agnostic이 문외한 정도로 해석되는 듯) 안드로이드 시스템이 디바이스 드라이버 계층을 호출할 수 있도록 해주는 표준화된 인터페이스를 제공한다.  개발자는 제품이 제공하는 하드웨어의 특정한 부분들을 위해 HAL (그리고 드라이버)에 일치하도록 구현해야 한다.  안드로이드는 디바이스 드라이버와 HAL 구현부간에 표준화된 방법을 강제하지 않기 때문에 개발자는 자신의 상황에 맞추어 구현할 수 있다.  하지만, 안드로이드 시스템이 하드웨어와 정확히 상호작용하기 위해 각 하드웨어에 특화된 HAL 인터페이스는 준수해야 한다.  HAL 구현부는 통상적으로 공유 라이브러리 모듈(.so 파일)로 포함된다.

The HAL serves as a standard interface that allows the Android system to call into the device driver layer while being agnostic about the lower-level implementations of your drivers and hardware. You must implement the corresponding HAL (and driver) for the particular piece of hardware that your product provides. Android does not mandate a standard interaction between your HAL implementation and your device drivers, so you have free reign to do what is best for your situation. However, you must abide by the contract defined in each hardware-specific HAL interface for the Android system to be able to correctly interact with your hardware. HAL implementations are typically built into shared library modules (.so files).

Linux Kernel

개발중인 디바이스 드라이버는 보통 리눅스의 디바이스 드라이버와 같은 경우가 대부분이다.  안드로이드는 wakelocks, 메모리 보존에 좀더 적극적인 메모리 매니저(Low Memory Killer를 말하는 것 같음), 바인더 IPC 드라이버, 그리고 안드로이드와 같은 모바일 임베디드 플랫폼에 중요한 다른 기능들이 추가된 특화된 버전의 리눅스를 사용한다.  이 추가기능들은 시스템의 기능보다 드라이버 개발에 더 관련이 없다.  개발자는 바인더 드라이버와 같이 필요한 기능들이 지원되는 동안에는 아무 버전의 커널을 사용할 수 있다.  하지만, 우리(구글)는 가장 최신 버전의 안드로이드 커널을 사용할 것을 권장한다.  최신 안드로이드 커널을 알고 싶다면, "커널 빌드하기"를 참조한다.

For the most part, developing your device drivers is the same as developing a typical Linux device driver. Android uses a specialized version of the Linux kernel with a few special additions such as wakelocks, a memory management system that is more agressive in preserving memory, the Binder IPC driver, and other features that are important for a mobile embedded platform like Android. These additions have less to do with driver development than with the system's functionality. You can use any version of the kernel that you want as long as it supports the required features, such as the binder driver. However, we recommend using the latest version of the Android kernel. For the latest Android kernel, see Building Kernels.

원문 : http://source.android.com/devices/index.html

Posted by 강군님

댓글을 달아 주세요

처음에 uC/OS-II를 실습할 때 (그러니까 uC/OS-II 실시간 커널 책을 사고 그안에 있던 예제를 돌려볼 때) windows에서 command창을 띄워서했었는데, 이건 문제가 있다고 생각이 들었다 (그냥 -_-;;)

앞으로 REBIS2440 board에 porting할 계획도 있고하니, 시험삼아 우선 linux에 porting하기로 하였다. 다행히도 인터넷에 자료도 많아서 금방되었다. 하지만 약간 수정을 가했기 때문에... 나중에 행해질 약간의 삽질을 피하고자... 정리를...

uC/OS-II를 컴파일 할 때에는 3가지 요소가 필요하다. 그 요소는 다음과 같다.

1. 프로세서 독립 코드 (Processor independent code)

이것들은 CD에 들어있는 11개의 파일들로써 os_core.c, os_flag.c, os_mbox.c, os_mem.c, os_mutex.c, os_q.c, os_sem.c, os_task.c, os_time.c, ucos_ii.c, ucos_ii.h이다.

2. 프로세서 의존 코드 (Processor dependent code)

말 그대로 프로세서마다 달라야 하는 코드로, uC/OS-II의 홈페이지(http://www.micrium.com/)에서 제공받을 수 있는데, 여기서 사용할 80x86의 코드는 http://www.it.fht-esslingen.de/~zimmerma/software/index_uk.html 에서 다운로드받을 수 있다. 여기서 받은 아카이브에서 4개의 파일을 사용한다. (os_cpu.h, os_cpu_c.c, pc.c, pc.h)

3. 응용프로그램 의존 헤더 (Application dependent header)

uC/OS-II는 각각의 응용프로그램마다 물론 code가 틀리겠지만, includes.h, os_cfg.h 역시 틀려진다. 이 헤더를 어떻게 정의하느냐에 따라서 uC/OS-II가 동작하는 방식이 틀려진다. 이것은 차후에 다루도록 하겠다.

여기서는 위의 홈페이지에서 받은 80x86의 코드중에서 첫번째 예제(example0)을 사용하도록 하겠다.

example0 디렉토리에 있는 파일들을 복사한 곳에서 Makefile을 다음과 같이 작성한다.

UCOS_SRC=Processor에 독립적인 파일이 있는 디렉토리 지정

UCOS_PORT_SRC=Processor에 의존적인 파일이 있는 디렉토리 지정

all:
        gcc -w -D__LINUX__ -I$(UCOS_SRC) -I$(UCOS_PORT_SRC) -I. \
        $(UCOS_SRC)/ucos_ii.c \
        $(UCOS_PORT_SRC)/os_cpu_c.c $(UCOS_PORT_SRC)/pc.c \
        -o test test.c

clean:
        rm -rf test

Processor에 독립적인 파일들 중에 ucos_ii.c만 컴파일 하는 것이 이상할 수도 있지만, ucos_ii.c의 내부에 다른 파일들을 include하여 컴파일 하게 되어있으니 신경쓸 필요는 없다. 다만 지금 이야기한 것 처럼 ucos_ii.c 내부에서 다른 code들을 include하는 곳을 수정해주어야 한다.

모든 것이 끝났으면, 쉘 프롬프트에서 make를 수행한다.

$ make

정상적으로 컴파일이 되었으면 test라는 이름의 ELF 파일이 생겼을 것이고, 이것을 실행함으로써 uC/OS-II가 에뮬레이트 된다.

Microprocessor에 porting하지 않고 이처럼 linux에 porting을 하게 되면, 여러가지 제약사항이 따르는데, 첨부된 문서를 참고하도록 한다.
Posted by 강군님

댓글을 달아 주세요