Android2.2 boot process details

Android2.2 boot process details

[正文开始]

启动第一步--CPU固件启动

对于桌面PC来说,存在bios和mbr(master boot record)。而多数移动设备不存在bios,CPU上电reset后从固件mbr开始执行必要的初始动作,然后就是load Boot程序。

启动第二步--Boot Loader

Boot Loader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好一切准备。

常见BootLoader有U-boot,x-boot。以我参考平台君正JZ4770(mips)x-boot为例:
1. 链接文件x-boot.lds指名boot入口函数ENTRY(_start)
2. Boot/init/init.S跳转到C函数boot_main
3. 初始化板极gpio,ldo
4. Lcd init,显示开机logo
5. nand_boot(NORMAL_BOOT)
6. Load kernel和ramdisk img到内存
7. 通过制定kernel image起始地址跳转到kernel,
kernel=(void(*)(int,char**,char*))CFG_KERNEL_DST;
(*kernel)(2, (char **)(PARAM_BASE + 16), (char *)PARAM_BASE);

启动第三步--加载内核

1. 链接文件vmlinux.lds指定kernel入口函数ENTRY(kernel_entry)
2. 跳转到C函数start_kernel
3. 内存,中断,时钟,控制台等初始化
4. 最后rest_init中do_basic_setup,do_initcalls开始进行外设的挂载,外设的挂载过程后面再详述
5. 至此Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了
6. init_post启动了第一个程序run_init_process("/init")

启动第四步--用户层init

内核被加载后,最开始运行的程序便是/init,并依据此文件来进行初始化工作。
源代码位置:/system/core/init,其作用:

http://bbs.hiapk.com/thread-6388-1-1.html 这篇帖子大致说明了init程序作用,最主要的就是:
1. 解析/init.rc文件。/system/core/init/readme.txt是对init.rc文件的编写说明,主要由四大类声明组成:行为类(Actions),命令类(Commands),服务类(Services),选项类(Options)
2. 解析文件/init.goldfish.rc(平台名称),parse_config_file将action和service保存在两个链表action_list与service_list中
3. 显示开机log图片,如果失败显示ANDROID字符
4. 最后进入主程序循环:
nr = poll(ufds, fd_count, timeout);
if (ufds[0].revents == POLLIN)
handle_device_fd(device_fd);
if (ufds[1].revents == POLLIN)
handle_property_set_fd(property_set_fd);
if (ufds[3].revents == POLLIN)
handle_keychord(keychord_fd);
主循环主要是监听两个localSocket和"/dev/keychord"文件:
 device_fd是基于getpid的localSocket,用于监听设备plugin,plugout事件,handle_device_fd负责设备挂载移除;
 property_set_fd是localSocket "property_service"的fd,负责监听是否有property属性改变。终端模式下我们可以通过执行命令 setprop改变属性,工具源代码所在文件:/system/core/toolbox。所以如果在终端下输入:setprop property:persist.service.adb.enable 1或者0,那么将会开启或者关闭adbd 程序。
 keychord_fd是文件"/dev/keychord"句柄,感觉是debug模式下用来重新service_start(svc, NULL)的接口

启动第五步--关键服务zygote

Init.rc启动了一个关键服务zygote,源代码位置:/framework/base/cmds/app_process。
AndroidRuntime::start方法启动虚拟机并调用”className”的”static void main(String[] args)”方法。利用JNIEnv,C++方法调用JAVA class的案例,具体没研究。
Runtime.start(“com.android.internal.os.ZygoteInit”,startSystemServer)调用ZygoteInit.main()
Zygote 是android 系统中最重要的一个服务,它将一步一步完成下面的任务:
1. 创建JAVA 虚拟机
2. 为JAVA 虚拟机注册android 本地函数
3. 调用 com.android.internal.os.ZygoteInit 类中的main函数
 装载ZygoteInit类
 注册registerZygoteSocket();
 装载preloadClasses();
 装载preloadResources();
4.调用 Zygote::forkSystemServer (源代码位置:/dalvik/vm/native/dalvik_system_Zygote.c)来fork一个新的进程,在新进程中调用 com.android.server.SystemServer 的main函数。
 装载 libandroid_servers.so库
5.调用native init1:/frameworks/base/services/jni/com_android_server_SystemServer.cpp.
 初始化SurfaceFlinger::instantiate();
 初始化AudioFlinger::instantiate();
 初始化MediaPlayerService::instantiate();
 初始化CameraService::instantiate();
 初始化AudioPolicyService::instantiate();
补充:模拟器上后面四个service是由system_server启动的,deivce上这四个service是由mediaserver启动的,专门为多媒体起了一个进程。
6.Callback回调runtime->callStatic("com/android/server/SystemServer", "init2");
SystemServer::init2 将会启动一个新的线程"android.server.ServerThread"来启动下面的所有JAVA服务:
Core 服务:
 Starting Power Manager(电源管理)
 Creating Activity Manager(活动服务)
 Starting Telephony Registry(电话注册服务)
 Starting Package Manager(包管理器)
 Set Activity Manager Service as System Process
 Starting Context Manager
 Starting System Context Providers
 Starting Battery Service(电池服务)
 Starting Lights Service(Lights服务)
 Starting Vibrator Service(振动器服务)
 Starting Alarm Manager(闹钟服务)
 Starting Watchdog Service (看门狗服务)
 Starting Sensor Service
 Starting Window Manager(启动窗口管理器)
 Starting Bluetooth Service(蓝牙服务)
 Starting Mount Service
其他services:
 Starting Status Bar Service(状态服务)
 Starting Hardware Service(硬件服务)
 Starting NetStat Service(网络状态服务)
 Starting Connectivity Service
 Starting Notification Manager
 Starting DeviceStorageMonitor Service
 Starting Location Manager
 Starting Search Service(查询服务)
 Starting Clipboard Service
 Starting Checkin Service
 Starting Wallpaper Service
 Starting Audio Service
 Starting HeadsetObserver
 Starting AdbSettingsObserver
补充:Init.rc中列出的service是指需要fork()得到子进程,而init2中starting service只是添加一个binder给ServiceManager,给其他进程提供服务。
7.android.server.ServerThread最后通知activity manager开始launching init applications
 ((ActivityManagerService)ActivityManagerNative.getDefault()).systemReady
 ActivityManagerService.resumeTopActivityLocked(null); 通过发送Intent.CATEGORY_HOME intent来启动第一个 activity,至此我们就看到了熟悉的launcher界面。

在背后,还有复杂的底层函数调用与实现,本文仅供大家参考学习,如有错误请不吝指正!

本文参考了如下文章,荟萃而成:

http://roclinux.cn/?p=1301
http://blog.chinaunix.net/uid-2630593-id-2955923.html
http://bbs.hiapk.com/thread-6388-1-1.html
http://blog.chinaunix.net/uid-27025492-id-3280767.html

感谢上述文章作者:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值