Android系统驱动介绍android手机驱动「Android系统驱动介绍」
Android中内核的结构和标准的Linux 2.6内核是基本相同的,不过Android在其基础上增加了私有内容。Android在Linux内核中增加的主要是一些驱动程序,这些驱动程主要分为两种:Android专用驱动和Android使用的设备驱动。
Android专用驱动程序不是Linux的标准驱动,它们的作用是辅助系统运行,一般不操作实际硬件。
- Ashmem: 匿名共享内存驱动。
- Logger: 轻量级的log驱动。
- Binder驱动(Binder Driver): 基于OpenBinder驱动,为Android平台提供IPC(进程间通信)的支持。
- 电源管理(Android Power Management ): 轻量级的能源管理,基于Linux的能源管理,为嵌入式系统做了优化。
- Android Power Management: 定时器驱动,用于唤醒设备。
- Low Memory Killer: 在缺少内存的情况卜,杀死进程。
- Android PMFM: 物理内存驱动。
- U Gadget: U 驱动(基于 gaeget 框架)。
- Ram Console: 用于调试写入日志信息的设备。
- Time Device: 定时控制设备。
- Android Alarm: 硬件时钟。
下面将主要介绍Android专用驱动中最重要的3个驱动:
Ashmem:匿名共享内存驱动
Ashmem ( Anonymous Shared Memory ),即匿名共享内存,通过内核的机制,为用户空间程序提供分配内存的机制。
Ashmem设备节点名称为/dev/ashmem,主设备号为10 ( Misc Driver ),次设备号动态生成。
Ashmem的代码路径如下:
Logger:轻量级的log驱动
Android的Logger驱动程序为用户层程序提供log的支持,这个驱动作为一个工具来使用。
Logger有3个设备节点,分别为:/dev/log/main, /dev/log/event, /dev/log/radioo
主设备号为10 (Misc Driver),次设备号动态生成。
Logger驱动的代码路径如下:
在用户空间logcat程序调用Logger驱动: system/core/logcat/可执行程序。
Binder驱动(Binder Driver)
Android的Binder驱动程序为用户层程序提供IPC(进程间通信)支持,Android整个系统的运行依赖Binder驱动。
Binder设备节点名称为/dev/binder,主设备号为10 ( Misc Driver ),次设备号动态生成。
Binder的代码路径:
Android系统上层用户空间的libutil 工具库和ServiceManager守护进程都是调用Binder接口驱动提供对整个系统进程间通信功能的支持,它们的代码路径为:
Binder是Android中主要使用的IPC方式,通常需要按照模板定义相关的类,不需要直接调用Binde驱动程序的设备节点。
其它专用驱动
-
Android Power Management
一个基于标准 linux 电源管理的轻量级 Android 电源管理系统。
源码位置:
-
Low Memory Killer
它在用户空间中指定了一组内存临界值,当其中某个值与进程描述中的 oom_adj 值在同一范围时,该进程将被Kill掉(在parameters/adj中指定oome_adj 的最小值)。它与标准的Linux OOM机制类似,只是实现方法不同。
源码位置: -
Android PMEM
PMEM 主要作用就是向用户空间提供连续的物理内存区域。
① 让 GPU 或 VPU 缓冲区共享 CPU 核心。
② 用于 Android service 堆。
源码位置: -
U Gadget
基于标准 Linux U gaeget 驱动框架的设备驱动。
源码位置: -
Ram Console
为了提供调试功能,android 允许将调试日志信息写入这个设备,它是基于 RAM 的 buffer。
源码位置: -
Time Device
定时控制,提供了对设备进行定时控制的功能。
源码位置: -
Android Alarm
提供一个定时器,用于把设备从睡眠状态唤醒,同时它还提供了一个即使在设备睡眠时也会运行的时钟基准。
设备节点:
源码位置:
Android中常使用的设备主要有Framebuffer驱动、输入设备驱动、v412摄像头—视频驱动、OSS音频驱动、ALSA音频驱动、MTD驱动、蓝牙驱动、Wlan驱动等。
Framebuffe显示驱动
Framebuffer 驱动在 Linux 中是标准的显示设备的驱动。
- 对于 PC 系统,它是显卡的驱动 ;
- 对于嵌入式 SOC 处理器系统,它是 LCD 控制器或者其他显示控制器的驱动。
它是一个字符设备,在文件系统中设备节点通常是 /dev/fbx 。 每个系统可以有多个显示设备 ,依次用 /dev/fb0、/dev/fb l等来表示。在 Android 系统中主设备号为 29 ,次设备号递增生成。
Android 对 Framebuffer 驱动的使用方式是标准的,在 / dev / graphie / 中的 Framebuffer 设备节点由 init 进程自动创建,被 libui 库调用。Android 的 GUI 系统中 , 通过调用 Framebuffer 驱动的标准接口,实现显示设备的抽象。
代码路径:。
输入设备驱动
Android中的输入设备设备驱动主要包括:游戏杆(Joystick、鼠标(Mouse)和事件设备(Event)。
- 其中事件设备驱动程序是目前通用的程序,可支持键盘 、 鼠标、触摸屏等多种输入设备。 Input 驱动程序的主设备号是13 ,每一种Input设备从设备号占用5位 ,3种从设备号分配是 : 游戏杆 0~61 ; Mouse 鼠标33~62 ; Mice鼠标63 ; 事件设备64 ~ 95,各个具体的设备在misc 、touchscreen 、keyboard 等目录中。
- Event设备在用户空问使用read 、ioctl 、poll 等文件系统的接口操作,read 用于读取输入信息,ioctl 用于获取和设置信息,poll 用于用户空间的阻塞,当内核有按键等中断时,通过在中断中唤醒内核的 poll 实现。
输入设备驱动同样也是字符设备,这个输入设备驱动程序那是相当相当的复杂。在Android内核中主要需要关注以下儿个文件:
上面这些都不需我们去实现,内核已经帮我们实现好了,不过在写硬件驱动时需要和Inputcore交互,所以需要用到上面这些函数中的接口,也就是说上面这些函数是透明的。
V4L2摄像头—视频驱动
摄像头(Camera)——视频驱动驱动通常使用Video For Linux。
V4L2是V4L的升级版本,为linux下视频设备程序提供了一套接口规范。包括一套数据结构和底层V4L2驱动接口。V4L2提供了很多访问接口,可以根据具体需要选择操作方法。
注意:很少有驱动完全实现了所有的接口功能。所以在使用时需要参考驱动源码,或仔细阅读驱动提供者的使用说明。
V4L2的主设备号是81,次设备号:0~255,这些次设备号里也有好几种设备(视频设备、Radio设备、Teletext、VBI)。
- V4L2的设备节点: /dev/videoX, /dev/vbiX 和 /dev/radioX
- V4L2驱动主要头文件路径:
- V4L2驱动核心实现路径:。
V4L2框架图
OSS音频驱动
OSS(Open Sound System开放声音系统)是 linux 上最早出现的声卡驱动。OSS 由一套完整的内核驱动程序模块组成,可以为绝大多数声卡提供统一的编程接口。
OSS 是字符设备,主设备号14,主要包括下面几种设备文件:
它是声卡驱动程序提供的简单接口,它通常是一个只读文件,作用也只限于汇报声卡的当前状态。(用于检测声卡)
用于数字采样和数字录音的设备文件。对于音频编程很重要。实现模拟信号和数字信号的转换。
类似于/dev/dsp,使用的是 mu-law 编码方式。
用于多个信号组合或者叠加在一起,对于不同的声卡来说,其混音器的作用可能各不相同。
这个设备用来对声卡内建的波表合成器进行操作,或者对 MIDI 总线上的乐器进行控制。
OSS 驱动所涉及的文件主要包括:
MTD驱动
Flash驱动通常使用MTD ( Memory Technology Device内存技术设备)
MTD 驱动程序是 Linux 下专门为嵌入式环境开发的新一类驱动程序。Linux 下的 MTD 驱动程序接口被划分为用户模块和硬件模块:
- 用户模块
提供从用户空间直接使用的接口:原始字符访问、原始块访问、FTL (Flash Transition Layer)和JFS(Journaled File System)。 - 硬件模块
提供内存设备的物理访问,但不直接使用它们,二十通过上述的用户模块来访问。这些模块提供了闪存上读、写和擦除等操作的实现。
MTD的字符设备:,主设备号为90。
MTD的块设备:,主设备号为13。
MTD驱动程序头文件路径:。
MTD源代码路径:
MTD驱动工作原理如图所示:
MTD工作原理图
ALSA音频驱动
ALSA ( Advanced Linux Sound Architecture)即高级Linux声音体系。
高级 Linux 声音体系ALSA是为音频系统提供驱动 的Linux 内核组件,以替代原先的开发声音系统 OSS 。它是一个完全开放源代码的音频驱动程序集 ,除了像 OSS 那样提供一组内核驱动程序模块之外 ,ALSA 还专门为简化应用程序的编写提供相应的函数库,与 OSS 提供的基于 ioctl 等原始编程接口相比, ALSA 函数库使用起来要更加方便一些 。
利用该函数库,开发人员可以方便、快捷地开发出自己的应用程序,细节则留给函数库进行内部处理 。所以虽然 ALSA 也提供了类似于 OSS 的系统接口,但建议应用程序开发者使用音频函数库,而不是直接调用驱动函数。
ALSA 驱动的主设备号为 116 ,次设备号由各个设备单独定义,主要的设备节点如下:
在用户空间中 , ALSA 驱动通常配合 ALSA 库使用,库通过 ioctl 等接口调用 ALSA 驱动程序的设备节点。对于 AIJSA 驱动的调用,调用的是用户空间的 ALsA 库的接口,而不是直接调用 ALSA 驱动程序。
- ALSA驱动程序的头文件:
- ALSA驱动程序的核心实现:
ALSA 音频驱动的架构如下图所示:
ALSA系统架构图
蓝牙驱动
在Linux中,蓝牙设备驱动是网络设备,使用网络接口。
Android 的蓝牙协议栈使用BlueZ实现来对GAP, SDP以及RFCOMM等应用规范的支持,并获得了SIG认证。由于Bluez使用GPL授权, 所以Android 框架通过D-BUS IPC来与bluez的用户空间代码交互以避免使用未经授权的代码。
- 蓝牙设备的网络协议:协议族AF BLUETOOTH ( 31) 。
- 蓝牙协议部分头文件:
- 蓝牙协议源代码文件:
- 蓝牙驱动程序部分的文件::
WLAN驱动
在Linux中,WLAN设备驱动是网络设备,使用网络接口。WLAN在用户空间使用标准的Socket接口进行控制。
- WiFi协议部分头文件:
- WiFi协议部分源文件:
- WiFi驱动程序部分:
驱动开发是Android开发系统中最底层的应用,属于Linux内核层的工作,因为驱动是系统和硬件之间的载体,涉及了不同硬件的应用问题,所以需要做系统移植的工作。
Android移植的任务
Android移植开发的最终目的是为了开发手机产品,从开发者的角度来看,这种类型的开发以具有硬件系统为前提,在硬件系统的基础上构建Android软件系统,这种类型的开发工作在Android系统的底层。在软件系统方面,主要工作集中在如下两个方面:
- Linux中的相关设备驱动程序
驱动程序是硬件和上层软件的接口,在Android手机系统中,需要基本的屏幕、触摸屏、键盘等驱动程序,以及音频、摄像头、电话的Modem,HIFi、蓝牙等多种设备驱动程序。 - Android本地框架中的硬件抽象层
在Android中,硬件抽象层工作在用户空间,介于驱动程序和Android系统之间。Android系统对硬件抽象层通常都有标准的接口定义,在开发过程中,实现这些接口也就给Android系统提供了硬件抽象层。
上述两个部分相互结合,共同完成了Android系统的软件移植。移植成功与否取决于驱动程序的品质和对Android硬件抽象层接口的理解程度。Android移植开发的工作由核心库、Dalvik虚拟机、硬件抽象层、Linux内核层和硬件系统协同完成,具体结构如图:
Android移植结构图
Android移植的内容
在移植过程中主要移植驱动方面的内容,具体来说,Android的移植主要分为下面的几个类型:
- 基本图形用户界面(GUI)部分:包括显示部分、用户输入部分和硬件相关的加速部分,还包括媒体编解码和OpenGL等,还包括媒体编解码和OpenGL等。
- 音视频输入输出部分:包括音频、视频输出和摄像头等。
- 连接部分:包括无线局域网、蓝牙、GPS等。
- 电话部分:包括通话、G等。
- 附属部件:包括传感器、背光、振动器等。
具体需要移植的内容如下所示:
① Display显示部分: 包括FrameBuffer驱动和Gralloc模块。
② Input用户输入部分: 包括Event驱动和EventHube
③ Codec多媒体编解码: 包括硬件Codec驱动和Codec插件,例如OpenMax o
④ 3D Accelerator ( 3D加速器)部分: 包括硬件OpenGL驱动和OpenGL插件。
⑤ Audi音频部分: 包括Audi、驱动和Audi、硬件抽象层。
⑥ Video Out视频输出部分: 包括视频显示驱动和Overlay硬件抽象层。
⑦ Camera摄像头部分: 包括Camera驱动(通常是v412)和Camera硬件抽象层。
⑧ Phone电话部分: 包括Modem驱动程序和RIL库。
⑨ GPS全球定位系统部分: 包括GPS驱动(例如串口)和GPS硬件抽象层。
⑩ Wi-Fi无线局域网部分: 包括Wlan驱动和协议以及Wi-Fi的适配层。
⑪ Blue Tooth蓝牙部分: 包括BT驱动和协议以及BT的适配层。
⑫ Sensor传感器部分: 包括Sensor驱动以及Sensor硬件抽象层。
⑬ Vibrator震动器部分: 包括Vibrator驱动和Vibrator硬件抽象层。
⑭ Light背光部分: 包括Light驱动和Light硬件抽象层。
⑮ Alarm警告器部分: 包括Alarm驱动和RTC系统以及用户空间调用。
⑯ Battery电池部分: 包括电池部分驱动和电池的硬件抽象层。
Android系统有很多组件,但并不是每一个部件都需要移植,例如浏览器引擎虽然需要下层的网络支持,但实际上并不需要直接为其移植网络接口,而是通过无线局域网或者电话系统数据连接来完成标准的网络接口,所以就不需要移植。
驱动开发要做的工作
驱动开发的任务是,为某一个将要在Android系统上使用的硬件开发一个驱动程序。因为Android是基于Linux的,所以开发Android驱动其实就是开发Linux驱动。
对于大部分子系统来说,硬件抽象层和驱动程序都需要根据实际系统的情况来实现,例如传感器部分、音频部分、视频部分、摄像头部分和电话部分。另外也有一些子系统的硬件抽象层是标准的,只需要实现Linux内核中的驱动程序即可,例如输入部分、振动器部分、无线局域网部分和蓝牙部分等。对于有标准的硬件抽象层的系统,有的时候通常也需要做一些配置工作。
随着Android系统的更新和发展,它已经不仅仅是一个移动设备的平台,而且可以用于消费类电子和智能家电,例如从3.0以后的版本主要是针对平板电脑的,另外电子书、数字电视、机顶盒、固定电话等都逐渐使用Android系统。
在这些平台上,通常需要实现比移动设备更少的部件。一般来说,包括显示和用户输入的基本用户界面部分是需要移植的,其他部分是可选的。例如电话系统、振动器、背光、传感器等一般不需要在非移动设备系统来实现,一些固定位置设备通常不需要实现GPS系统。
Android内核是基于Linux 2.6内核的,这是一个增强内核版本,除了修改部分Bug外,还提供了用于支持Android平台的设备驱动。Android不但使用了Linux内核的基本功能,而且对Linux进行了改造,以实现更为强大的通信功能。
Android构建Linux系统
如果以一个原始的Linux操作系统为基础,将其改造成为一个适合于Android的系统所做的工作其实非常简单,就是增加适用于Android的驱动程序。在Android中有很多Linux系统的驱动程序,将这些驱动程序移植到新系统非常简单,具体来说有以下三个步骤。
① 编写新的源代码。
② 在KConfig配置文件中增加新内容。
③ 在Makefile中增加新内容。
在Android系统中,最常用的驱动程序有FrameBuffer驱动、Event驱动、Flash MTD驱动、WiFi驱动、蓝牙驱动和串口等驱动程序,并且还需要音频、视频、传感器等驱动和sysfs接口。所以说移植的过程就是移植上述驱动的过程,底层程序员的工作是在Linux下开发适用于Android的驱动程序,并移植到Android系统。
在Android中添加扩展驱动程序的基本步骤介绍如下:
① 在Linux内核中移植硬件驱动程序,实现系统调用接口;
② 把硬件驱动程序的调用在HAL中封装成Stub;
③ 为上层应用的服务实现本地库,由Dalvik虚拟机调用本地库来完成上层Java代码的实现;
④ 最后编写Android应用程序,提供Android应用服务和用户操作界面。
Android中的Linux内核和设备驱动结构
HAL层又被称为硬件抽象层,HAL在Android体系中有着深远的意义,因为Android是开放的而不是开源的原因就是在这一层上。因为HAL层的代码没有开源,所以Google将硬件厂商的驱动程序放在HAL层。也正是这个原因,所以Android被Linux家族删除。
Android HAL定义和概述
HAL层(硬件抽象层)是位于操作系统内核与硬件电路之间的接口层,其目的在于将硬件抽象化。它隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性,这样就可以在多种平台上进行移植。
从软硬件测试的角度来看,软硬件的测试工作都可分别基于硬件抽象层来完成,从此使软硬件测试工作的并行进行成为可能。HAL层的位置结构如图所示。
HAL层结构
由上图可以看出,HAL的功能是把Android Framework< Android框架)与Linux内核隔离。这样做的目的是让Android不过度依赖Linux Kemel,从而让Android Framework开发可以在不考虑驱动程序的前提下进行。在HAL层主要包含了GPS, Vibrator, Wi-Fi, Copybit, Audio,Camera, Lights, Ril, Overlay等模块。
Android HAL层的分类和结构
Android HAL层的分类,Android硬件抽象层可以分为如下六种HAL :
- 上层软件
- 内部以太网
- 内部通信CLIENT
- 用户接入口
- 虚拟驱动,设置管理模块
- 内部通信SERVER
定义硬件抽象层接口的代码具有以下五个特点:
- 硬件抽象层具有与硬件的密切相关性。
- 硬件抽象层具有与操作系统无关性。
- 接口定义的功能应包含硬件或系统所需硬件支持的所有功能。
- 接口定义简单明了,太多接口函数会增加软件模拟的复杂性。
- 具有可测性的接口设计有利于系统的软硬件测试和集成。
Android HAL层的目录结构,在Android源码中,HAL主要被保存在下面的目录中:
- : 过去的目录,采取了链接库模块观念来架构。
- : 新版的目录,被调整为用I-3AL stub观念来架构。
- : 是Radio接口层。
- :和QUAL平台相关的信息。
当然Android的HAL层仍旧散布在不同的地方,例如分为Camera, Wi-Fi等,因此上述的目录并不包含所有的HAL程序代码。在HAL架构成熟前的结构如左图所示,现在HAL层的结构如图所示:
HAL架构成熟前的结构 HAL架构成熟后的结构
从现在HAL层的结构可以看出,当前的HAL stub模式是一种代理(proxy)的概念,虽然stub仍以“.so”档的形式存在,但是HAL已经将“.so”档隐藏了。Stub向HAL提供了功能强大的操作函数(operation ),而runtime则从HAL获取特定模块(stub)的函数,然后再回调这些操作函数。这种以Indirect Function Call模式的架构,让HAL stub变成了一种“包含”关系,也就是说在HAL里包含了许多stub(模块)。Runtime只要说明module ID(类型)就可以取得操作函数。
在当前的HAL模式中,Android定义了HAL层结构框架,这样通过接口访问硬件时就形成了统一的调用方式。
HAL_legacy和HAL的比较
- HAL_legacy:这是过去HAL的模块,采用共享库形式,在编译时会调用到。由于采用function call形式来调用,因此可被多个进程使用,但会被映射到多个进程空间中造成浪费,同时需要考虑代码能否安全重入的问题(thread safe )。
- HAL:这是新式的HAL,采用了HAI module和HAI stub结合形式。HAL stub不是一个共享库,在编译时上层只拥有访问HAL stub的函数指针,并不需要HAL stub。在上层通过HAL module提供的统一接口获取并操作HAL stub,所以文件只会被映射到一个进程,而不会存在重复映射和重入问题。
HAL层的调用
重要的结构体
在HAL module中主要有如下三个结构:
- struct hw_module_t
hw_module_t 结构体是通用模块结构体,是具体模块的一个基类,如果你要实现类似音频、相机等模块就需要继承这个通用模块,对应的结构为:
- struct hw_module_methods t
hw_module_methods_t 结构体定义一个打开具体设备的函数open ,结构为:
- struct hw_device_t
hw_device_t 结构体是通用设备结构体,上层找到对应模块之后需要定位具体设备,一个模块可以有多个设备(根据device id来区别),上面的open函数就是去初始化这个设备的各个参数的,具体结构为:
HAL_MODULE_INFO_SYM是定义具体模块的结构体变量,结构体内部是一个hw_module_t结构体,这种包含关系可以理解为,具体模块继承通用模块hw_module_t结构体
这三个结构体之间的关系为:
三种结构之间的关系
HAL调用(Android 中实现调用 HAL 是通过 hw_get_module 实现的)
函数hw_get_module()能够根据模块ID寻找硬件模块动态链接库的地址,然后调用load打开动态链接库从中获取硬件模块结构体地址。
执行后首先是根据固定的符号HAL_MODULE_INFO_SYM寻找到hw module t结构体,然后是在hw_moule_t中hw_module_ methods_t结构体成员函数提供的结构open打开相应的模块,并同时进行初始化操作。因为用户在调用open()时通常会传入一个指向hw device t指针的指针。这样函数open()将对模块的操作函数结构保存到结构体hw_device_t中,用户通过它可以和模块进行交互。
① Native code通过hw_get_module调用获取HAL stub:
② 通过继承hw_module_methods_t的callback来 open设备:
图木舒克版权声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕,E-mail:xinmeigg88@163.com