Android从BIOS到Zygote到SystemService到Launcher启动概况
来源:互联网 发布:沈阳市软件工资 编辑:程序博客网 时间:2024/06/05 19:54
不想当将军的士兵不是好的士兵,作为Android开发 肯定好奇手机启动到运行经历了什么。最近有点时间,所以看了几本书。有《LINUX SYSTEM PROGRAMING》、《Android源码分析实录》。
只写流程和重要的几个点。代码都可以在《Android源码分析实录》上找到,太多我就不写了。
开机第一个程序BIOS:
BIOS程序启动,检查硬件。
BIOS是烧在主板上上的只读程序,叫做韧体。硬件的信息记录在CMOS(记录各种硬件参数且嵌入在主板上面的存储器)。
BIOS到硬盘读取第一个扇区的MBR(主引导分区块)。MBR存储了引导加载程序(BootLoader)
操作系统第一个程序BootLoader
引导加载程序BootLoader,用于加载系统的内核文件。是操作系统安装在MBR上的一套软件。
内核运行的第一个进程 init进程
pid为1。系统查找init程序的默认顺序(除非用户通过init内核命令指定)
- /sbin/init
- /etc/init
- /bin/init
- /bin/sh Bourne shell程序的位置
如果都没有找到,就会挂起系统(halt system with a panic)
Zygote进程
init进程启动中解析init.rc文件,其中有
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-serverclass mainsocket zygote stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart mediaonrestart restart netd
解析的代码是在system\core\init\init.c 的service_start方法
init进程执行 系统调用 (System call,从应用程序发起 进入到内核的函数,为了从操作系统获取 服务或资源) fork(生成新进程)、execve (加载程序到内存地址,并替换为当前进程的地址空间)zygote程序。
从而运行了zygote进程,代码是在/system/bin/app_process
(fork 从当前进程生成子进程,新进程执行方法的栈不变。通过返回值区分那个进程,0是子进程,父进程是自己的pid。exec系列的调用 子进程就不在当前的方法栈中执行了,而是直接在新程序的方法中执行)
void testFork() { pid_t pid; pid = fork(); if (pid > 0) printf("I am the parent of pid = %d!\n", pid); else if (!pid) printf("I am the child"); else if (pid == -1) perror("fork error");}
扫描文件发现socket选项
为zygote进程创建Socket。调用函数create_socket在/dev/socket目录下创建文件。create_socket中System call函数socket,返回一个文件描述符,保存到环境变量中。
Linux系统最重要的抽象概念 文件(其次是进程),Linux遵循 everything is a file的理念。除了普通文件,Linux支持四种特殊文件: 字符设备文件(键盘)、 快设备文 件(硬盘、CD)、命名管道(Named pipes)和Unix域套接字(Unix domain sockets)
所以socket也是文件,还有Android中的Binder、Ashmem(匿名共享内存)都是创建一个文件,获取文件描述符,然后进行读取、增删改等操作。举例/dev/socket/zygote;/dev/binder; /dev/ashmem; Binder就是打开binder文件,通过 System call函数mmap把设备内存映射到 用户进程地址空间。然后相当于两个进程,共同操作一个文件,来达到IPC。
Zygote进程中的操作(入口函数在frameworks\base\cmds\app_process\app_main.cpp):
- fork出SystemServer进程,用于启动Android各项服务
- 创建虚拟机
- 注册JNI方法
- 连接前文中创建的Socket
- 最后无限循环等待socket连接。
ActivityManagerService收到startActivity的IPC调用后,经过N个方法的调用,判断目标Activity是否要在新的进程。如果是,通过startProcessLocked 生成LockSocket对象 去连接Zygote进程。Zygote收到读取参数,fork出应用进程,反射ActivityThread的main方法。最终应用进程的ActivityThread 初始化Looper,信息队列无限循环,用于接收 点击事件、Activity切换了各种Message。
SystemServer进程
Android最主要的两个进程 Zygote和SystemService。其中SystemService是Zygote fork出的第一个进程。fork后的操作:
- 关闭Socket服务端(因为fork出的子进程和父进程 共享文件,所以也持有Zygote的socket资源)
- 执行com.android.server.SystemServer类中的main()函数
Android绝大多数的Service(ActivityManagerService, WindowManagerService, PackageManagerService, InputManagerService)都是以线程的形势存在于SystemService中。
Android服务如图:
第一个Activity
ActivityManagerService(AMS)的启动最后调用systemReady(),systemReady启动task顶部Activity,因为mMainStack队列还没有Activity对象,导致ActivityStack调用startHomeActivityLocked()。startHomeActivityLocked()中发出一个category为CATEGORY_HOME的intent,从而启动Launcher应用。
然后Launcher调用PackageManagerService查询 应用程序的icon、应用名称,用户一点击 IPC到AMS,AMS socket连接到 Zygote进程,Zygote进程fork应用进程,进程内部反射 ActivityThread main, ActivityThread初始化Looper,通过Binder的子类ApplicationThread,和AMS等服务进行IPC通信
相关资料:
首先《Android源码分析实录》,亮点是深入到了 Linux内核层,我第一次看到讲Binder,详细到把Linux驱动的源代码给贴出来的。缺点也很明显了:偏底层,不像《Android开发艺术探索》、《深入理解Android内核设计》在FrameWork层可以明显的有好处。
《LINUX SYSTEM PROGRAMING》就是看Binder驱动哪里看不懂,然后借了一本读的。有个惊喜的收获是讲了很多概念,有种醍醐灌顶的感觉。像是Linux两大抽象概念 文件、进程,文件的特殊文件、进程的fork exec。进程通信的signal。感觉挺有意思的。
- Android从BIOS到Zygote到SystemService到Launcher启动概况
- android zygote 到launcher的启动关键点
- Android研究-Android的init启动到launcher启动-主要分析zygote服务
- Android研究-Android的init启动到launcher启动-主要分析zygote服务
- Android研究-Android的init启动到launcher启动-主要分析zygote服务
- 计算机启动从bios到操作系统整过程详解
- 计算机启动从bios到操作系统整过程详解
- Android系统开机启动到Launcher流程总结
- 从BIOS到内核的过程分析
- 从作弊到机器学习——足球AI概况
- 进程system_service诞生java世界的SystemService,从进程到线程
- apk从打包到安装到启动
- android launcher 之踩到的坑
- 【Launcher】获取最新Launcher源码,并且导入到Android Studio
- SystemServer到Launcher
- 从Linux启动过程到android启动过程
- 从android到ios
- app从点击到启动
- 淘淘商城第五天
- 淘淘商城第六天
- 前端开发神一样的工具chrome调试技巧
- 淘淘商城第七天
- sdut-l离散题目2
- Android从BIOS到Zygote到SystemService到Launcher启动概况
- SVN的概述
- 淘淘商城第八天
- iOS内存管理的问题总结
- 如何用springcloud找妹纸之11--- 一个承载着"思念"的行囊(spring Cloud Bus)
- 和为S的两个数字之和&&和为s的连续正数序列
- CentOs简单命令
- 使用Chrome调试模式获取App混合应用H5界面元素
- Linux中sed命令整理