1 / 50

ANDROID 底层开发专题 1 Android 移植

ANDROID 底层开发专题 1 Android 移植. 刘健培 北京邮电大学 ljp020993@gmail.com 2013.05. 本次内容. Android 底层开发 专题 之 Android 移植 Android 移植概念 Android 移植流程 Android 移植示例. 参考资料. 源代码 Linux 源代码 Android 源代码 图书 Linux 设备驱动程序 Android 系统源代码情景分析 网站 Android on TI OMAP http://elinux.org/Android_on_OMAP

Download Presentation

ANDROID 底层开发专题 1 Android 移植

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ANDROID底层开发专题1Android移植 刘健培 北京邮电大学 ljp020993@gmail.com 2013.05

  2. 本次内容 • Android底层开发专题之Android移植 • Android移植概念 • Android移植流程 • Android移植示例

  3. 参考资料 • 源代码 • Linux源代码 • Android源代码 • 图书 • Linux设备驱动程序 • Android系统源代码情景分析 • 网站 • Android on TI OMAP • http://elinux.org/Android_on_OMAP • Android on X86 • http://www.android-x86.org/ • beagleboard主页: • http://beagleboard.org/ • Rowboat主页 • http://code.google.com/p/rowboat/ • 源代码在线阅读 • http://hala01.com/

  4. Android移植概念 • 将Android系统和Linux内核移植到特定硬件平台上,同时开发/移植必要的设备驱动、中间件与应用程序。 • 可“移植”的内容 • 底层平台程序(bootloader、Linux内核、设备驱动、HAL) • 本地库(如使用NDK或基于源代码) • 应用程序(如J2ME->Android)

  5. Android移植层次 • 从Android运行的硬件平台“从里往外”看: • 处理器内核架构级(Arch级) • 指令集ISA、编译器等有差异 • Android-x86(http://www.android-x86.org/) • Android-mips(http://developer.mips.com/android/) • 处理器芯片级(Soc级) • 总线、内部存储、SOC内部驱动等有差异 • Android on OMAP(http://elinux.org/Android_on_OMAP) • Android for MSM(https://www.codeaurora.org/projects/all-active-projects/android-msm) • Android on NVIDIA’s Tegra(https://developer.nvidia.com/tegra-android-development-pack) • 板级(Board级) • 外设配置(如数量、型号、使用方式等)、外设与SOC连接关系有差异 • Rowboat(http://code.google.com/p/rowboat/) • BeagleBoard(http://beagleboard.org/) • 产品设备级(Device级) • 硬件配置(如屏幕尺寸、有无特定硬件模块等)、语言环境、安装软件、主题外观、操作等有差异 • CyanogenMod(http://www.cyanogenmod.org/) • MIUI(http://www.miui.com/)

  6. Android移植流程 • 收集资料,决定移植目标 • 搭建移植开发环境 • 移植Bootloader • 移植Linux内核 • 移植Android系统/运行时环境 • 移植/开发设备驱动 • Android系统开发 • 开发/移植应用程序 • 调试与测试 • 集成与部署Android系统

  7. 收集资料,决定移植目标 • 资料 • 硬件资料 • 处理器平台架构 • 存储空间:RAM与ROM、大小与配置 • 外设配置 • 原理图与外设数据手册等 • 有没有相似的开发板 • 软件资料 • 可否有可以运行的bootloader、linux内核,版本如何 • 已经成功运行的设备驱动有多少 • 搜索处理器的官方资料: • 是否支持Android(如TI、MSM、NVIDIA的一些处理器都有Android开发环境) • 驱动等是以源代码还是二进制文件形式提供 • 是否有操作手册、移植指南等资料 • 搜索相似开发板: • 有没有能够运行Android的,如有,Linux内核版本、驱动如何(如一些第三方的开源移植项目) • 有没有类似的移植总结 • 决定 • Linux内核基线版本 • Android版本 • 支持的驱动情况

  8. 搭建移植开发环境 • 完善的开发环境(building environment)对项目的成功有极大的影响 • 本机开发:在主机系统上为其自身编译并构建应用的过程 • 交叉开发:在主机系统上编译并构建将在嵌入式目标系统上运行的应用的过程 • Linux交叉开发环境包括: • 主机linux操作系统环境(如UbuntuLinux系统) • 目标系统软件包:包括程序、实用程序和库 • 交叉工具链(编译器、汇编器、链接器等) • 主机工具:例如编辑器、调试器和实用程序 • 例如:Eclipse、vi、GDB、DDD、cscope、strace等追踪和程序分析工具、readelf/objdump/objcopy/nm等二进制实用程序 • 主机为目标机提供的服务 • 串口终端、TFTP、BOOTP/DHCP服务器、NFS服务器

  9. 建立交叉开发环境 Android移植环境建立方法 DIY:自己安装主机系统,并下载、配置、编译需要的组件 获取现成商业版的嵌入式Linux发行版 Linux软件包一般基于源代码发布 目的:linux版本众多,硬件平台、系统目录、函数库(为软件所依赖)等都有区别,为使为linux编写的软件能够运行于这些不同的平台,一般需要根据本地linux系统的特点进行配置、编译、安装 Linux上大多数软件是通过GNU make来编译的。 一般安装过程:apt-get/wget/rpm…(下载)— tar…(解压缩)./configure(配置)—make(编译)—make install(安装) Make功能:一个依赖性跟踪工具,它遵循一系列的规则以确定对一个大型项目中每个单独源文件必须执行的动作 Makefile规则

  10. Embedded Linux System简介 系统架构

  11. Embedded Linux System简介 启动流程 • 构建流程

  12. 移植Bootloader 功能 系统加电后运行的第一个软件 提供早期初始化代码,并负责初始化处理器和平台主板 并启动(定位、载入、提供操作系统启动参数和移交控制权)完整的操作系统 其余:验证操作系统映像、更新自身或操作系统、在多个操作系统间进行选择等。

  13. 移植Bootloader 软件运行需要硬件和软件资源,Bootloader需要的每种资源在使用前都必须进行初始化并完成资源分配 DRAM控制器 DRAM是内存资源,DRAM芯片需要专门的硬件控制权支持读写周期 Flash与RAM Bootloader要保存在非易失性存储器中(如Flash、磁盘等),但是常又要将自身载入到RAM中运行 映像复杂 需要按照与处理器启动顺序兼容的格式组织启动代码,这需要开发人员通过链接器描述文件(ld脚本)指定二进制映像 缺少执行上下文 高级语言程序需要预先建立执行环境(如:C程序调用需要用到堆栈,需要RAM存储临时变量;C库需要进行动态内存分配等) 启动时代码是放在非易失性存储器中的,也没有DRAM可用

  14. 移植Bootloader Linux常用bootloader U-Boot Lilo GRUB Bootloader生命周期 初始化硬件 设置UART 设置网口 设置USB 探测存储器 设置启动参数 内核硬件信息 波特率 跳转到linux kernel的首地址 消亡

  15. 移植Bootloader U-Boot移植要点 熟悉硬件电路板与处理器,确认U-Boot支持新开发的处理器和I/O设备 从U-Boot已经支持的开发板中,找出硬件配置(处理器—SOC—以太网接口等外围接口)最接近的 创建一个与开发板相关的目录,建立移植基线 增加、删除、修改源代码,并编译 修改makefile目标文件 修改处理器初始化代码 修改特定开发板初始化 调试 Jtag仿真器、GDB等

  16. 移植Linux kernel Linux kernel功能 进程管理 内存管理 系统调用 文件系统管理 设备驱动程序 Linux kernel特性 多进程与虚拟地址空间 内核空间与用户空间 文件系统VFS抽象 动态链接与模块化 系统调用接口

  17. 移植Linux kernel Linux kernel结构

  18. 移植Linux kernel 启动流程

  19. 移植Linux kernel 目标 先构建一个Pure Embedded Linux Kernel,接着建立Android Runtime System 步骤 移植Linux Kernel到目标平台 整合修改Android(android kernel patches、linux device driver、Android library、Android Framework、Android application) Android对Linux内核的要求 Recent (~2.6.23) Linux kernel with Thumb & MMU & EABI etc support 移植关键 消除“Android—Linux Kernel—硬件平台”3者之间的差别 Android基于Goldfish和某个特定硬件平台(如G1手机)编译,未必有当前硬件平台的支持 Pure Linux Kernel一般有当前硬件平台的支持,但缺少Android对Kernel的修改

  20. 移植Android运行时环境 移植Linux Kernel成功后,要整合修改Android部分:linux device driver、Android library、Android Framework、Android application 注意:尽可能以最少的修改、最少的side effects达到预期效果

  21. 开发设备驱动程序 Android设备驱动开发有2方面的含义: Linux kernel设备驱动的开发 Android HAL驱动的开发

  22. 开发linux设备驱动程序 基本目的 分离没有权限的用户应用程序和关键的内核资源(硬件和其他设备) 提供一致的统一应用程序接口 Linux驱动特性 可加载模块与动态链接 使用文件系统的设备节点将用户空间应用程序与设备驱动程序联系起来 字符设备文件 块设备文件 网络设备文件 devfs、sysfs、udev 设备驱动函数实现一致的open、read、write、close等功能

  23. 开发linux设备驱动程序

  24. 开发Android设备驱动程序 Android专用驱动 Ashmem:匿名共享内存驱动。通过这种内核的机制,可以为用户空间程序提供内存分配机制。 节点名称/dev/ashmem, 为用户空间程序提供内存分配机制,实现类似malloc的功能内核中代码路径: kernelmm/ashmeme.cC libutils库对其进行了封装:system/core/libcutils/ashmeme-*.c Logger:轻量级的log驱动。 三个设备节点:/dev/log/main, /dev/log/event, /dev/log/radio在内核中代码: kernel/drivers/misc/logger.c在用户空间logcat(system/core/logcat)调用Logger驱动 Binder:基于Openbinder系统的驱动,为Android平台提供IPC(进程间通信)支持,Android整个系统的运行依赖Binder驱动。 节点名称/dev/binder, 为用户程序提供IPC支持,是Android中的主要IPC方式用户空间的libutils工具库(framework/base/libs/utils)和Service Manager守护进程中调用Binder接口提供对整个系统的支持 Android Power Management(PM):电源管理模块。 Low Memrry Killer:在缺少内存的情况下,杀死进程。 Android PMEM:物理内存驱动。

  25. 开发Android设备驱动程序 Android使用的设备驱动 Framebuffer显示驱动对于嵌入式系统,Framebuffer通常作为LCD控制器驱动或者其他显示设备的驱动;FB是一个字符设备,通常其设备节点为/dev/fbX,但在Android中使用/dev/graphic/fb0,该设备节点由init进程自动创建,被libui库调用;FB驱动在用户空间多使用ioctl,mmap,write等文件系统接口进行操作,ioctl用于获得/设置信息,mmap可以将Framebuffer的内存映射到用户空间,write直接用写的方式输出显示内容 Event输入设备驱动Event驱动是通用的输入设备驱动,目前可支持鼠标,键盘,触摸屏等多种输入设备;Event设备在文件系统中的设备节点为:/dev/input/eventX,由init进程创建,公libui库使用;用户空间使用read,ioctl,poll等文件系统接口操作Event设备

  26. 开发Android设备驱动程序 V4L2 Camera & Video驱动V4L2驱动既可以支持视频捕获,也可以支持视频输出,但因为两者硬件结构相差很大,因此一个系统中的两种驱动程序需要分别实现;Android中没有直接使用V4L2驱动,而是通过Camera或者Overlay硬件抽象层来使用用户空间使用ioctl, mmap操作V4L2 OSS音频驱动Open Sound System是基于字符的音频驱动, 用户空间用ioctl/read/write操作/dev/mixer, /dev/dsp, /dev/xxx接口Android中没有直接使用OSS驱动,可基于OSS来实现Android Audio部分的硬件抽象层 ALSA音频驱动比OSS使用更方便的音频驱动,除了OSS原来的ioctl等原始接口外,ALSA还提供了函数库,以简化应用程序;建议使用用户空间的ALSA库接口,而不是直接操作ALSA驱动程序;Android中没有直接使用ALSA驱动,而是通过Android–>Audio硬件抽象层–>ALSA库–>ALSA驱动

  27. 开发Android设备驱动程序 MTD驱动Memory Technology Device,通常用于Linux中Flash驱动程序,包括字符设备(/dev/mtdX)和块设备(/dev/block/mtdblockXMTD驱动通常不在用户空间直接调用,而是用于构建文件系统,用户空间只需要使用文件系统即可 蓝牙驱动两部分:蓝牙协议 + 蓝牙控制器驱动;蓝牙协议部分:包括HCI接口,SCO模块,L2CAP模块,BNEP模块等蓝牙控制器驱动部分:为基于SDIO/UART/USB接口的蓝牙设备提供驱动 Wlan驱动用户空间使用标准的socket接口进行控制Wifi驱动在Android中一般编译成module的方式,通过应用程序设置开关进行加载和卸载

  28. 开发Android设备驱动程序 Framebuffer显示驱动举例

  29. 开发设备驱动程序 驱动开发的一些知识 会看原理图 时序电路基础 电平信号 电路图分析 时序图分析 会看器件datasheet 外围器件结构与中断 GPIO操作 会使用调试工具 仿真器 示波器、万用表等

  30. Android核心开发

  31. Android核心开发 Android系统启动过程 Android从Linux系统启动有4个步骤: 启动Service Manager,Native服务启动 Zygote进程启动,启动JavaVM System Server、Android 服务启动 HOME启动

  32. Android核心开发 组件一般结构 Java application Java framework Jni Lib.so

  33. Android核心开发 Surface系统

  34. Android核心开发 JNI JNI(Java Native Interface),JAVA本地接口。 它允许Java代码和其他语言写的代码进行交互。 JNI标准至少保证本地代码能工作在任何Java虚拟机实现下。

  35. Android Makefile & Build System Makefile文件用来告诉make命令需要怎么样的去编译和链接程序。在编译时,需要根据编译环境和编译目标选择编译工具、编译参数、安装哪些模块、构建目标所需的依赖性以及生成规则。 在Android中,主要的Makefile文件存在于build/core/目录下,它的表现形式为多个后缀为mk的文件组成,也称为build system。 Android build system是一个设计优秀的Framework,具有良好的扩展性: 增添子模块编译 多CPU架构 – ARM/PPC/X86 多语言编译 – C/C++/Java 多目标 – static lib/share lib/execute/Java/Java library 多发布版本

  36. Android Makefile & Build System Makefile的流程 初始化相关参数 侦测编译环境和目标环境 决定目标product 读取product 的配置 读取product 所指定的目标平台架构配置 选择toolchain 指定编译参数(*-.mk) 清除输出目录 设定/检查版本编号 读取所有BoardConfig.mk 文件 读取所有module 的配置 根据配置,产生必需的rule 产生image Android build system主要有两部分:配置部分、目标构建部分。

  37. Build system 配置部分 基于Android 产品的配置(product config):选择构建安装的运行程序 (user package) 设置target 等相关变量TARGET_ARCH, TARGET_OS, TARGET_BUILD_TYPE, TARGET_PREBUILT_TAG 根据编译环境设置host等相关变量 HOST_OS, HOST_ARCH, HOST_BUILD_TYPE, HOST_PREBUILT_TAG 编译target上运行程序所需的工具链及编译参数设置,如linux-arm-cc,cflag,include目录等。 编译host上运行程序所需的工具链及编译参数设置。

  38. Build system 目标构建部分 主要工作就是选择所需构建的目标,确定它们所需依赖的目标,然后根据规则来构建最终的目标。 要能方便的添加子模块 要支持多种编程语言、编译工具( host 端和target端),如C、C++、Java、Python、shell脚本等。 要支持不同种类的构建目标,有:可执行文件,static library, dynamic library,java library,java app等。

  39. 几个重要的mk文件 Android .mk module和package的配置文件,每个module/package的目录下都会有一个Android .mk。 AndroidProducts.mk 设定product 配置。product 即特定系统版本,透过编译不同product ,产生不同软体配置内容,安装不同的application target_<os>-.mk, host_-.mk and -.mk 针对选择的作业系统和CPU 架构,进行相关设定。 BoardConfig.mk 为product 主板做配置,像driver 选择、 设定。 buildspec.mk 位于source 根目录下,为进行编译进行额外配置。例如,可在此选择要产生的product 、平台、额外的module/package 等。 main.mk build/core/ 下,Build system的主流程文件。

  40. 开发/移植应用程序 开发应用程序 移植J2ME应用程序 移植C/C++应用程序

  41. 开发/移植应用程序 J2ME平台程序移植到Android 用户界面 Android的图形类和Sun Java ME有了很大的不同,导致了移植时出现很多需要自己去实现相关类,使最终程序的运行效率可能会受影响。真机没有出现的情况下通过开发板可以适当的测试出性能损失。 媒体播放 这部分在Android系统上有大幅的改变,官方推荐使用MediaPlayer播放类,该类支持mp3、mid、wav、mp4等常规媒体格式的播放,相比J2ME中提供的要灵活强大。

  42. 开发/移植应用程序 数据存储 Android平台附带SQLite数据库,和Sun J2ME中的Record Management System (RMS)相比在功能上有了很大的提升,同时在性能上也会有不俗的表现。 网络数据 Android平台的做法是import Sun中的I/O读写库InputStream这样的类,同时网络相关的仍然采用Sun的URLConnection类进行操作,基本上没有变化。

  43. 开发/移植应用程序 移植C/C++应用程序 使用Android NDK 一般流程 配置android NDK编译环境 获得待移植的C/C++项目源代码 根据要移植的目标平台configure源代码 根据NDK支持的特性,修改源代码和编译条件,如restrict关键字、STL库、异常等 编写android.mk编译文件 使用NDK-build编译源码,由于NDK使用的c库以及对一些语言特性的有限支持,一般会出现编译错误,须做相应修改 编译成功生成静态库或动态库(.so) 部署:用adb push把程序放到 虚拟机里;或者手动放到android根文件系统的库文件目录下,如/system/lib 运行,做相应修改

  44. 辅助技巧 • Init时设置设备权限 • 修改init.rc • 更改配置文件 • 设置文件系统属性

  45. 调试 • 查看进程 • 统计性能 • Dmesg • Android特殊调试命令 • printk • Logcat

  46. 兼容性测试 • Android兼容性 • CTS兼容性验证

  47. 集成与部署 • 制作SD卡 • 烧写FLASH

  48. 谢 谢!

More Related