Android驱动开发权威指南(txt+pdf+epub+mobi电子书下载)

您所在的位置:网站首页 安卓驱动开发入门教程 Android驱动开发权威指南(txt+pdf+epub+mobi电子书下载)

Android驱动开发权威指南(txt+pdf+epub+mobi电子书下载)

2023-10-22 21:25| 来源: 网络整理| 查看: 265

Android驱动开发权威指南(txt+pdf+epub+mobi电子书下载)

发布时间:2021-06-24 14:03:24

点击下载

作者:杨柳

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Android驱动开发权威指南Android驱动开发权威指南试读:

前言

目前关于Android开发的书籍比较多,但大多数或立足于Android的上层,讲解如何开发Android应用,或偏重于Android Framework的繁杂机制,而缺乏讲述Android驱动及具体实践的书籍。由于工作的原因,本人正在根据多年Linux与Android驱动开发的经验,整理相关的新员工培训材料。为此,应张国强先生相邀,把相关资料整理成册,以飨读者,希望能让读者对Android有更深、更全面的理解,期待对从事Android驱动开发的工程人员的实际工作有所帮助。

我们知道Android底层是基于Linux内核的,因此要基于Android开发智能手机或终端,就少不了Linux内核与底层驱动的开发。据了解,这方面的开发人员目前还很缺乏,其中一个重要的原因就是Linux是一个与Windows一样复杂的软件系统,要理解它,本身不是一件容易的事,因此许多感兴趣的读者在翻阅相关书籍之后就知难而退了。根据个人的工作经验,Linux内核和底层驱动的开发其实并没有想象中的那么难,大概是相关书籍首先就讲进程调度、信号同步等复杂技术,让读者立刻坠入云里雾里,特别是若没弄明白设备驱动的本质,当真正讲到相关驱动开发技术时,心气已去了大半,更不用谈利用所学的知识进行实践了。

因此,我们在讲述相关驱动开发基础知识前,先让大家初步了解Linux内核,再着手讲设备输入/输出(I/O),接着由设备I/O引入DMA与中断处理,再讲驱动的并发处理技术,最后才讲设备驱动向上层提供的同步与异步访问方法。以设备I/O本质为源,根据前后因果,一层一层向读者展现设备驱动开发的核心技术。只有这样,我们在编写或修改相应的Android驱动时,采用相关的技术才会得心应手,所创建的驱动才能健壮地与原有驱动与系统融为一体。而且经过这样一个学习与实践过程,相信读者对于基于Linux内核的Android会有更清楚的认识。

Android驱动开发是一门工程性很强的技术,因此本书从实际开发需要出发,同时反复强调动手实践。另外,我们认为一个合格的Android驱动程序开发工程师,除了要会编写驱动程序,向上层程序提供相应设备模块功能外,还应会编写DVT(Design Verify Test)测试程序,以验证所创建的驱动程序。因此在第三篇“Android驱动实践篇”中,除了讲解Android驱动开发原理,还讲解了Android HAL等与Android驱动紧密相关的中间层知识;在讲述具体Android设备子系统时,从该子系统整体工作机制出发,力求让读者理解开发的驱动如何成为相关子系统的有机部分,为Android驱动开发人员提供驱动开发以及DVT测试程序开发指导。

通过本书的学习,读者将对Android整体有更深且更全面的认识。至于Android APK等程序开发的具体知识,相关的书籍与互联网上有很多资料,读者可以在进行具体DVT之类开发时,查阅相关技术的资料。

众所周知,驱动开发是与操作系统紧密相关的,因此Android驱动开发的工作应该属于系统级工程师的任务,要求我们比Android应用等开发人员知识面更广,这一点在本人编写本书时感触特别深。站在许多前辈的肩膀上,糅合了自己的经验与理解,历时8个月,终于成稿,心中依然忐忑。Android系统可谓博大精深,加上自己才疏智浅,书中难免存在缺点与漏洞,欢迎大家提出宝贵意见,并不吝赐教。

最后默默期许,有读者赞一声“这书对Android驱动开发还有些用”,本人则不胜感激与欣慰!当然,还要感谢张国强先生及我的家人,正是他们的支持与鼓励,才得以让我坚持并最终完成了这本书。同时,还要感谢网上不知名的“大牛们”给予的无私帮助,正是你们,让我相信中国的嵌入式驱动工程师队伍一定会强大。

本书内容安排

本书的内容被划分为三篇,共20章。

第一篇是Android概述篇,讲述了Android的来龙去脉、Android软件体系结构。它包含了两章内容:

第1章Android的前世今生,讲述了Android的起源、现状与发展。

第2章Android体系结构,讲述了Android的4层软件架构、源代码目录组织及其开发环境的搭建。

第二篇是Linux驱动基础篇,讲述了Linux内核基础知识,以及Linux驱动开发的关键技术。它包含了11章内容:

第3章Linux内核综述,讲述了Linux OS基本概念、进程管理、内存管理与文件系统。

第4章Linux内核编程与内核模块,讲述了Linux内核模块模型、内核模块编程,以及Linux内核源码组织与编译。

第5章Linux文件系统,根据Linux“一切皆文件”的核心要旨,着重讲解了文件系统,特别是与设备驱动紧密相关的设备文件系统。

第6章Linux字符设备驱动,讲述了字符设备驱动程序结构,并实现了一个虚拟化的字符设备,最后讲解了如何通过设备文件名和设备驱动程序来访问设备。

第7章Linux设备驱动中的内存与I/O访问,讲述了Linux设备驱动通过内存映射或分配I/O地址,实现对设备访问的基础原理。

第8章Linux设备驱动中的中断,讲述了Linux驱动的主处理流程与中断处理异步机制,以及中断响应与定时器技术。

第9章Linux设备驱动中的并发,讲述Linux驱动中并发访问存在的原因,以及解决并发竞争的同步访问技术。

第10章Linux设备的阻塞式与非阻塞式访问,讲述了Linux向上层应用提供的阻塞式与非阻塞式两类同步访问设备模式,以及所要提供的相关支撑技术。

第11章Linux设备驱动中的异步访问,讲述了Linux向上层应用提供的非同步(即异步)访问设备模式,以及Linux所要提供的相关支撑技术。

第12章Linux块设备驱动,讲述了Linux块设备的I/O操作与字符设备的不同之处、块设备驱动结构,以及关于块设备驱动的相关支撑技术。

第13章Linux网络设备驱动,讲述了Linux网络设备驱动架构体系、该类设备驱动结构,以及针对该类设备的I/O实现。

第三篇是Android驱动实践篇,讲述了Android HAL等Android驱动开发专有基础知识,以及若干个实践着Linux驱动的Android功能子系统,为Android驱动开发提供具体的帮助与指导。它包含了7章内容:

第14章Android HAL层的设计,讲述了Android HAL层工作原理,并以虚拟驱动为例,列举了针对具体驱动实现HAL层的实例。

第15章Framebuffer子系统,讲述了Android基于Framebuffer实现显示输出的工作机理;从开发实践出发,描述了Android Framebuffer子系统中经常遇到的相关硬件和相关驱动开发;还从系统角度讲解了所开发的Framebuffer驱动如何与Android Framebuffer子系统融为一体,为Android用户提供所需的显示输出服务。

第16章Input子系统,讲述了Android Input子系统的工作机理;从开发实践出发,以扩展键盘驱动为例,描述了Android Input子系统中相应驱动的开发;还从系统角度讲解了键盘等Input类驱动如何与Android Input子系统融为一体,为Android用户提供所需的输入服务。

第17章V4L2子系统,讲述了Android V4L2子系统的工作机理;从开发实践出发,以OV5642 Camera驱动为例,讲述了Android V4L2子系统中相应驱动的开发;还从系统角度讲解了Camera等V4L2驱动如何与V4L2子系统融为一体,为Android用户提供拍照、录像等多媒体服务。

第18章Binder IPC通信子系统,讲述了Android这个专有轻量级进程通信子系统的工作原理;描述了该子系统的Binder驱动底层支撑技术;还从系统的角度讲解了Binder驱动如何与Binder IPC子系统融为一体,为Android中的应用、服务等进程提供进程间通信。

第19章USB子系统,讲述了USB协议的基础知识;描述了Android中USB底层驱动支撑技术;以USB Mass Storage为例,讲解了USB驱动如何与USB子系统融为一体,为Android用户提供USB相关服务。

第20章Bootloader引导子系统,讲述了Bootloader的工作机理;从开发实践出发,给出了若干Bootloader的修改指导。

本书特色

本书立足于Android驱动开发实践,从开发者角度出发,主要有以下几个特点:

·实战性强。体现在两个方面,一是本书使用了大量的代码和例子,其中有的代码和例子稍做修改就可运用到具体的Android驱动开发中;二是讲解相关技术内容时,处处站在开发者角度,整篇的编排都是根据作者多年开发经验、从实战出发合理组织的。

·循序渐进。本书内容尽量由浅入深,逐层推进,力求让稍有软件和操作系统基础的入门者也能看懂并能掌握相关的Android开发技术。

·整体把握。本书始终强调避免将Android驱动与Android的其他组件部分割裂,而是从软件工程系统的观点,确保开发的驱动能成为Android的有机组成,为Android用户提供实际的功能服务。第一篇Android的前世今生——Android概述篇

本篇由两章构成:第1章讲述Android的前世今生;第2章讲述Android体系结构。该篇主要是想让读者对Android的历史有所了解,对Android的整体架构有所把握。第1章 Android的前世今生

Android是一个可用于手机、平板电脑和笔记本等移动设备的、嵌入式的、实时的智能操作系统。Android系统由Google公司在Linux内核和GNU软件基础上开发,上层通过修改JVM,实现了一个安全、易移植的平台。

本书主要讲解Android底层驱动的开发与应用,但也有必要先了解一下Android的前世今生,以便对Android有一个全面、感性的认识。1.1  Android的起源

Android系统最初由美国一家名字叫 Android的小型创业公司开发, Google公司在 2005年 7月收购了 Android公司。 Android公司的联合创始人 Andy Rubin、 Rich Miner、 Nick Sears和 Chris White也一起到 Google公司工作。 Andy Rubin加入 Google公司后担任 Android项目的负责人,组织开发这个基于 Linux内核、功能灵活、升级方便的移动操作系统。也正是从那个时候起,业界传出了 Google公司打算进入移动手机市场的消息。1.2 开放手机联盟

开放手机联盟( Open Handset Alliance, OHA)由 Google公司在 2007年 11月 5日正式宣布成立,并且随后在开放手机联盟的旗下公布了全新的 Android操作系统。开放手机联盟是由全世界顶尖的硬件、软件和电信公司组成的联盟,致力于为移动设备提供先进的开放式标准,以便开发可以显著降低移动设备与移动服务开发成本的技术。中国三大电信运营商中国移动、中国电信和中国联通都是开放手机联盟成员,中国移动还是开放手机联盟的创始成员。图 1-1列出了 OHA的部分成员。图1-1 OHA部分成员1.3 开源与相关协议

Android操作系统于 2008年 10月 21日在 Apache Software License( ASL)协议下开放源代码, Google公司在该协议下公布了 Android系统的全部源代码。 Google公司选择 Apache Software License 2.0许可证既保证了系统的开放源代码,又鼓励开源软件的商业性使用。 Google公司将 Android置于 ASL许可证之下,可以确保许多商业性公司接受这个平台,并且在它的基础上使用自己的专有技术。图 1-2就是 Apache基金会的标志。图1-2 Apache基金会的标志

Google公司开放 Android源码,对于 Android开发者与学习者来讲,真是莫大的福音。它为我们学习与研究 Android内在运行机制提供了方便;以及在开发 Android产品过程中,对于产品设计、问题解决等提供了最可依赖的基础。1.4 系统的升级与发展

系统升级是 Android的一大特色,每次新系统的发布, Android功能和用户体验都有很大提升。而且有趣的是,从 Android 1.5版本开始,每个系统版本都被冠以一个以美国传统食物命名的代号,比如 1.5( Cupcake)、 1.6( Donut)、 2.1( Eclair)、 2.2( Froyo)、 2.3( Gingerbread)、 3.0( Honeycomb)、 4.0( Ice Cream Sandwich)。细心的人很容易发现,这些食物名称的首字母是以英文字母表为顺序的。更让我们感到亲近的是, Google公司还将所有发布的 Android系统代号做成卡通模型,并将这些卡通模型放在位于加州山景城的 Google公司总部的草坪上,陪伴在 Android小绿人旁边。本书编写完成时 Android最新的版本已是 4.3。

为了方便后面的探讨,我们将基于 Android公司 2.3.7,以及该版本所用的 Linux 2.6.35内核展开。因为 Android 2.3是 Android发展中较为成熟的一个产品。而且读者可以发现,我们只要深刻理解了 Android 2.3,再去分析和理解其他 Android版本并基于这些版本做相应的开发,就没有什么难度。

随着 Android系统手持终端占有率的不断攀升, Android系统吸引了一大批程序开发者不断开发程序来扩展 Android手机的功能。目前 Android电子市场(最新更名为 Android Player)拥有数不胜数的应用程序。另外还有许多设备商、网络 SP公司以及集成商等也纷纷推出自己的 Android App Store,以向用户提供功能强大的各种 Android应用。目前支持 Android系统的 CPU硬件平台最多,市场上 Android手持终端的品类也是最多的。

我们可以清楚地看到, Android已具有良好的生态环境,形成了一个巨大的产业链。通过了解 Android的前世今生,我们应该能感受到,学习与掌握 Android是值得的。希望本书接下来的内容能在读者学习与研究 Android的道路上提供帮助。第2章 Android体系结构

从本章开始,我们将真正进入关于Android的学习。本章主要介绍Android的体系结构。希望通过本章的学习,读者能对Android有个整体的了解。本章在本书中不是重点,但仍请读者偶尔回头翻一翻该章的内容,因为这样让我们在畅游繁杂的Android系统时不会迷失了方向。2.1 四层空间基本结构

Android是一个开放的软件系统,从下至上包括 4个层次,如图 2-1所示。图2-1 Android四层空间架构

其中第一层是 Linux内核层,包括 Linux操作系统及驱动。不同的 Android版本所用的 Linux内核版本不一样;甚至在不同平台,即使所用的 Android版本一样,其所用的 Linux版本也会有差异。例如, Android 1.6可能用的是 Linux 2.6.29;而 Android 2.3.7则可能用的是 Linux 2.6.35;最新的 Android 4.x则纷纷采用 Linux 3.x。虽然, Linux 2.6.1之后的任何一个小版本都会有很大变化,但我们认为,就目前 Android所用的 Linux版本来讲,这些差别并不会有我们想象中的那么大,所以在第二篇中不会太追究 Linux版本之间的差异,而是关注最根本的东西,让读者能有所收获,并打下一个扎实的基础。 Android基于 Linux内核,还增加了 Binder驱动等模块,为系统运行提供了 IPC进程通信等方面的支撑。我们将在第三篇对关于 Android驱动的特性部分展开更详实的描述。

第二层是核心的扩展类库,如 SQLite、 WebKit、 OpenGL等,它们可以通过 Java本地调用( Java Native Interface, JNI)的接口函数实现与上层之间的通信。该层由 Android的 Java虚拟机 Dalvik和基础的 Java库为 Java运行环境提供了 Java编程语言核心库的大多数功能。

第三层是包含所有开发所用的 SDK类库和某些未公开接口类库的框架层,是整个 Android平台核心机制的体现。

第四层是应用层。系统自带应用和第三方开发的应用都位于这个层次上,但两者不完全相同:其中系统应用会使用一些隐藏的类,也就是说,这些类没有包含在 SDK中;而第三方开发的应用,是基于 SDK基础上开发的。一般 Android开发是在 SDK基础上用 Java编写应用程序,但本机开发程序包 NDK提供了应用层穿越 Java框架层直接与底层包含了 JNI接口的 C/C++库直接通信的方法。在研发工作过程中,我发现有人常将 NDK与 JNI混为一谈。从这里,我们应认识到它们还是有所区别的: Android的应用开发者用 JNI与 C/C++库通信的话,他应该通过 NDK;而对于本书的主要读者—— Android的驱动开发者来讲,则主要考虑如何为底层驱动实现 JNI接口,以便上层可以方便地调用由该驱动程序所驱动的相应设备的功能。

从 Linux操作系统的角度来看,第一、二层次之间是内核空间与用户空间的分界线,第一层运行于内核空间,第二、三、四层运行于用户空间。第二、三层之间是本地代码层和 Java代码层的接口,第三、四层之间是系统 API接口。

另外,用心的读者也许会从图 2-1中发现,在第一、二层之间,即第二层的最底层,有一个硬件抽象层( Hardware Abstract Layer, HAL)。其实,该层并不一定要存在,它是为了保护一些硬件提供商的知识产权而提出的。根据 Android的 Apache License,硬件厂商可以只提供二进制代码,但这些二进制代码应该符合 HAL规范,以便上层调用这些硬件所提供的特殊功能。具体内容我们将在第三篇的第 14章进行详细的探讨。

基于上面这个分层结构,我们所从事的 Android开发主要分成两类:一类是 Android系统底层开发;另一类就是 Android应用开发,如图 2-2所示。在本书中,我们将主要关注 Android系统底层开发。但为了让底层开发能为 Android应用开发所用,我认为底层开发者至少应对上述 Android四层架构中的第二层与第三层有所了解。在必要的情况下,比如一个新的设备模块,就会要求我们提供相应的 C/C++库、 JNI,甚至应用 Demo等,以便上层应用基于我们的设备开发出相应的功能提供给最终用户。图2-2 Android开发分类

2.1.1  Android系统底层开发

我们将除第四层之外的所有层的开发都称为底层开发。其中第三层是 Java框架层,我们一般不做修改;在第二层,我们会为调用底层硬件功能编写 JNI、 HAL以及相关的动态共享库。如图 2-3所示:图中 Java应用程序、 Java框架、核心库等部分是不会修改的; JNI、 Android各种底层库、硬件抽象层等部分将会有一定的修改;而处在内核空间的各部分,尤其是 Android系统相关设备驱动部分将会有大量的修改甚至新的创建在里面。图2-3 Android底层开发

2.1.2 应用程序开发

应用程序不是本书关心的部分,因此这里了解一下就可以。如图 2-4所示。图2-4 Android应用开发

对这部分感兴趣的读者,可以参考 http://developer.android.com/index.html,里面有针对应用开发各部分的讲解,并有翔实的例子。2.2  Android代码目录结构

我们还应了解 Android的代码组织方式,这样将对阅读代码和分析问题有很大的帮助。

先介绍 Android源码阅读与开发的前提条件:因为对于前面所述四层结构中,第一层由 C语言实现,第二层由 C和 C++实现,第三、四层主要由 Java代码实现,所以,要学习 Android开发,应具有 C、 C++、 Java三种语言的基础。

Android代码包括三个部分:①核心工程( Core Project)是建立 Android系统的基础,在根目录的各个文件夹中;②扩展工程( External Project)即使用其他开源项目扩展功能;③包( Package)提供 Android应用程序和服务,其中既包含要在 Android设备上运行的代码,还包括主机编译工具、仿真环境等。

第一级别的目录和文件如下:

1) Makefile:全局的 Makefile。

2) bionic:这里面是一些基础的库的源代码。

3) bootloader:引导加载器,不同的平台,该名字会稍有不同,但其意义差不多;事实上,有很多平台都有专有 boot目录,以满足这些平台特殊的引导要求。

4) build:目录的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具。

5) dalvik: Java虚拟机。

6) development:程序开发所需要的模板和工具。

7) device:与实际目标机器所用平台直接相关的库或源码。

8) external:目标机器使用的一些库,其实现了开源的扩展功能。

9) frameworks:应用程序的框架层。

10) hardware:与硬件相关的库,前面讲的 HAL就是在这个目录下实现的。

11) kernel: Linux的源代码。

12) packages: Android的各种应用程序。

13) prebuilt: Android在各种平台下编译的预置脚本。

14) recovery:与目标的恢复功能相关。

15) system: Android底层的一些库。

16) vendor:有的 CPU厂商用它来放置与 CPU相关的 CSP或 BSP相关代码或库。

注意,上面有的目录可能在相应的 SDK中不存在,或者在 SDK中有的目录该列表中没有,这要看具体开发的机器与平台,但一般 SDK主体就是上面 16个目录。

另外,这里再解释几个我们经常碰到的名词: SDK全称是 Software Develop Kit,是指 Android开发完整的软件包,是对上述代码的总称; CSP全称是 CPU Support Package,是针对某操作系统而适配的、与 CPU紧密相关的代码与库; BSP全称是 Board Support Package,是针对某操作系统而适配的、与具体开发的 PCB板紧密相关的代码与库; PCB全称是 Print Circuit Board,一般是指印刷电路板,它是开发将要依赖的硬件基础。

编译完成后,将在根目录中生成一个 out文件夹,生成的所有 Android代码结构内容均放置在这个文件夹中。 out文件夹包含如下目录和文件:

1) CaseCheck.txt。

2) casecheck.txt。

3) host。

4) common。

5) linux-x86。

6) target。

7) common。

8) product。

其中,两个主要的目录为 host和 target,前者表示在主机( x86)生成的工具,后者表示目标机(如 ARMv5)运行的内容。2.3  Android开发环境搭建

我们要进行 Android开发,首先要有一台 PC。 PC的最低配置如下:

1) 32位 4核 CPU。

2) 2GB内存。

对于 Android 2.3.x之后的版本, Google公司逐渐要求 64位的 CPU,而且要求内存在 8GB以上。否则用虚拟 64位机的方式,仅编译的时间就让人无法忍受。但是这么高的机器配置,可能让 Android开发爱好者望而却步。

不过,我们找到了一种用上述低配 PC就可以编译 Android 2.3.x的方法。网上有很多相关的描述,这里不对该方法做更多的讲述了。这也是本书选定 Android 2.3.7为蓝本的主要原因之一。另外基于低配的 PC,用 Eclipse调试 Android 4.x以上的应用,也是相当慢的。因此,我们建议 Android开发初学者,不妨先从 Android 2.3.x入手。笔者认为,学习一门技术,特别是像 Android之类的系统级软件,掌握其思想是最重要的。

有了 PC硬件之后,还要为该 PC准备好 Android开发软件环境。该环境的搭建分成两大步。

1) Ubuntu Linux的安装。这一步又可以分为两小步:

① VMware虚拟机的安装。可能对于大多数的 Android开发初学者来讲, PC上应该预先装载了 Windows系统;为了安装 Ubuntu Linux,我们应该在 Windows系统上安装虚拟机。而虚拟机软件,我们推荐 VMware。对于专业的 Android开发者来讲,建议反过来,系统默认安装 Ubuntu,而 Windows系统安装在 Ubuntu的虚拟机上。

② Ubuntu的安装。建议使用 Ubuntu 10.04及以上版本。推荐使用 10.04,因为 Google以及各 CPU原厂都是基于该版本来开发验证的。另外,分配 Ubuntu的硬件空间建议尽量大于 90GB,因为 Android的开发包太占空间了。如果 PC的内存足够大,也尽可能为 Ubuntu分配更多的内存空间,这样会大大缩短编译时间。

2) Android编译环境搭建。这一步则可以分成以下几步。

① Repo工具安装。执行以下两步命令:$ curl https://dl-ssl.google.com/dl/googlesource/gitrepo/repo >~/bin/repo$ chmod a+x ~/bin/repo

该工具将被用来从 Google公司指定的网站提取 SDK源码。如果第一条指令不成功,不妨将 https修改为 http试试,或者安装 ssl相关的包,以让 Ubuntu支持 https。

②安装 SUN JDK1.6。 Ubuntu中已不默认支持 JDK安装。你不妨直接从 Oracle网站直接下载一个,并执行以下命令直接解包即可:$ ./jdk-6u37-linux-x86.bin

注:上面的数字 37是该 JDK 6.0的版本号,用户下载的版本不同,该数字可能不同。

如果你安装的是 64位的 Ubuntu,则运行的应该是 jdk-6u37-linux-x64.bin。

接着,要配置 Java的环境,以便 Ubuntu中的其他工具或软件可以方便地用到 Java。因此,我们修改了文件 etc/profile,在该文件的最后 3行加上以下代码:export JAVA_HOME=/root/tools/JDK/jdk1.6.0_37/export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/libexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH

最后,执行下面的命令,来验证 Java的版本以及是否安装成功:$ java -version

③安装必要的其他工具。执行以下的命令即可:$ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline-gplv2-dev lib32z-dev libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown libxml2-utils xsltproc

④升级 Git工具。对于 Ubuntu 10.04, Git工具默认的版本有些旧。到 Android 2.3.x版本之后, Git版本要求 1.7.1之后的。从网上下载一个最新的 Git包,解包并执行以下的命令即可:$ tar –zxf git-1.7.1.tgz$ cd git-1.7.1$ ./configure$ make$ sudo make install

升级完成后,可以用下面的命令来验证升级的成功:$ git --version

当开发环境搭建好后,就应针对目标机做工作了:那就是 SDK源码的获得,以及编译。编译好的 Image将被烧写进目标机。

1) SDK源码的获得。执行以下命令,这要花费不少时间。$ mkdir [android_dir]$ cd [android_dir]$ repo init -u https://android.googlesource.com/platform/manifest$ repo sync

2) SDK编译。笔者认为, Android的编译应该分成 3部分(平台不一样,可能会有些许差别):

① uboot的编译。该编译所产生的 Image将用来引导 PCB板,装载与下载后面的 Kernel与 Android的相关 Image。

② kernel的编译。就是对 Linux内核的编译,它与一般的 Linux编译没有太大的区别,其所生成的 Image,将用来承载 Android所需要的 Linux OS。常用到的编译步骤有:$ make menuconfig #对Linux内核各组成模块进行配置$ make #编译生成Linux内核映像

③ Android的编译。其用来编译生成 Android的相关 Image。一般主要有 3个: system.img、 ramdisk.img、 userdata.img。编译的方法就是在 Android的主目录下,执行以下的命令:$make

生成完 Image后,我们就应找一块开发板,来验证我们的编译成果。我们强烈建议读者想办法找到相应的开发板来检验开发。如果实在找不到,不妨把生成的 Image文件复制替换 Android AVD的相应文件,并用 Eclipse来调试自己的修改。请记住,我们讲的是 Android底层开发技术,这是个实践性很强的技术,有机会就要多动动手。第二篇勿于浮砂筑高台——Linux驱动基础篇

下面将讲述Android最底层的部分:Linux OS。Linux OS其实是一个很大的课题。这里我首先要提醒各位读者,学习Linux OS的目的是让用户可以方便地使用PCB板上的CPU,以及GPS等功能模块。因此我们在着手开发驱动程序之前,应先想到相应的功能设备,想想我们开发该驱动的目的何在。我们将在本篇让读者对Linux OS有一个基础而清晰的认识。第3章 Linux内核综述

如前面所讲,Android的OS(Operation System,操作系统)是Linux。因此,如果对Linux内核没有一定的理解,就去进行Android开发,甚至Android底层开发,哪怕是在“前辈”的基础上对某个模块进行修修改改得到了想要的结果,也终究走不太远。老祖宗教导我们“勿于浮砂筑高台”,诚不欺也。

对于具备一些Linux基础的读者,不妨跳过本篇中的某些章节。但还请大家有空的时候,多多阅读这部分的内容。完全没有基础的读者,也不用担心,安心地阅读下去,相信一定会有所斩获的,因为我们尽力用浅显的方式来捅破Linux的一层层窗户纸。3.1  OS基本概念

现在的 PC和常用的手机等,都有一组基本的程序—— OS(操作系统)。在这组程序中最重要的叫内核。内核将在系统引导时被装载进 RAM,其中包含了许多关键的例程,以操作系统;当然除了内核之外, OS中还有其他的程序以方便用户交互,方便用户使用计算机。可以说,内核是 OS最为关键的部分,人们常将 OS与内核等同。 Android设备中所用的 OS就是 Linux 2.6之后的版本。在本书中,除非特别说明, OS就是指 Linux内核。并且,本篇将基于 Android 2.3所用的 Linux 2.6.35的内核来讲解。

OS必须完成两个主要目标:

·与硬件交互。

·为在计算机系统上运行的应用程序提供可执行的环境。

一些 OS允许用户程序直接与硬件组件交互(如 MS-DOS)。相反, Linux OS会屏蔽掉所有与物理硬件相关的东西。当应用程序要用到硬件资源时,它就必须向 OS发出请求,而 OS则会根据情况许可上层应用使用该硬件资源。

为了加强这种机制,现代的 OS将依赖于特定硬件的特性( feature)来禁止用户程序直接与底层的硬件组件交互,或直接地随意访问内存的地址。继而,该硬件引入了两个不同的 CPU执行模式:非特权模式给上层用户程序用;特权模式则给内核用。相应地, Linux中将之称为用户模式和内核模式。

下面我们先了解关于 Linux的几个概念。

3.1.1 多用户系统

Linux OS是源于 UNIX系统的。 UNIX设计时,考虑到计算机是很昂贵与稀缺的资源,因此一台计算机就要满足多个用户同时使用。 Linux OS沿用了这一设计思想,就通过分时共享等策略,让多个用户可以同时使用一台计算机,却让各用户感受不到自己是在与其他用户共用这台机器。该分享策略,使得机器即使只有一个用户,也可以同时运行多个任务,响应多个进程。

Linux作为一个多用户系统,它必须具有以下几个特性:

·认证机制,以验证用户ID。

·保护机制1,以对抗bug,不让这些坏程序阻塞了其他用户程序。

·保护机制2,以对抗恶意的程序,以防它去监听其他用户的活动。

·审计机制,以限制分派给每个用户的资源。

为了确保机器的安全, Linux内核要求使用由 CPU硬件提供的特权模式;而用户程序只能运行在非特权模式下;用户程序要使用底层的软、硬件资源,必须向 Linux内核发出请求,在 Linux内核许可后,并切入特权模式以执行。提醒各位读者一点,要实现这两种模式,常常需要 CPU在硬件上给予支持。例如,在现在最流行的 ARM处理器中, CPSR(当前程序状态寄存器)就用了 5个位来识别处理器的 7种模式,其中两种模式就与 Linux中的用户模式和内核模式相对应,其他 5种模式则用来标识不同的中断或出错场景。

3.1.2 用户和组

Linux OS作为多用户系统,每个用户在机器上都有一个私有空间;特别是,他会拥有配额的磁盘空间(对于 Android手持终端来讲,更可能是 Flash空间或 MMC存储空间),以存储文件、接收私有的 mail消息等。 OS必须确保这部分私有空间只对它的拥有者是可见的。另外,它应该确保没有用户可以使用系统应用程序来侵犯其他用户的私有空间。

所有用户都是通过唯一的用户 ID来识别的,简称 UID。当用户想用机器,会被要求输入用户名和密码,这样用户的私密权就得到了保证。

如果要选择与其他用户共享材料,共享的每个用户就应是一个或多个组的成员,这个组由组 ID( GID)来识别。每个文件都可与一个确切的组相关联。例如,作为文件拥有者的用户拥有对该文件的读写权限,而组中其他用户则只拥有读权限,系统中非组中的用户则没有任何访问权。

Linux OS中,有一个特殊的用户: root。系统管理员应以 root的身份登入机器,以管理其他用户账号,完成维护任务(如系统的备份和程序的升级等)。 root用户几乎可以做任何事情,因为 OS并没有对它采取一般的防护机制。另外, root用户可以访问系统上的每一个文件,可以管理每一个正运行着的用户程序。

如果需要,在 Android开发中,可以通过超级终端或 adb shell,可以输入以下命令来拥有 root的权限:$ su –#

3.1.3 进程

前面我们提到了进程。事实上,对于支持多用户的 OS都有一个基本的抽象:进程。进程是一个执行的实例( an instance of a program in execution),是程序执行的上下文( execution context)。在初始的 OS中,一个进程是在一个地址空间中,执行单个顺序的指令集。现代的 OS中,则允许进程中有多个执行流,也就是在同样的地址空间里有多个同步运行着的顺序执行指令集。作为 Linux OS,它就允许进程中有多个执行流可以并发执行。这些执行流在 Linux OS中被称为线程或轻量级进程。

对于单处理器,进程、线程或中断处理执行流的并发,是分时的并发,是逻辑上的并发。对于多处理器系统,这些并发执行是真真切切同时在运行的。多用户系统,必须保证有一个这样的并发执行环境:允许几个进程同时执行,它们将对系统的资源共享,且通过竞争来获得使用。这些允许多个活动进程的 OS,也被称作多程序或多进程系统。 Linux OS就是支持多用户、多进程、多处理器的一款操作系统。

注 1:程序与进程是有区别的。程序是静止的,由代码、库或资源组成的集合体;而进程则是程序在计算机系统里运行,是程序的动态体现。

注 2:有些多进程系统并不是多用户系统,比如 Windows 98。

OS中有一个组件叫调度器( scheduler),它将负责选择可以被执行的进程。这个选择的过程,我们称之为进程调度。支持多用户的 OS要跟踪某一进程已拥有 CPU多长时间了,从而周期性地激活 scheduler,从而对系统的进程重新进行一次调度,以便其他用户能够得到执行的机会。

Android所用 Linux 2.6是一个多进程的系统,同时实现了可抢占式的进程调度,也就是高优先级进程可以抢占低优先级进程的 CPU执行权,以便高优先级的任务能得到更快的响应,从而满足 Android系统的实时性要求。 LinuxOS即使没有用户登录或没有应用程序运行,其实也会有几个系统进程在运行,以监控机器的外围设备。特别是有几个进程会监听系统的终端以等待用户的登录。当有用户输入了用户名,该监听进程就会去核查用户的密码是否正确。如果用户的 ID被认可了,该监听进程就会创建另一个进程。这个监听进程就是以命令行形式与 Linux交互的 Shell进程。 Android系统启动后,肯定会运行 Launcher应用,它其实是一个图形化 Shell,从这里用户可以点击其他应用和 Icon,从而激活其他进程执行相应的程序。

3.1.4  Linux单核架构

OS的内核架构主要分为两种:一种是单内核的;另一种是微内核的。 Linux内核是单核的:每个内核层被集成为一个整体的内核程序,并运行在当前进程的内核模式中。相反,微内核 OS则只有上述内核的最核心功能,一般包括:一些同步用的原语、调度器、与进程间通信的机制;而几个系统进程会运行在上述微内核之上,来完成 OS其他系统层的功能,如内存分配、设备驱动,以及系统调用处理例程( Handlers)。像微软的 Windows CE OS就是微内核的。

尽管学术界更倾向于微内核,但微内核 OS速度上较单核的架构要慢,因为在 OS不同层之间的显式消息传递就是要花费时间的。当然,从理论上讲,微内核具有许多单内核所不具有的优点。微内核强制系统程序员采用模块化的方法,因为每个 OS层是一个相对独立的程序,它要通过已定义好的、简洁的软件接口与其他层交互。另外,微内核的 OS移植起来将更简单,因为所有与硬件相关的组件基本都被封装在微内核代码中了。最后,微内核 OS相对于单内核 OS,能更好地使用 RAM,因为那些功能不为所需的系统进程可以被交换出去甚至毁灭。

为了得到上述微内核理论上的好处,却又没有性能上的损失, Linux内核基于面向对象的思想,引入了模块的概念。一个模块包含一个 object文件,该 object代码由一组功能组成:归属于某一文件系统、底层设备功能驱动,以及其他属于内核上层的特性( features)。这个模块又不同于微内核 OS的外部层,它不是运行在专门的进程中,而是运行在当前进程的内核模式中。本书所要讲述的重点—— Android底层驱动,就是以模块的方式实现的。

总之, Linux OS使用模块机制主要带来了以下好处:

·模块化的方法。

·保持平台的独立性。

·节俭的主内存使用。

·没有任何性能上的损失。

为使大家有一个感性认识,下面实现一个 hello模块,参见代码清单 3-1。代码清单 3-1  hello模块#include #include MODULE_LICENSE("Dual BSD/GPL");static int hello_init(void){ printk(KERN_ALERT"Hello, Android Driver"); return 0;}static void hello_exit(void){ printk(KERN_ALERT"Goodbye, Android Driver");}module_init(hello_init);module_exit(hello_exit);

上面的代码很简单,其主要功能就是当调用 insmod命令,向系统内核插入该模块时,输出 "Hello, Android Driver",而调用 rmmod命令从系统卸载该模块时,输出 "Goodbye, Android Driver"。 Linux驱动,包括 Android驱动,就是该类模块的一种。在第 4章,我们将对 Linux模块机制展开更详细的讲解。有兴趣的读者可以就这个例子模块,在 PC主机的 Linux系统、 Android设备或模拟器上测试验证。3.2  Linux内核综述

内核必须实现一组服务和相应的接口,应用程序则可以用这些接口,而不是直接与硬件打交道。下面就针对这些服务,进行一次总体的描述,帮助读者理清这些服务的出发点并了解相应的概念。

3.2.1 进程 /内核模型综述

Linux内核主要由以下 5个子系统组成:进程调度、内存管理、虚拟文件系统、进程间通信以及设备驱动。如图 3-1所示。图3-1 Linux内核组成

在这个组成中,其中最核心的就是进程管理,也是图 3-1中的进程调度与进程间通信两个部分。本节将讲述 Linux进程管理的关键特性。

我们首先应了解,正是基于该组成模型使得编写的 Android程序,不管是上层的还是属于中间框架层的代码,甚至是最底层的驱动模块,都可以以进程的形式在系统上运行。前面我们讲了, CPU可以运行在用户模式与内核模式。

在 Linux OS进程 /内核模型中,每个进程就是执行在机器上的唯一的镜像,它们对系统服务的访问具有排他性。当进程需要访问系统服务时,它会发出系统调用(就是对内核的请求),硬件则会将权利模式由用户模式改为内核模式。此时,该进程就开始执行某内核的过程,这个过程是有严格限制的。通过这种方式, OS(确切地讲应该是内核代码)运行在该进程的上下文( context)中,却又保证其请求是安全的。该内核过程在合适时机会通过硬件强制返回用户模式,此时该进程将继续执行程序中紧接着系统调用的下一条指令。

当一个程序执行在用户模式下,它就不能直接地访问内核数据结构或内核的程序。当程序处于内核模式时,这些限制就不再存在了。现在 CPU一般提供了特定的指令在用户模式与内核模式之间切换。通常,在用户模式下执行的程序向内核发出服务请求时,就会切换到内核模式。当内核已响应程序的请求时,就会设置程序退回用户模式。

进程是动态的实体,其在系统中的生命是有限的。任务的创建、销毁和同步在内核中体现为一组线程。 Linux内核是以线程为调度的单位。

注 1:任务就是进程的集合,其中可以包含一个或多个进程。当用户想让机器做某件事时,就会启动一任务,而该任务可以由一个或多个进程来完成。

注 2:同步与异步。读者对同步与异步要有深入的理解,因为在后面这两个词出现的频率很高。异步,就是两件事的发生是没有任何关联的,一件事的发生不会因另一事件的发生而有任何变化;同步,则是两件事之间有先后顺序之分,一个事件的发生一定是在某个事件之后。例如,当一个程序访问某一硬件资源时,另一个程序也要访问该硬件资源,后一个程序就要等待前一个程序,我们就说这两个程序同步访问该硬件资源。千万不要把同步理解为两件事同时发生,初学者常有这样的误解。

内核不是进程,而是进程的管理者。

除了用户进程, Linux系统包括一些特权线程,这些内核线程有以下特点:

·它们运行在内核模式,用的是内核地址空间。

·它们不与用户直接交互。

·它们通常在系统启动时被创建,并一直存活到系统关闭。

在单处理器系统中,某一时间只有一个进程在运行,该进程可能运行在用户模式,也可能运行在内核模式。如果它运行在内核模式,处理器就正在执行内核例程。图 3-2显示了用户模式与内核模式间的迁移。图3-2 进程用户模式/内核模式间的迁移

Linux内核除了处理系统调用,还会做很多事情。事实上,内核例程会在以下情况被激活:

·进程调用系统调用。

·CPU正执行进程发出异常的信号,表示诸如无效指令等非常规条件发生了。此时内核为了保护引起该异常的进程和计算机,会处理该异常。

·外围设备发出一个中断信号到CPU,告诉CPU某一事件(如请求注意、状态改变或I/O操作的完成)。每个中断信号都是由一个叫做中断处理句柄的内核程序来处理的。中断与CPU的执行是异步的,所以中断的发生是不可预期的。

·内核线程被调度执行。

注:异常与中断很相似,它们都会导致 CPU停下当前的进程进入专门的处理例程。但异常是同步发生的,它一定发生在某一错误之后;而中断则是异步发生的,它的发生是随机的;因此虽然在处理流程上很相似,但 OS还是给予了它们不同的名称。

1.进程实现

为了让内核可以管理进程,每个进程都由一个进程描述符( descriptor)来代表,在该描述符中记录了该进程的当前状态。

当内核停止了一个进程的执行,它会在该进程描述符中记录几个处理器寄存器的当前内容。这类寄存器包括:

·PC与SP寄存器。

·通用目的寄存器。

·浮点寄存器。

·处理器控制寄存器(处理器状态Word),其中包含了CPU状态的信息。

·内存管理寄存器,用来跟踪该进程所访问的RAM。

当内核决定重新执行一个进程时,它会用到合适的进程描述符的相关域来装载 CPU的寄存器。例如 PC的信息就会让进程从被暂时中止的位置开始执行。

当进程没有在 CPU上执行,它就应在等待某些事件。 Linux内核区分出许多等待状态,这些状态通常通过进程描述符的队列来实现;每个队列(有可能是空队列)对应着一组进程,这组进程都在等待着特定的事件。也就是讲, Linux会为每个事件创建队列数据结构,该数据结构类型其实是一个链表,该链表上的元素其实就是所有等待该事件进程的描述符。

2.可重入的内核

Linux内核都是可重入的。这就意味着,几个进程可能同时在内核模式下执行。当然,在单处理器系统,在某一时间只会有一个进程运行,但许多会阻塞在内核模式;这些进程会分时共享 CPU、 I/O设备等系统资源;这些进程给用户的感觉就像是在同时运行。

要提供可重入性代码方法是:编写的函数都只会影响到局部变量,而不能改变全局的数据结构。这样的函数都被称作可重入函数。但是一个可重入内核不仅有这些可重入函数,事实上,如上所讲,由于在访问 I/O等共享资源,内核还要有不可重入函数。此时, Linux内核就要使用锁机制,来保证在某一时间内只有一个进程可执行该不可重入代码,也就是分时共享的办法,来实现可重入的内核。

如果某硬件中断发生, Linux内核作为可重入内核,在任何情况下就可挂起该正运行着的进程。这个能力是非常重要的,因为它提高了发出中断的设备控制器的吞吐量。一旦一设备发出了中断信号,它会等待 CPU响应它。如果该内核可以快速地应答,该设备控制器就可以在 CPU处理中断时,马上去处理其他事件。在中断处理例程中,不应该有不可重入代码。因为不可重入代码会导致处理流程等待,进而导致中断不能得到及时的处理。更糟糕的是,我们后面会讲到,如果允许中断处理中使用不可重入代码,很容易导致系统死锁而代码得不到进一步的执行。中断处理例程除了可以被更高优先级的中断暂时中止,它应该能被顺序地执行完。

现在让我们仔细看看内核的可重入,以及其对内核组织所带来的深远影响。内核控制路径是指内核处理系统调用、异常和中断的一系列指令集。

在最简单的情况中, CPU顺序地执行内核控制路径,从头执行到尾。但当有以下情况发生时,则 CPU就要交替地执行内核控制路径:

·在用户模式下运行的某进程调用了系统调用,而当前的内核控制路径检验到该请求不能被马上响应,则内核会调用调度器,并选择新的进程来运行。这样,原来运行的进程被挂起,而一个新进程切换进来拥有CPU的执行。

·CPU检查到有异常发生。例如访问的页面不在RAM中。此时,异常处理例程这个内核控制路径会被执行,但是它与出现异常的内核控制路径是在同一进程的执行上下文中。

·发生硬件中断。与异常一样,切换的两个内核控制路径也是在同一进程的执行上下文中。

·更高优先级的进程到来。

图 3-3显示了内核控制路径的交替,此时 CPU会有 3种状态:

试读结束[说明:试读内容隐藏了图片]

下载完整电子书

相关推荐 初夜(txt+pdf+epub+mobi电子书下载) 实用西医师中成药手册·肿瘤科分册(txt+pdf+epub+mobi电子书下载) 马尔克斯:番石榴飘香(txt+pdf+epub+mobi电子书下载) 济公传(txt+pdf+epub+mobi电子书下载) 因为苦过,所以知足(txt+pdf+epub+mobi电子书下载) 出发吧,少年:回到古代去旅行(txt+pdf+epub+mobi电子书下载) 在入世后——企业篇(txt+pdf+epub+mobi电子书下载) 孽债(txt+pdf+epub+mobi电子书下载) 少年读历史(套装4册):写给孩子的中国历史故事,浓缩五千年之精华, 谈人类文明之辉煌历程,给孩子厚积薄发的财富,从容应对变化的世界(txt+pdf+epub+mobi电子书下载) 数控铣编程与实训教程(txt+pdf+epub+mobi电子书下载) 看中国(txt+pdf+epub+mobi电子书下载) 新时代相声创作集(txt+pdf+epub+mobi电子书下载) 白孔雀(txt+pdf+epub+mobi电子书下载) 中国文史精品年度佳作2017(txt+pdf+epub+mobi电子书下载) 社会性规制评论(第1辑)(txt+pdf+epub+mobi电子书下载) 年糕妈妈辅食日志(txt+pdf+epub+mobi电子书下载) 调养体质更健康(txt+pdf+epub+mobi电子书下载) 荀子公开课(txt+pdf+epub+mobi电子书下载) 福尔摩斯探案全集2:福尔摩斯冒险史(txt+pdf+epub+mobi电子书下载) 欧洲战史(txt+pdf+epub+mobi电子书下载) 最新文章 人生就要不断精进(txt+pdf+epub+mobi电子书下载) 做个心智成熟的人:人生可以不走弯路(txt+pdf+epub+mobi电子书下载) 跟谁都能聊不停:一看就能用的魔鬼搭讪学(txt+pdf+epub+mobi电子书下载) 赴美留学必知(txt+pdf+epub+mobi电子书下载) 我的男友(txt+pdf+epub+mobi电子书下载) 中国东北与东北亚古代交通史(txt+pdf+epub+mobi电子书下载) 幸福生活讲座(txt+pdf+epub+mobi电子书下载) 情商决定一生(txt+pdf+epub+mobi电子书下载) 夜雨寄北(txt+pdf+epub+mobi电子书下载) 让学生热爱学习(txt+pdf+epub+mobi电子书下载) On Dreams(txt+pdf+epub+mobi电子书下载) 我的史学人生(txt+pdf+epub+mobi电子书下载) Creo2.0完全学习手册(txt+pdf+epub+mobi电子书下载) 2018年陕西省军转干部安置考试《公共基础知识》题库【真题精选+章节题库+模拟试题】(txt+pdf+epub+mobi电子书下载) 假如给我三天光明(txt+pdf+epub+mobi电子书下载) 带出高效执行力(txt+pdf+epub+mobi电子书下载) 北史(四)(txt+pdf+epub+mobi电子书下载) 影响力的企业富豪(上册)(txt+pdf+epub+mobi电子书下载) 商界40年:逐鹿人(1999-2008)(txt+pdf+epub+mobi电子书下载) The Boats of the Glen Carrig(txt+pdf+epub+mobi电子书下载) © 2020 txtepub下载


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3