Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1071591
  • 博文数量: 277
  • 博客积分: 8313
  • 博客等级: 中将
  • 技术积分: 2976
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-22 11:25
文章分类

全部博文(277)

文章存档

2013年(17)

2012年(66)

2011年(104)

2010年(90)

我的朋友

分类: LINUX

2011-04-29 14:42:55

首先看看整体开机流程。这个对于软件开发测试工作非常有用,特别是在项目初期的时候,通常出在驱动或者启动参数上面的问题比较多,比如关机充电,连接char

ger关机等问题。

一般开机过程大致可以分为三个大阶段:

1. OS级别,由bootloader载入linux kernel后(注:bootloader和制造商有关,一般都是自己修改后的bootloader,大同小异,无外乎加载了自己的安全机制,我们可以用最常见的uboot来考虑),kernel开始初始化, 并载入built-in的驱动程序。Kernel完成开机后,载入init process,切换至user-space后,结束kernel 的循序过程(sequence),进入排程模式(process scheduling)。

2. Android-level,由init process 开始,读取init.rc,Native 服务启动,并启动重要的外部程序,例如:servicemanager、Zygote以及System Server。

3. Zygote-Mode,Zygote 启动完SystemServer 后,进入Zygote Mode,在Socket 等候命令。随后,使用者将看到一个桌面环境(Home Screen)。桌面环境由一个名为[Launcher]的应用程序负责提供。

注:Zygote干嘛用的?主要负责启动system server和执行android程序(APK)。成功启动system server后会使用socket方式监听(monitor android apps/prcesses)



我们的image都包含什么?

Bootloader,system(是Android镜像),data(用户数据/data),kernel(android linux kernel,基础OS,负责process管理,HAL和一些系统程序),ramdisk(init装载, /system/init/init.c).

关于开机时间长短问题,对于产品开机和关机时间长短,直接影响到用户的感受,所以我们需要对开机时间进行评估。

Bootloader阶段,linux kernel阶段,android boot阶段(preload阶段,启动android service,启动launcher)

Android阶段启动过程分析:

Init会读取init process启动ril-daemon, media, bootsound, bootanim, servicemanager......

最重要的init会启动Zygote,然后Zygote会启动Davik VM,davikVM会启动systemserver,紧接着会把Framework启动,比如Activity Manager,Windows Manager... 还有一些Android服务程序。Activity Manager负责把Home引导完毕。

Android第一个启动进程init(system\core\init),这个在OS级别启动之后的第一个程序(用户程序),用它来完成引导过程。她会读取init.rc, init_xxx.rc(跟制造商有关), 按照脚本引导。引导完毕之后init并不退出,继续负责property service的工作



需要首先阅读init.rc启动参数文档,里面有很多启动过程说明:

例子:

   on boot

   首先设置环境变量

   export PATH /sbin:/system/sbin:/system/bin

   export LD_LIBRARY_PATH /system/lib

   创建文件目录并加载

   mkdir /dev

   mkdir /proc

   mkdir /sys

   mount tmpfs tmpfs /dev

   mkdir /dev/pts

   mkdir /dev/socket

   mount devpts devpts /dev/pts

   mount proc proc /proc

   mount sysfs sysfs /sys

   write /proc/cpu/alignment 4

   ifup lo

   hostname localhost

   domainname localhost

   mount yaffs2 mtd@system /system

   mount yaffs2 mtd@userdata /data

   导入init.conf

   import /system/etc/init.conf

   class_start default

启动service

service adbd /sbin/adbd

   user adb

   group adb

service usbd /system/bin/usbd -r

   user usbd

   group usbd

   socket usbd 666

启动zygote,启动了它,我们的桌面就有着落了。

service zygote /system/bin/app_process -Xzygote /system/bin --zygote

   socket zygote 666

service runtime /system/bin/runtime

   user system

   group system

on device-added-/dev/compass

   start akmd

on device-removed-/dev/compass

   stop akmd

service akmd /sbin/akmd

   disabled

   user akmd

   group akmd

第二步,就是要建立起android运行空间,担当此任务的是个重量级程序:Zygote,结合Servicemanager奠定了android运行基础。在init.rc(system\core\rootdir\init.rc)里面会有这一句话

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

   socket zygote stream 666

   onrestart write /sys/android_power/request_state wake

   onrestart write /sys/power/state on

   onrestart restart media

如果zygote因为启动某些服务导致异常退出后,init将会重新去启动它

Zygote启动main函数(\frameworks\base\cmds\app_process\app_main.cpp)

里面有一句话是首先建立Android Runtime: runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);//建立虚拟机

//启动runtime在{\frameworks\base\core\jni\AndroidRuntime.cpp},

建立ZygoteInit(\frameworks\base\core\java\com\android\internal\os\zygoteinit.java)(装载Zygote,装载preloaded classes,装载Load preload资源,调用ForkSystemServer来fork一个systemserver新进程。)

里面包含了Zygote的机制(socket方式):

registerZygoteSocket()建立socket server

acceptCommandPeer()接受Android应用的socket命令

closeServerSocket()关闭Android应用的连接

startSystemServer()启动systemserver很重要的一步

经过这些步骤Zygote就建立好了,利用socket进程间通讯方式,接收ActivityManagerService的请求,Fork应用程序(runForkMode()这个函数里面的Zygote.fork();映射到linux进程得到一个pid)(关于linux fork函数,详细请参考)

第三步: SystemServer:

在Zygote执行startSystemServer()之后,在Zygote上fork了一个进程com.android.server.SystemServer( pid = Zygote.forkSystemServer具体实现在具体实现在dalvik/vm/native/dalvik_system_Zygote.c)。

Android所有服务都是建立在SystemServer之上。这里需要简单介绍一下SystemServer(\frameworks\base\service\java\com\android\server\systemserver.java)

System.loadLibrary("android_servers");load android_servers.so,

调用Native方法init1()实现在com_android_server_SystemServer.cpp (frameworks\base\services\jni)其实仅调用system_init()(是现在System_init.cpp (frameworks\base\cmds\system_server\library)里面)

静态函数init2中启动一个新的线程来加载android服务:

(Entropy Service,Power Manager,Activity Manager,Telephony Registry,Package Manager,

Account Manager,Content Manager,SystemContent Providers,Battery Service,Hardware Service,Alarm Manager,Init Watchdog,Sensor Service,Window Manager,Bluetooth Service,Status Bar,Clipboard Service,InputMethod Service,NetStat Service,Connectivity Service,Accessibility Manager,Notification Manager,Mount Service,Device Storage Monitor,

Location Manager,Search Service,Checkin Service,Wallpaper Service,Audio Service,

Headset Observer,Dock Observer,Backup Service,AppWidget Service)

注意线程里面的这一句话,初始化完成了,给个systemReady()

// We now tell the activity manager it is okay to run third party

// code. It will call back into us once it has gotten to the state

// where third party code can really run (but before it has actually

// started launching the initial applications), for us to complete our

// initialization.

((ActivityManagerService)ActivityManagerNative.getDefault())

   .systemReady(new Runnable()

我们找到ActivityManagerService中的(实现在ActivityManagerService.java (frameworks\base\services\java\com\android\server\am))systemReady函数最后调用resumeTopActivityLocked,这个函数最终调用startHomeActivityLocked()来启动HOME程序,至此,我们的启动任务分析完成了。

参考文档:

http://blog.chinaunix.net/u1/38994/showart_1775465.html

http://blog.chinaunix.net/u1/38994/showart_1168440.html

http://blog.csdn.net/ruixj/archive/2010/05/26/5626816.aspx

阅读(2512) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~