第十五章_Android内核驱动——杂项

合集下载

往android的内核添加驱动及ueventd.rc修改

往android的内核添加驱动及ueventd.rc修改

往android的内核添加驱动及ueventd.rc修改向android的内核添加驱动,其实就是向linux内核添加驱动。

主要在两个文件里添加点信息,一个是Kconfig文件,一个是Makefile 文件。

比如你添加的驱动你代码放到drivers目录下面的XXX目录,那么修在该目录下的Kconfig文件和Makefile文件。

具体的修改方法:比如我现在修改drivers/staging/android/下的Kconfig文件。

config ANDROID_LOGGERtristate "Android log driver"default nconfig ANDROID_RAM_CONSOLEbool "Android RAM buffer console"default nconfig ANDROID_RAM_CONSOLE_ENABLE_VERBOSEbool "Enable verbose console messages on Android RAM console"default ydepends on ANDROID_RAM_CONSOLE如果我想添加一个驱动,驱动名字为 somedrv,那么在这个文件里加入:config ANDROID_DEMUXERbool "Android Somedrv Driver"default n这样就可以了。

这样在编译内核的时候,make menuconfig命令之后,会有Android Somedrv Driver的选择,选择它就可以将驱动编进内核。

然后在Makefile里面添加一句obj-$(CONFIG_ANDROID_SOMEDRV) += somedrv.o。

这样就修改好了。

这样编译内核的时候就把驱动编译进去了,前提编译前选择驱动。

现在我编译的内核都是用在模拟器上的,也就是说在qemu上运行内核。

android驱动开发介绍

android驱动开发介绍
向内核注册和注销一个块设备可使用如下函数: int register_blkdev(unsigned int major, const char *name); int unregister_blkdev(unsigned int major, const char *name);
• 网络设备驱动
• 二 Hal module Stub框架分析 每个硬件对象都由hw_module_t来描述,只要我们拿到了这个硬件对象,就可 以调用它的open方法,返回这个硬件对象的硬件操作接口,然后就可以通过 这些硬件操作接口来间接操作硬件。
• 模块管理(module management) • 虚拟文件系统接口(VFS layer) • 文件系统(file system) • 设备驱动程序(device driver) • 进程间通信(inter-process communication) • 网络管理(network management) • 系统启动(system init)
Stub是存根或者桩的意思,上层应用层或者框架层代码加载so库代码,so库代码我们称之为 module,在Hal层注册了每个硬件对象的存根stub,当上层需要访问硬件的时候,就从当前注 册的硬件对象stub里查找,找到之后stub会向上层module提供该硬件对象的operations interface(操作接口),该操作接口就保存在module中,上层应用或框架层再通过这个 module操作接口来访问硬件。 新的Stub框架虽然也要加载module库,但是这个module已经不包含操作底层硬件驱动的功能 了,它里面保存的只是底层stub提供的操作接口,底层stub扮演了“接口提供者”的角色, 当stub第一次被使用时加载到内存,后续再使用时仅返回硬件对象操作接口,不会存在设备 多次打开的问题。

Android 驱动

Android 驱动
Android 驱动
1
标准的Linux内核




Android的启动流从宏观上大致可以划分为 以下几个步骤: (1)上电,并执行相关的Boot ROM代码。 (2)启动引导加载程序Boot Loader。 (3)Linux内核启动并执行。 (4)Init进程启动并执行。 (5)Zygote和Dalvik虚拟机启动并执行。 (6)System Server启动并执行。
Zygote
System Server进程
Dalvik 虚拟机 Dalvik 虚拟机 虚拟内存 虚拟内存 Boot BootROM ROM 启动媒介 启动媒介 (NAND) (NAND) Boot Bootcode code Boot 引导 BootLoader Loader 引导 加载程序 加载程序 Kernel 内核 Kernel 内核 init init ServiceMan ServiceMan ager ager Zygote Zygote System System Server Server


Ashmem驱动创建了/dev/ashmem设备文件。 进程通过open打开该文件,用ioctl命令 ASHMEM_SET_NAME和ASHMEM_SET_SIZE 设置共享内存块的名字和大小,并将得到 的handle传给mmap,来获得共享的内存区 域,其他进程可以通过将相同的handle传给 mmap,获得同一块内存。 handle在进程间的传递可通过Binder来实现。
2
启动流程分析
Linux空间 BootLoader Android空间
Linux Kernel Init init.rc servicemanager Zygote SystemServer

Android驱动学习-app调用内核驱动过程(驱动框架回顾)

Android驱动学习-app调用内核驱动过程(驱动框架回顾)

Android驱动学习-app调⽤内核驱动过程(驱动框架回顾)考研已经过去了,android驱动的学习也断了半年多了,现在重新捡起来学习,回顾⼀下Android驱动的⼤体框架。

Android系统的核⼼是java,其有⼀个David虚拟机。

Android-app操作硬件也相当于是java操作硬件。

在Linux系统上操作硬件是通过open read write等来实现,也就是操作C库。

如果java能直接调⽤C库中的函数,也就解决了app操作硬件的问题。

下⾯的⽂章是java调⽤C/C++库的⽅法。

链接:1.⽅法1——jni调⽤底层驱动在android框架中写⼊c/c++直接调⽤底层linux驱动,并向上提供jni接⼝给应⽤程序:优点:简单易⾏;缺点:主要在于驱动,由于在linux中需要遵循GPL协议,需要开源,⽽许多⼚商的⼀些代码不希望开源。

⽽且像屏幕等设备可能需要多个app同时操作,这样的话将会导致各种各样的问题。

2.⽅法2——增加硬件抽象层将驱动程序⼀分为⼆,⼀部分开源在内核中,⼀部分不开源在android框架中:⼆、举例led android驱动:从这⾥我们将看到整个应⽤框架层到底层驱动的⾛向。

⾸先,⽆论是哪种⽅法,我们都需要实现⼀个linux驱动以供上层访问led资源。

同样也是通过jni来加载C库,从⽽通过调⽤open等来实现对硬件的操作。

Android为了实现多个APP能操作同⼀个硬件,硬件不由app来直接操作,⽽是有SystemServer来操作。

app需要把请求通过serviceManager发给SystemServer,由SystemServer最终完成对硬件的操作。

这⾥我们反过来思考⼀个app操作硬件的过程:1、app需要申请服务和获得服务getservice。

⽽这个服务是有接⼝完成的。

所以第⼀步我们需要建⽴⼀个aidl⽂件,来⽣成接⼝类。

frameworks/base/core/java/android/os/ILedService.aidl同时修改 frameworks/base/Android.mk,加⼊新建的aidl⽂件。

嵌入式linux(贺丹丹等编著)课后习题答案

嵌入式linux(贺丹丹等编著)课后习题答案

嵌入式linux(贺丹丹等编著)课后习题答案第八章一、填空题。

1、ARM-Linux内核的配置系统由三个部分组成,它们分别是Makefile、配置文件和配置工具。

2、配置工具一般包括配置命令解释器和配置用户界面,前者主要作用是对配置脚本中使用的配置命令进行解释;而后者则是提供基于字符界面、基于Ncurses图形界面以及基于X Window图形界面的用户配置界面。

3、Makefile文件主要包含注释、编译目标定义和适配段。

4、Linux内核常用的配置命令有make oldconfig、make config、make menuconfig和make xconfig。

其中以字符界面配置的命令是make config。

5、内核编译结束后,会在“/arch/arm/boot/”目录下面和根目录下面生成一个名为zImage的内核镜像文件。

二、选择题C AD D B三、叙述题1、Linux内核各个部分与内核源码的各个目录都是对应起来的,比如有关驱动的内容,内核中就都组织到“drive”这个目录中去,有关网络的代码都集中组织到“net”中。

当然,这里有的目录是包含多个部分的内容。

具体各个目录的内容组成如下:arch:arch目录包括了所有和体系结构相关的核心代码。

include:include 目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在include/linux 子目录下;init:init 目录包含核心的初始化代码(不是系统的引导代码),有main.c 和Version.c 两个文件;mm:mm 目录包含了所有的内存管理代码。

与具体硬件体系结构相关的内存管理代码位于arch/*/mm 目录下;drivers:drivers 目录中是系统中所有的设备驱动程序。

它又进一步划分成几类设备驱动,每一种有对应的子目录,如声卡的驱动对应于drivers/sound;ipc:ipc 目录包含了核心进程间的通信代码;modules:modules 目录存放了已建好的、可动态加载的模块;fs:fs 目录存放Linux 支持的文件系统代码。

android驱动开发和移植详解

android驱动开发和移植详解

android驱动开发和移植详解本文出处:《Android 底层开发技术实战详解——内核、移植和驱动》我们开发的Android 驱动程序是基于Linux 内核的,本文首先介绍移植Android 系统的基本知识和基本原理,这也是为驱动开发打下坚实基础,知其然也知其所以然;最后我们将通过深入浅出的案例学习驱动开发过程。

1.1 驱动开发需要做的工作Android 作为当前最流行的手机操作系统之一,受到了广大开发人员和商家的青睐。

Android正在逐渐形成一个蓬勃发展的产业,带来了无限商机。

既然Android 这么火爆,我们程序员可以学习它的哪一方面的内容呢?本书的驱动开发又属于哪一领域呢?接下来将为读者奉上这两个问题的答案。

Android 是一个开放的系统,这个系统的体积非常庞大,开发人员无须掌握整个Android 体系中的开发知识,只需熟悉其中某一个部分即可收获自己的未来。

从具体功能上划分,Android 开发主要分为如下三个领域。

1. 移植开发移动电话系统移植开发的目的是构建硬件系统,并且移植Android 的软件系统,最终形成手机产品。

2. Android 应用程序开发应用程序开发的目的是开发出各种Android 应用程序,然后将这些应用程序投入Android 市场,进行交易。

Android 的应用程序开发是Android 开发的另一个方面。

从开发的角度来看,这种形式的开发可以基于某个硬件系统,在没有硬件系统的情况下也可以基于Linux 或者Windows 下的Android模拟器来开发。

这种类型的开发工作在Android 系统的上层。

事实上,在Android 软件系统中,第3 个层次(Java 框架)和第4 个层次(Java 应用)之间的接口也就是Android 的系统接口(系统API)。

这个层次是标准的接口,所有的Android 应用程序都是基于这个层次的接口开发出来的。

Android 系统的第4 个层次就是一组内置的Android应用程序。

Android系统核心或驱动的开发之Androidrepo魔法

Android系统核心或驱动的开发之Androidrepo魔法

Android repo 魔法Android 为企业提供一个新的市场,无论大企业,小企业都是处于同一个起跑线上。

研究Android 尤其是Android 系统核心或者是驱动的开发,首先需要做的就是本地克隆建立一套Android 版本库管理机制。

Android 使用Git 作为代码管理工具,开发了Gerrit 进行代码审核以便更好的对代码进行集中式管理,还开发了Repo 命令行工具,对Git 部分命令封装,将百多个Git 库有效的进行组织。

要想克隆和管理这百多个Git 库,还真不是一件简单的事情。

在研究Repo 的过程中,发现很多文档在Google Group 上,非“翻墙”不可看。

非法的事情咱不干,直接阅读repo 的代码吧。

创建本地Android 版本库镜像的思路如果了解了Repo 的实现,参考《Using Repo and Git》 , 建立一个本地的android 版本库镜像还是不难的:∙下载repo bootstrap 脚本∙提供–mirror 参数调用repo init ,建立git 版本库克隆o使用–morror 则下一步和源同步的时候,本地按照源的版本库组织方式进行组织,否则会按照manifest.xml 指定的方式重新组织并检出到本地∙开始和源同步∙修改manifest ,修改git 库地址,指向本地的git 服务器o修改platform/manifest.git 库中现有的xml 文件,或者创建一个新的xml 文件o将git 的地址改为本地地址,提交并push∙本地repo 镜像建立完毕之后,就可以在执行repo init 时,使用本地更改后的manifest 库,之后执行repo sync 就是基于本地版本库进行同步了。

∙也可以改造repo,使得不必为repo 工具初始化,也在本地网络完成操作…Repo init 干了些什么?实际上,得到客户使用repo 的信息后,首先下载repo 执行脚本开始研究。

Android核心模块内容概述

Android核心模块内容概述

千锋3G嵌入式移动互联网技术研发中心 千锋 嵌入式移动互联网技术研发中心
音频驱动(Audio Driver):常用基于ALSA (Advanced Linux Sound Architecture,高级 Linux声音体系)驱动。 WiFi驱动(Camera Driver):基于IEEE 802.11 802.11标准的驱动程序 键盘驱动(KeyBoard Driver) 蓝牙驱动(Bluetooth Driver) Binder IPC驱动: Andoid一个特殊的驱动程 序,具有单独的设备节点,提供进程间通讯的功 能。 Power Managem网技术研发中心 千锋 嵌入式移动互联网技术研发中心
Android 的各种库一般是以系统中间件的形式提供的,它 们均有的一个显着特点就是与移动设备的平台的应用密切 相关。 Android 运行环境主要指的虚拟机技术——Dalvik。 Dalvik虚拟机和一般JAVA虚拟机(Java VM)不同,它执 行的不是JAVA标准的字节码(bytecode )而是Dalvik可 执行格式(.dex)中执行文件。在执行的过程中,每一个 应用程序即一个进程(Linux的一个Process)。 二者最 大的区别在于Java VM是以基于栈的虚拟机(Stackbased),而Dalvik是基于寄存器的虚拟机(Registerbased)。显然,后者最大的好处在于可以根据硬件实现 更大的优化,这更适合移动设备的特点。

千锋3G嵌入式移动互联网技术研发中心 千锋 嵌入式移动互联网技术研发中心
Android核心模块之应用程序框架 (Application Framework)
Android的应用程序框架为应用程序层的开发者提供 APIs,它实际上是一个应用程序的框架。由于上层的应用 程序是以JAVA构建的,因此本层次提供的首先包含了UI 程序中所需要的各种控件: 例如: Views (视图组件)包括 lists(列表), grids(栅格), ( ) lists( ), grids( ), text boxes(文本框), buttons(按钮)等。甚至一个嵌入式的 Web浏览器。 一个Andoid的应用程序可以利用应用程序框架中的以 下几个部分: Activity (活动) Broadcast Intent Receiver (广播意图接收者) Service (服务) Content Provider (内容提供者)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第十五章Android内核驱动——杂项15.1 日志系统基本原理Android的logger是一种轻量级的日志系统。

在内核中实现为一种misc设备驱动,它与用户态的logcat工具配合实现了方便的调试工具,开发应用程序的时候可以利用logger查看日志,进行跟踪调试。

logger的实现logger的源代码在drivers/staging/android/logger.c中,它用三个结构体logger_log,logger_reader和logger_entry来维护logger设备的信息。

其中logger_log代表一个log设备,logger_reader代表一个读日志的reader,logger_entry代表writer写入的一条日志。

logger在模块初始化时注册三个misc设备:log_main,log_events和log_radio。

其中log_main 记录主要的日志信息,log_events记录与事件有关的信息,log_radio记录与通信有关的信息,实现了以下的file operation:●logger_open标准的open接口,如果以读模式打开,则分配一个logger_reader,初始化其成员变量,并把这个logger_reader保存在file->private_data中。

如果是write模式打开,则直接把对应logger 设备的logger_log保存在file->private_data。

此后在读或者写的时候就可以通过file-> private_data找到对应的logger_reader或logger_log。

●logger_read首先当前进程(读log的进程)加到logger_log->wq等待队列上,判断当前日志buffer是否为空,如果空则调度别的进程运行,自己挂起(如果指定了非阻塞模式,则直接返回-EAGAIN),重复上述过程直buffer中有日志可读,此时,读出一条日志,拷贝到用户空间,返回。

●logger_aio_write写操作支持同步、异步以及scatter方式的写操作。

写操作几乎总是成功的,当buffer满的时候,新写入的日志会覆盖最初的日志。

总之,buffer是环形的,如果没有及时被读出,数据会丢失。

●logger_ioctl支持以下命令:⏹LOGGER_GET_LOG_BUF_SIZE:得到logger device 环形缓冲区的大小⏹LOGGER_GET_LOG_LEN:得到当前日志buffer 中未被读出的日志长度LOGGER_GET_NEXT_ENTRY_LEN:得到下一条日志长度(即紧接着上次读出的日志后面一条)⏹LOGGER_FLUSH_LOG:清空日志●logger_poll查询当前进程是否可以对logger device操作。

POLLOUT总是成立的,即进程总是可以写入日志。

但只有以FMODE_READ模式打开logger设备的进程,并且当前日志非空,才可以读到日志。

用户接口logger日志系统是标准的misc设备,提供标准的file operation,应用程序可以通过标准的C 库文件函数操作日志系统。

在Android应用开发中,比较有用的是logcat命令,通过该命令可以查看系统的日志输出,在调试的时候,应用程序插入日志,在logcat中就可以看到,这样就实现了方便的插桩跟踪调试。

logcat 的选项包括:-s 设置过滤器,例如指定'*:s'-f <filename> 输出到文件,默认情况是标准输出。

-r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires –f-n <count> Sets max number of rotated logs to <count>,default 4-v <format> 设置log 的打印格式,<format> 是下面的一种:brief process tag thread raw time threadtime long-c 清除所有log并退出-d 得到所有log 并退出(不阻塞)-g 得到环形缓冲区的大小并退出-b <buffer> 请求不同的环形缓冲区('main'(默认),'radio','events')-B 输出log 到二进制中过滤器的格式是一个这样的串:其中<tag>表示log的component,tag(或者使用* 表示所有),可以应用中定义,这样在用logcat查看日志的时候就可以指定这个tag,只查看这个tag的应用产生的日志。

priority如下所示:V VerboseD DebugI InfoW WarnE ErrorF FatalS Silent事实上logcat的功能是由Android的类android.util.Log决定的,在程序中log的使用方法如以上log的级别依次升高,DEBUG信息应当只存在于开发中,INFO,WARN,ERROR这三种log将出现在发布版本中。

15.2 Switch基本原理Switch是Android引进的新的驱动,目的是用于检测一些开关量,比如检测耳机插入、检测USB 设备插入等。

Switch在sysfs文件系统中创建相应entry,用户可以通过sysfs与之交互;此外还可以通过uevent机制与之交互,从而检测switch状态。

Switch的实现Switch class在Android中实现为一个module,可动态加载;而具体的switch gpio则是基于platform device框架。

代码在drivers\switch\switch_class.c和drivers\switch\switch_gpio.c中。

其中switch_class.c实现了一个switch class,而switch_gpio.c则是这个class中的一个device,即针对gpio的一个switch设备。

switch_class.c文件创建了一个switch_class,实现了内核的switch机制,提供支持函数供其他switch device驱动调用。

init函数调用create_switch_class->class_create创建switch_class设备类。

相对应exit则是销毁这个设备类。

该文件导出两个函数供其他switch设备驱动调用,分别是注册switch设备switch_dev_register 和注销switch_dev_unregister。

然后是两个sysfs操作函数(state_show和name_show),分别用于输出switch device的name 和state。

当用户读取sysfs中对应的switch entry(/sys/class/switch/<dev_name>/name和/sys/class/switch/<dev_name>/state)时候,系统会自动调用这两个函数向用户返回switch设备的名称和状态。

可见,这两个函数就是直接调用对应的switch_dev中的print_state和print_name函数;如果没有定义这两个函数,则调用sprintf把信息打印到buf缓冲区里。

最后是switch_set_state 函数,该函数是内核内部使用,并不为用户调用,它完成的功能主要是两件事:●调用name_show和state_show输出switch设备名称和状态至sysfs文件系统●发送uevent通知用户switch device的信息(名称和状态)switch_gpio.c文件基于switch class实现了一个gpio的switch设备驱动,其实现的原理如下:基于platform device/driver框架,在probe函数中完成初始化,包括获取gpio的使用权限,设置gpio方向为输入,注册switch_dev设备,为gpio分配中断,指定中断服务程序,初始化一个gpio_switch_work工作,最后读取gpio初始状态。

当GPIO 引脚状态发生变化时,则会触发中断,在中断服务程序中调用schedule_work,这个被schedule的work即前面初始化的gpio_switch_work,最后这个work被执行,在gpio_switch_work函数中读取当前gpio电平,调用switch_set_state更新sysfs并通过uevent 通知上层应用。

这个设备驱动只实现了print_state函数:switch_gpio_print_state,没有实现print_name函数。

当gpio_switch_work执行的时候,里面调用switch_set_state->switch_gpio_print_state输出GPIO状态到sysfs。

用户接口sysfs文件系统和uevent机制。

sysfs文件为sys/class/switch/<dev_name>/name,sys/class/switch/<dev_name>/state,uevent环境变量为SWITCH_NAME=<name>,SWITCH_STATE=<state>。

15.3 Timed GPIO基本原理Timed GPIO基于platform driver实现了一个增强的GPIO驱动。

与普通GPIO驱动不同的地方就是Timed GPIO将普通GPIO与内核定时器绑定在一起,实现了一种时钟控制的GPIO;当定时器过期后,GPIO的状态会设置为指定的状态。

Android的timed GPIO实际上实现的功能是:通过sysfs操作GPIO,比如可以让GPIO 输出高/低电平;但同时可以指定一个定时器过期时间。

到达过期时间后,执行一个callback 函数,可以重新设置GPIO的输出电平。

Timed GPIO的实现Timed GPIO代码在drivers/staging/android下,对应的文件为:timed_gpio.c,timed_gpio.h,timed_output.c,timed_output.h。

Timed GPIO驱动实现为platform driver,在其probe函数中,sysfs创建了相应的设备文件和class文件,应用程序可以通过设备文件实现与内核驱动的交互。

相关文档
最新文档