Android基础知识和驱动开发Mickal.ma•Android系统架构•Android系统启动过程•Linux内核驱动模型•Android系统的编译•Android驱动开发与调试概述•Android系统是基于Linux内核的手机操作系统平台,要深入系统的学习Android,不仅仅是有Java和Android应用开发,必须要具备Linux,C/C++高级编程才能深入的涉及AndroidFramework和Android内核开发。Android系统架构Applications•Android装配一个核心应用程序集合,包括电子邮件客户端、SMS程序、日历、地图、浏览器、联系人和其他设置。所有应用程序都是用Java编程语言写的,它们的源代码是开放的,代码存放的位置在android_root/packages/apps。更加丰富的应用程序有待我们去开发!ApplicationFramework•Android应用框架的核心代码在android_root/frameworks/base目录下,是用java和c/c++语言编写的可重用类和组件,它提供一系列的服务和系统,包括视图、内容提供器、资源管理器、通知管理器、活动管理器等。*视图(View)——丰富的、可扩展的视图集合,包括列表、网格、文本框、按钮,甚至是内嵌的网页浏览器*内容提供者(ContentProviders)——使应用程序能访问其他应用程序(如通讯录)的数据,或共享自己的数据*资源管理器(ResourceManager)——提供访问非代码资源,如本地化字符串、图形和布局文件*通知管理器(NotificationManager)——使得程序可以在状态栏中显示自定义的提示信息*活动管理器(ActivityManager)——管理应用程序生命周期,提供通用的导航回退功能Libraries•Android包含一个C/C++库的集合,供Android系统的各个组件使用。这些功能通过Android的应用程序框架(applicationframework)暴露给开发者。下面列出一些核心库:*系统C库——标准C系统库(libc)的BSD衍生,调整为基于嵌入式Linux设备*媒体库——基于PacketVideo的OpenCORE。这些库支持播放和录制许多流行的音频和视频格式,以及静态图像文件,包括MPEG4、H.264、MP3、AAC、AMR、JPG、PNG*界面管理——管理访问显示子系统和无缝组合多个应用程序的二维和三维图形层*LibWebCore——新式的Web浏览器引擎,驱动Android浏览器和内嵌的web视图*SGL——基本的2D图形引擎*3D库——基于OpenGLES1.0APIs的实现。库使用硬件3D加速或包含高度优化的3D软件光栅*FreeType——位图和矢量字体渲染*SQLite——所有应用程序都可以使用的强大而轻量级的关系数据库引擎Android的运行环境(AndroidRuntime),这个也应该属于这个框架里面的,android的虚拟机叫做Dalvik,运行环境就是由这个虚拟机和基础的java类库组成。LinuxKernel•Android基于Linux2.6提供核心系统服务,例如:安全、内存管理、进程管理、网络堆栈、驱动模型。LinuxKernel也作为硬件和软件之间的抽象层,它隐藏具体硬件细节而为上层提供统一的服务。小结•总结一下,我们可以把android分为四个层次,从底层往上依次为:linux内核、C/C++库、java框架和java应用程序。简单的从上到下,android应用程序需要有java框架支持,比如它要发送短信,就需要java框架,java框架其实就是将C/C++库包装成为了一个JNI(JavaNativeInterface),而实现具体的功能是C/C++库,最后驱动硬件完成功能,这也就是linux内核部分。从Android的架构可以知道,android设备的开发主要是Linux内核层的驱动开发、framework层的系统级开发和applications层的应用程序开发。虽然android的framework开发比较少,但是对其了解后更有利于整体开发的进行,当然很多设备厂商还是非常需要这些的。Android系统启动过程•Android系统启动可以分为两个阶段,分别是linux启动和android启动。它们分别代表了Linux内核启动过程和android服务的启动过程。下面我们以mt6573平台为例,大致描述下linux启动过程,想知道详细的代码级的启动过程,需要个人研究代码,这里不打算从代码去分析它们。•Linux包括了bootloader和kernel(vmlinux)两部分。Mt6573平台为例,bootloader=preloader+uboot。在mt6573中,kernel(vmlinux)和ramdisk(ramdisk.img)被一起包裹在bootimage(boot.img)中,所以,kernel启动就是bootimage的启动。Linux启动•Mt6573开始上电到Linux系统运行完成,分成下面的几步:1)上电开始,运行常驻在bootrom中的bootcode,bootcode代码会把烧入在Nand中的preloader拷贝到ISRAM中,跳转到Preloader执行;2)执行preloader,preloader代码将烧入在Nand中的uboot拷贝DRAM中,然后跳转到uboot执行3)uboot对硬件进行初步的初始化,比如关闭WATCHDOG、改变系统时钟、初始化存储控制器、初始化lcd控制器等,然后从NAND中装入bootimg,跳转到bootimg,引导kernel执行。4)kernel会进一步初始化硬件,比如内存、irq、timer、console和cache初始化等,载入built-in设备驱动,完成启动。Kernel启动后会创建若干内核线程(kernelthread),之后装入并执行程序/sbin/init/,装入initprocess,切换至userspace。Android启动Android从Linux系统启动有4个步骤;(1)init进程启动(2)Native服务(Linux运行空间的进程或服务,最重要的一个服务就是servicemanager)启动(3)SystemServer,Android服务启动(4)Home启动•init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程.Init进程首先初始化log系统,然后根据init.rc和init.XX.rc(硬件平台相关,比如marvell平台,init.marvell.rc)脚本建立了几个基本的服务:1)servicemanamger2)zygote3)…最后Init并不退出,而是担当起propertyservice的功能。第一步:initial进程(system/core/init/init.c)1.1脚本文件•init@System/Core/InitInit.c:parse_config_file(Init.rc)@parse_config_file(Init.marvel.rc)解析脚本文件:Init.rc和Init.xxxx.rc(硬件平台相关)Init.rc是Android自己规定的初始化脚本(AndroidInitLanguage,System/Core/Init/readme.txt)该脚本内容包含:Commands:命令Actions:动作Triggers:触发条件Services:服务Options:选项Properties:属性(1)Commands是一些基本的操作,例如:mkdir/sdcard0000systemsystemmkdir/systemmounttmpfstmpfs/sqlite_stmt_journalssize=4m这些命令在init可执行程序中被解析,然后调用相关的函数来实现。(2)Actions(动作)表示一系列的命令,通常在Triggers(触发条件)中调用,动作和触发条件的形式为:ontriggercommandcommandcommand动作的使用示例如下:oninitexportPATH/sbin:/system/sbin:/system/bin:/system/xbinmkdir/systeminit表示一个触发条件,这个触发事件发生后,进行设置环境变量和建立目录的操作称为一个“动作”(3)Services(服务)通常表示启动一个可执行程序,Options(选项)是服务的附加内容,用于配合服务使用。servicevold/system/bin/voldsocketscketstream0660rootmountservicebootsound/system/bin/playmp3usermediagroupaudiooneshotvold和bootsound分别是两个服务的名称,/system/bin/vold和/system/bin/playmp3分别是他们所对应的可执行程序。socket、user、group、oneshot就是配合服务使用的选项。socket表示为vold程序分配一个socket资源,这里是创建一个名字为scket,类型为stream的socket。oneshot选项表示该服务只启动一次,而如果没有oneshot选项,这个可执行程序会一直存在--如果可执行程序被杀死,则会重新启动。(4)Properties(属性)是系统中使用的一些值,可以进行设置和读取。setpropro.FOREGROUND_APP_MEM1536setpropro.VISIBLE_APP_MEM2048onproperty:ro.kernel.qemu=1startadbdsetprop用于设置属性,onproperty可以用于判断属性,这里的属性在整个Android系统运行中都是一致的。init脚本的关键字可以参考init进程的system/core/init/keyword.h文件init.rc的使用方法,可以参考说明文件system/core/init/readme.txt如果想要修改启动过程只需要修改init.c(system/core/init)或者init.rc里的内容即可.1.2服务启动机制我们来看看Init是怎样解析.rc文件开启服务的。(1)打开.rc文件,解析文件内容@system/core/init/init.c将service信息放置到service_list中。@system/core/init/parser.c(2)restart_service()@system/core/init/init.cservice_startexecve(…).建立service进程。ServicemanagerServiceManager在init.rc文件中的服务启动项:serviceservicemanager/system/bin/servicemanagerAndroid中ServiceManager的源码位于:platform\frameworks\base\cmd\servicemanager\Service_manager.cpp,我们发现了main函数,说名它本身也是一个进程。ServiceManager服务是负责管理服务。客户端(应用程序)需要向ServiceManager来查询和获得所需要服务。服务也需ServiceManager注册自己以供客户端查询。可以看出ServiceManager是服务的大管家。ServiceManager是通过字符驱动设备/dev/binder,在客户端和server之间的传递数据。第二步Zygote•Servicemanager和zygote进程