2022年Android操作系统[归 .pdf

上传人:Che****ry 文档编号:27261510 上传时间:2022-07-23 格式:PDF 页数:12 大小:114.72KB
返回 下载 相关 举报
2022年Android操作系统[归 .pdf_第1页
第1页 / 共12页
2022年Android操作系统[归 .pdf_第2页
第2页 / 共12页
点击查看更多>>
资源描述

《2022年Android操作系统[归 .pdf》由会员分享,可在线阅读,更多相关《2022年Android操作系统[归 .pdf(12页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、下面介绍如何烧写一个完整的Android 操作系统。 bootloader、kernel、rootfs 的镜像最后都要烧在 nandflash 下,先了解一下nandflash 的分区情况以避免出现前后覆盖的情况:分区名称地址范围分区描述bootloader 0 x000000000 x0003FFFF 烧写 Uboot的分区kernel 0 x000400000 x003FFFFF 烧写 linux内核的分区cramfs 0 x004000000 x007FFFFF 烧写 cramfs格式文件系统(用作备份)Ubifs 0 x008000000 x3FFFFFFF 烧写 ubifs格式文件系

2、统(真正的文件系统)介绍一级目录的大体功能:bin:这个目录主要用来放下载android 代码的执行文件。bionic: Android的 libc 库,包含了一些基础库,其存在的意义在于其可规避GPL,同时减少库的体积,针对arm 进行指令和内存优化。bootable:启动和恢复相关的代码和工具。build :Android 工程编译的规则脚本,是其建立Android 系统的核心。cts: 兼容性测试的文件。dalvik :Android 自己开发的JAVA 虚拟机。development:程序开发所需要的模板和工具。external:第三方的一些软件和库。frameworks :应用程序框

3、架。hardware:与硬件相关的库。kernel:Android 的 linux kernel 2.6.XX内核。out:编译后输出的文件,比如SDK,文件系统等等。Makefile : Android 整个工程编译的配置文件。packages:Android 应用程序。prebuilt :各种平台下编译所需的脚本和交叉编译工具。system:Android 底层的系统接口和工具。vendor:保存不同厂家的配置和特别的文件要想 Android 运行起来,不但要编译内核正确,还需要有正确地安装根文件系统,才可以运行起来第一步, 就是从模拟器里提取data目录的数据。 也许你会问, 为什么要从

4、模拟器里提取呢?因为这样做是最方便的,不必要每个目录和文件,都要自己去建立。在一个终端里运行模拟器,并且运行android 系统正常,然后再打开一个终端,在这个终端里运行adb 来获取模拟器的文件,如下命令:adb pull /data /nfsboot/data 这样就可以从模拟器里下载到data、system 目录到本地目录。第二步,把从模拟器里提出来的data目录拷贝到android 编译出来的目录: Android-2.0/out/target/product/generic/root目录下面,并把相同的目录覆盖。名师资料总结 - - -精品资料欢迎下载 - - - - - - - -

5、 - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 12 页 - - - - - - - - - 第三步,把Android-2.0/out/target/product/generic/system目录下所有文件复制到目录:Android-2.0/out/target/product/generic/root/system目录下面。第四步, 修改目录Android-2.0/out/target/product/generic/root/下的 init.rc 文件, 注释掉下面几句:mount rootfs rootfs / ro remount

6、mount yaffs2 mtdsystem /system mount yaffs2 mtdsystem /system ro remount mount yaffs2 mtduserdata /data nosuid nodev mount yaffs2 mtdcache /cache nosuid nodev 由于不使用yaffs2 文件系统要把这些注释掉。到这里, root 下的内容就是一个完整可用的android 根文件系统,开发板就可以通过nfs 的方式来加载,不过要把这个目录设置为777 的权限属性,否则启动会失败。为了把这个根文件系统烧写到开发板里,需要把root 打包,在终端

7、里运行下面的命令:tar zcvf android.tar.gz * 这样就得到android.tar.gz 文件,就可以按前面的办法来固化到flash 里面了用 nfs下载固件嵌入式 Linux 的 NFS 开发环境的实现包括两个方面:一是Linux 服务器端的NFS 服务器支持;二是嵌入式目标系统的NFS 客户端的支持。因此,NFS 开发环境的建立需要配置Linux 服务器端和嵌入式目标系统端。1Linux 服务器端NFS 服务器的配置以 root 身份登陆Linux 服务器,编辑/etc 目录下的共享目录配置文件exports,指定共享目录及权限等。执行如下命令编辑文件/etc/expo

8、rts: #gedit /etc/exports 或者使用#sudo gedit /etc/exports 在该文件里添加如下内容:/nfsboot *(rw,sync,no_root_squash) 然后保存退出。添加的内容表示:允许 ip 地址范围是所有 IP 地址的计算机以读写的权限来访问/nfsboot 目录。 /nfsboot 也称为服务器输出共享目录。括号内的参数意义描述如下:rw:读 /写权限,只读权限的参数为ro;sync:数据同步写入内存和硬盘,也可以使用async,此时数据会先暂存于内存中,而不立即写入硬盘。no_root_squash:NFS 服务器共享目录用户的属性,如

9、果用户是root,那么对于这个共享目录来说就具有root 的权限。接着执行如下命令,启动端口映射:# /etc/rc.d/init.d/portmap start 最后执行如下命令启动NFS 服务,此时NFS 会激活守护进程,然后就开始监听Client 端的请求: # /etc/rc.d/init.d/NFS start 用户也可以重新启动Linux 服务器,自动启动NFS 服务。在 NFS 服务器启动后,一般需要关闭防火墙服务iptables F。我们首先在Linux 服务器上进行 NFS 服务器的回环测试,验证共享目录是否能够被访问。在Linux 服务器上运行如下命令:# mount t

10、NFS 192.168.1.20:/home/work /mnt # ls /mnt 命令将 Linux 服务器的NFS 输出共享目录挂载到/mnt 目录下,因此,如果 NFS 正常工作,名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 12 页 - - - - - - - - - 应该能够在 /mnt 目录看到 /home/work 共享目录中的内容。2、Linux 内核里添加NFS 支持3、在 UBOOT 里设置启动参数如下:setenv bootargs noinit

11、rd root=/dev/nfs console=ttySAC0 init=/init nfsroot=192.168.1.103:/nfsboot ip=192.168.1.20:192.168.1.103:192.168.1.1:255.255.255.0:eth0:on 通过上面的参数设置,就可避免去烧写FLASH 的过程,直接把电脑主机里的目录当作文件系统,这样可以方便修改测试任何程序,当完全调试完成后,就可以烧写到FLASH 里加载并运行用 tftp方式从 linux主机下载文件到开发板里运行1. 安装 tftp :sudo apt-get install tftp tftpd 建立

12、 tftp 服务器目录cd / sudo mkdir tftpboot sudo chmod 777 tftpboot 接着修改tftp 服务器配置的目录:sudo gedit /etc/inetd.conf tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /tftpboot 重新启动服务sudo /etc/init.d/openbsd-inetd restart sudo in.tftpd l /tftpboot 在/tftpboot 目录下面建立一个文件:cd /tftpboot touch testfile 在进入

13、另外一个目录里面:tftp 127.0.0.1 tftpget testfile 如果在这个目录下面看到testfile 文件,就说明安装服务器,否则就是安装失败了。2 在开发板里设置uboot 的 tftp 下载参数,先来设置开发板上的IP 地址:setenv ipaddr 192.168.1.20 这里设置IP 地址为 192.168.1.20。设置 tftp 服务器的IP 地址: setenv serverip 192.168.1.103 这里的 IP 地址 192.168.1.103 是电脑 ubuntu 的 IP 地址,也就是tftp 服务所在的IP 地址。在开发板里运行uboot

14、之后,就可以输入下面的命令来测试是否可以从tftp 服务器里加载linux 内核文件zImage,当然是需要把这个文件放到/tftpboot 目录下面。如下命令:tftp c0008000 zImage 这里 c0008000 是下载开发板里内存起始地址,zImage 是需要下载的文件名称Android 的代码是比较庞大的,如果要全部编译一遍,是花费比较多时间,这样导致开发效率非常低, 那么有没有办法只编译修改那一部份代码呢?答案是肯定有的,因为面对这么多代码,如果没有好的方法是开发不成功的。下面就来学习怎么样单个目录编译的方法。在 android 的顶层目录里,运行下面的命令:. build

15、/envsetup.sh 运行命令后,就添加了很多命令到sh 解释器,具体命令如下:- croot: Changes directory to the top of the tree. 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 12 页 - - - - - - - - - - m: Makes from the top of the tree. - mm: Builds all of the modules in the current directory. - m

16、mm: Builds all of the modules in the supplied directories. - cgrep: Greps on all local C/C+ files. - jgrep: Greps on all local Java files. - resgrep: Greps on all local res/*.xml files. - godir: Go to the directory containing a file. 其中命令croot 是改变到顶层目录;m 是编译源码树;mm 是编译当前目录下所有模块;mmm 是编译所有满足条件编译的模块;cgr

17、ep 是查找本地所有C/C+文件; jgrep 是查找本地所有 java 文件; resgrep是查找本地所有资源文件res/*.xml ;godir 是跳到包括这个文件的目录。下面就是演示使用命令来编译一个目录:tonytony-desktop:/arm/Android-2.0/system/core$ mm PLATFORM_VERSION_CODENAME=AOSP PLATFORM_VERSION=AOSP TARGET_PRODUCT=generic TARGET_BUILD_VARIANT=eng TARGET_SIMULATOR= TARGET_BUILD_TYPE=releas

18、e TARGET_ARCH=arm HOST_ARCH=x86 HOST_OS=linux HOST_BUILD_TYPE=release BUILD_ID=MASTER make:进入目录 /home/tony/arm/Android-2.0 这个命令是在目录/arm/Android-2.0/system/core 开始编译, 这样编译速度就可以提高很多了Andriod 主进程android 系统的初始化过程是从那里开始呢?它在加载linux 基本内核后, 就开始运行一个初始化进程,叫做init 进程 ,那么怎么样知道它是加载init 进程的呢?难道上天就注定的吗?呵呵,不是的,原来是从an

19、droid 加载 linux 内核时,就设置了下面的参数:Kernel command line: noinitrd root=/dev/nfs console=ttySAC0 init=/init nfsroot=192.168.1.103:/nfsboot ip=192.168.1.20:192.168.1.103:192.168.1.1:255.255.255.0:eth0:on 在这行命令里,就是告诉linux 内核初始化完成后开始运行init 进程,由于init 进程就是放在系统根目录下面。而这个进程的代码,就是位于源码的目录system/core/init 下面, 现在就来仔细地分

20、析这个进程到底做了什么事情,以便理解整个系统运行情况。在分析过程中, 会学习很多有用知识,甚至linux 编程知识。这么有用,还等什么呢?现在就开始,找到目录system/core/init/init.c 代码,先从main 函数开始,如下:#001 int main(int argc, char *argv) #002 #003 int device_fd = -1; #004 int property_set_fd = -1; #005 int signal_recv_fd = -1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - -

21、 - - 名师精心整理 - - - - - - - 第 4 页,共 12 页 - - - - - - - - - #006 int keychord_fd = -1; #007 int fd_count; #008 int s2; #009 int fd; #010 struct sigaction act; #011 char tmpPROP_VALUE_MAX; #012 struct pollfd ufds4; #013 char *tmpdev; #014 char* debuggable; #017 act.sa_handler = sigchld_handler; #018 act

22、.sa_flags = SA_NOCLDSTOP; #019 act.sa_mask = 0; #020 act.sa_restorer = NULL; #021 sigaction(SIGCHLD, &act, 0); 在上面这段代码里,调用函数sigaction 来 设置处理子进程发送回来的关闭信号,其中SIGCHLD 是设置子进程信号处理,SA_NOCLDSTOP是表示子进程结束时不要向父进程发送 SIGCHLD ,sigchld_handler 是信号SIGCHLD的处理函数。这样做的作用,就是如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。因此需要对

23、SIGCHLD 信号做出处理,回收僵尸进程的资源,避免造成不必要的资源浪费。#024 umask(0); linux中的umask 函数主要用于:在创建新文件或目录时屏蔽掉新文件或目录不应有的访问允许权限,就是设置允许当前进程创建文件或者目录最大可操作的权限 (0 & mode 等于 0777 & mode)#030 mkdir(/dev, 0755); #031 mkdir(/proc, 0755); #032 mkdir(/sys, 0755); 在当前内存模拟磁盘里建立一个基本的文件系统,以便后面加载rc 文件来做其它事情。/dev是 devfs(设备文件系统)或者udev 的挂在点所在

24、。在使用devfs 的内核里如果没有/dev,根本见不到Shell 启动的信息,因为内核找不到/dev/console;在使用udev 的系统里,也事先需要在 /dev 下建立 console 和 null 这两个节点。关于devfs 和 udev 的区别,网上很多文章说。当然如果你的内核已经不支持devfs 了( 2.6.12 以后) ,可以使用纯纯的静态节点。也就是用 mknod 人工生成。 /proc 是用来挂载存放系统信息虚拟文件系统 proc 文件系统 , proc 文件系统 在内核里面可以选。 如果没有 proc 文件系统 , 很多 Shell 自己的命令就没有办法运行,比如 if

25、config 。 proc 文件系统 不像 devfs 可以自动挂载,它需要使用初始化脚本挂载。另外,udev 也需要 proc 文件系统 的支持。 /sys 用于挂载 sysfs 文件系统 , sysfs 文件系统 在内核里面可以选#034 mount(tmpfs, /dev, tmpfs, 0, mode=0755); #035 mkdir(/dev/pts, 0755); #036 mkdir(/dev/socket, 0755); #037 mount(devpts, /dev/pts, devpts, 0, NULL); #038 mount(proc, /proc, proc, 0

26、, NULL); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 12 页 - - - - - - - - - #039 mount(sysfs, /sys, sysfs, 0, NULL); 在 Linux 中将一个文件系统与一个存储设备关联起来的过程称为挂装(mount) 。 使用mount 命令将一个文件系统附着到当前文件系统层次结构中(根)。在执行挂装时,要提供文件系统类型、文件系统和一个挂装点。因此,这里就是把tmpfs 文件系统加到目录/dev 下面,文件系统

27、的名称是tmpfs。 tmpfs 是一个虚拟内存文件系统,它不同于传统的用块设备形式来实现的 Ramdisk,也不同于针对物理内存的Ramfs。Tmpfs 可以使用物理内存,也可以使用交换分区。在Linux 内核中,虚拟内存资源由物理内存(RAM) 和交换分区组成,这些资源是由内核中的虚拟内存子系统来负责分配和管理。Tmpfs 向虚拟内存子系统请求页来存储文件,它同 Linux 的其它请求页的部分一样,不知道分配给自己的页是在内存中还是在交换分区中。同Ramfs 一样,其大小也不是固定的,而是随着所需要的空间而动态的增减。接着创建 pts和 socket 目录, 在 /dev/pts 挂装 d

28、evpts 虚拟文件系统,在目录 /proc 挂装 proc 文件系统,在目录 /sys 挂装 sysfs 文件系统。#047 open_devnull_stdio(); 这段代码是创建空的设备节点(/dev/null ) 。#048 log_init(); 这段代码是创建kmsg(/dev/kmsg)节点,主要用来输出LOG 信息。比如把LOG 信息输出到开发板的串口上,再在电脑上打印出来,方便跟踪和调试系统的功能。#051 ERROR(Init:main() %sn, caijunsheng 2010-07-13); 这里是我测试系统引导输出的一行LOG 代码。#053 INFO(read

29、ing config filen); #054 parse_config_file(/init.rc); 这段代码是分析根目录下面的init.rc 配置文件, 并且把里面的参数组成链表的方式,以便后面使用,后面再来仔细地分析init.rc 文件的格式和内容。#056 /* pull the kernel commandline and ramdisk properties file in */ #057 qemu_init(); 这里初始化qemu 模拟器运行计数,这里是指模拟ARM 指令的虚拟系统。#058 import_kernel_cmdline(0); 这段代码是从linux 内核里获

30、取引导系统给内核的引导参数,并保存到全局变量,以便使用 . #060 get_hardware_name(); 这段代码是获取当前android 系统运行的硬件信息,比如硬件的CPU 名称。主要从/proc/cpuinfo 里读到相关的信息。#061 snprintf(tmp, sizeof(tmp), /init.%s.rc, hardware); #062 parse_config_file(tmp); 这段代码是从前面获取到的硬件名称,然后以硬件的名称(/init. 硬件名称 .rc)来获取相应硬件的配置文件,并且把配置文件参数加载到链表里。#064 action_for_each_tr

31、igger(early-init, action_add_queue_tail); #065 drain_action_queue(); 这 段 代 码 是 先 把 有early-init标 识 的 命 令 提 前 添 加 到 一 个 命 令 队 列 , 以 便 函 数drain_action_queue 一个一个命令地执行配置文件里的函数,这样可以在不同的配置文件里,只要标明是最先执行的函数,就可以优先地运行。#067 INFO(device initn); #068 device_fd = device_init(); 这段代码是遍历为/sys,添加设备事件响应,创建设备节点。名师资料总结

32、 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 12 页 - - - - - - - - - #070 property_init(); 这段代码是进行属性初始化。每个属性都有一个名称和值,它们都是字符串格式。属性被大量使用在 Android 系统中, 用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set 属性。在系统初始化时,Android 将分配一个共享内存区来存储的属性,这里主要是从/default.prop 属性文件读取属性。这个有点

33、像Windows 下的注册表的作用。#072 / only listen for keychords if ro.debuggable is true #073 debuggable = property_get(ro.debuggable); #074 if (debuggable & !strcmp(debuggable, 1) #075 keychord_fd = open_keychord(); #076 这段代码是从属性里获取调试标志,如果是可以调试,就打开组合按键输入驱动程序。#078 if (console0) #079 snprintf(tmp, sizeof(tmp), /d

34、ev/%s, console); #080 console_name = strdup(tmp); #081 #083 fd = open(console_name, O_RDWR); #084 if (fd = 0) #085 have_console = 1; #086 close(fd); 这段代码是判断是否有控制台,如果没有,就尝试是否是可以打缺省的控制台。#088 if( load_565rle_image(INIT_IMAGE_FILE) ) #089 fd = open(/dev/tty0, O_WRONLY); #090 if (fd = 0) #091 const char

35、*msg; #092 msg = n #093 n #094 n #095 n #096 n #097 n #098 n / console is 40 cols x 30 lines #099 n #100 n #101 n #102 n #103 n #104 n #105 n #106 A N D R O I D ; #107 write(fd, msg, strlen(msg); #108 close(fd); #109 #110 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - -

36、第 7 页,共 12 页 - - - - - - - - - 这段代码是先调用load_565rle_image 函数来尝试加载定制的显示的LOGO 图片,如果不成功,就直接在屏幕上显示字符串android。通过这里可以定制不同厂家的LOGO 图片显示,以便在系统初始化时,进行更人性化的等待,更加漂亮个性#112 if (qemu0) #113 import_kernel_cmdline(1); 这段代码是用来判断是否使用模拟器运行,如果时,就加载内核命令行参数。#115 if (!strcmp(bootmode,factory) #116 property_set(ro.factorytes

37、t, 1); #117 else if (!strcmp(bootmode,factory2) #118 property_set(ro.factorytest, 2); #119 else #120 property_set(ro.factorytest, 0); 这段代码是根据内核命令行参数来设置工厂模式测试,比如在工厂生产手机过程里需要自动化演示功能,就可以根据这个标志来进行特别处理。#122 property_set(ro.serialno, serialno0 ? serialno : ); 这段代码是设置手机序列号到属性里保存,以便上层应用程序可以识别这台手机。#123 prope

38、rty_set(ro.bootmode, bootmode0 ? bootmode : unknown); 这段代码是保存启动模式到属性里。#124 property_set(ro.baseband, baseband0 ? baseband : unknown); 这段代码是保存手机基带频率到属性里。#125 property_set(ro.carrier, carrier0 ? carrier : unknown); 这段代码是保存手机硬件载波的方式到属性里。#126 property_set(ro.bootloader, bootloader0 ? bootloader : unknow

39、n); 这里是保存引导程序的版本号到属性里,以便系统知道引导程序有什么特性。#128 property_set(ro.hardware, hardware); 这里是保存硬件信息到属性里,其实就是获取CPU 的信息。#129 snprintf(tmp, PROP_V ALUE_MAX, %d, revision); #130 property_set(ro.revision, tmp); 这里是保存硬件修订的版本号到属性里,这样可以方便应用程序区分不同的硬件版本。#132 /* execute all the boot actions to get us started */ #133 act

40、ion_for_each_trigger(init, action_add_queue_tail); #134 drain_action_queue(); 这段代码是先把所有init 命令添加队列,然后再执行。#136 /* read any property files on system or data and #137 * fire up the property service. This must happen #138 * after the ro.foo properties are set above so #139 * that /data/local.prop cannot

41、 interfere with them. #140 */ #141 property_set_fd = start_property_service(); 这段代码是加载system和 data目录下的属性,并启动属性监听服务。#143 /* create a signalling mechanism for the sigchld handler */ #144 if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) = 0) #145 signal_fd = s0; #146 signal_recv_fd = s1; 名师资料总结 - - -精品资料欢迎下载

42、 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 12 页 - - - - - - - - - #147 fcntl(s0, F_SETFD, FD_CLOEXEC); #148 fcntl(s0, F_SETFL, O_NONBLOCK); #149 fcntl(s1, F_SETFD, FD_CLOEXEC); #150 fcntl(s1, F_SETFL, O_NONBLOCK); #151 这 段代码是创建一个全双 工的通讯机制的两个SOCKET , 信号可以在signal_fd和signal_recv_

43、fd 双向通讯, 从而建立起沟通的管道。其实这个信号管理,就是用来让init 进程与它的子进程进行沟通的,子进程从signal_fd 写入信息, init 进程从 signal_recv_fd 收到信息,然后再做处理。#153 /* make sure we actually have all the pieces we need */ #154 if (device_fd 0) | #155 (property_set_fd 0) | #156 (signal_recv_fd 0) #182 ufds3.fd = keychord_fd; #183 ufds3.events = POLLIN

44、; #184 fd_count+; #185 else #186 ufds3.events = 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 12 页 - - - - - - - - - #187 ufds3.revents = 0; #188 这段代码是判断是否处理组合键轮询。#190 #if BOOTCHART #191 bootchart_count = bootchart_init(); #192 if (bootchart_count 0) #195 N

45、OTICE(bootcharting started (period=%d ms)n, bootchart_count*BOOTCHART_POLLING_MS); #196 else #197 NOTICE(bootcharting ignoredn); #198 #199 #endif 这段代码是初始化linux 程序启动速度的性能分析工具,这个工具有一个好处,就是图形化显示每个进程启动顺序和占用时间,如果想优化系统的启动速度,记得启用这个工具#201 for(;) #202 int nr, i, timeout = -1; 这段代码是进入死循环处理,以便这个init 进程变成一个服务。#

46、204 for (i = 0; i fd_count; i+) #205 ufdsi.revents = 0; 这段代码是清空每个socket 的事件计数。#207 drain_action_queue(); 这段代码是执行队列里的命令。#208 restart_processes(); 这句代码是用来判断那些服务需要重新启动。#210 if (process_needs_restart) #211 timeout = (process_needs_restart - gettime() * 1000; #212 if (timeout 0) #218 if (timeout BOOTCHAR

47、T_POLLING_MS) #219 timeout = BOOTCHART_POLLING_MS; #220 if (bootchart_step() 0 | -bootchart_count = 0) #221 bootchart_finish(); #222 bootchart_count = 0; #223 #224 #225 #endif 这段代码是用来计算运行性能。#226 nr = poll(ufds, fd_count, timeout); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - -

48、 - - - - 第 10 页,共 12 页 - - - - - - - - - #227 if (nr = 0) #228 continue; 这段代码用来轮询几个socket 是否有事件处理。#230 if (ufds2.revents = POLLIN) #231 /* we got a SIGCHLD - reap and restart as needed */ #232 read(signal_recv_fd, tmp, sizeof(tmp); #233 while (!wait_for_one_process(0) #234 ; #235 continue; #236 这段代码

49、是用来处理子进程的通讯,并且能删除任何已经退出或者杀死死进程,这样做可以保持系统更加健壮性,增强容错能力。#238 if (ufds0.revents = POLLIN) #239 handle_device_fd(device_fd); 这段代码是处理设备事件。#241 if (ufds1.revents = POLLIN) #242 handle_property_set_fd(property_set_fd); 这段代码是处理属性服务事件。#243 if (ufds3.revents = POLLIN) #244 handle_keychord(keychord_fd); 这段代码是处理

50、调试模式下的组合按键。#245 #247 return 0; #248 #249 到这里已经分析完成init 进程的主流程,后面再来详细地其它功能实现名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 12 页 - - - - - - - - - 在 ubuntu10.04 最新版本下编译android 出错解决Install: out/host/linux-x86/bin/dx host Executable: aapt (out/host/linux-x86/obj/E

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁