新手大战Android源码之启动过程
2015-03-27 10:57
323 查看
新手上路,当学习笔记整理记忆。
先来个基本启动流程框架图:
深入理解Android卷I书籍一本
有关博客数篇,大小不限,高矮胖瘦都不限。
可以随时百度的百度。
本新手一个,所以实力有限,招兵买马也仅限于此。实在是难登大雅之堂。
敌手实力不容小视,单单一个Android系统启动流程就屯兵百万。
瞎话就不叙述了,进入正题,据探子回报:
底层linux kernel
Android源代码于底层linux搭边的在System\core…里。而存放各种待解析的文件则在System\core\rootdir里面。比如init.rc,uevent.rc,init.zygote32.rc等,以rc为文件后缀存放的,类似于编译原理的各种规定的语法格式,以便后面文件进行解析。
次底层的libraries以及Android Runtime的Dalvik 虚拟机
这里面包含了引用库。一般都存放在模块的子目录里。
主要包含C语言和JNI等编写的程序。
次顶层的Application Framework
是各种服务的管理者,activity manager,resource manager,view System等。主要存在于framwork\base\里。包含Java语言,c++语言,以及native的JNI。
顶层的Application
这个就不多说了,各种api,各种服务都给你准备好了,只等调用了。
本次关于启动的研究,没深入敌营到如此深的地步,止步于次底层。
单单一个main函数就又高又壮,看的头都大了。那就umask(0)为何是权限最大值,请查阅相关资料,这给个链接啊http://zhidao.baidu.com/link?url=EM6Z49OctQaxCVa38HloyfgpnIqVguMRWRW7T16dt3njaY1ykN4UlkFGHli-PJnTYfFmR51WjrtS9ImAr4f7Z
Pc_)。然后不能浪费上面给的权力啊,因此会执行各种目录的建立,挂载,关于init.rc的解析,解析后会产生响应的属性配置list表,进行属配置,配置后启动相应的service_list,这里会启动zygo后面就会属性启动,例如:来大麻烦。最后不断的检测和重启挂掉的服务。对于service的结构体的定义书《深入理解Android》有介绍,里面各种属性被赋值,各种服务所携带的属性值也就不同了,后面就会属性启动,例如:zygote的svc(为service的结构体)svc->classname为default属性。解决掉init的main函数之后,再去找找附带的喽喽兵看看。
来到init.rc的文件下,看看所谓的用规定语法格式进行指令书写的文件的是什么样。截图如下:
注意到了没,以on和service的关键字的前面没有缩进啊,说明这两个是要存在什么问题的,查看keyword.h的里面的宏定义,发现对应SECTION,同时还存在其它几种,opinion和command。这样解析的时候就会差别对待。
里面有Android_power以及power state on。入口是这啊。且慢,最上面一行的又是啥东东?system\bin下面的app_process32 和后面的start system_server…..socket-name = zygote?
实际上,深入浅出Android书里已说明,zygote本身是一个native的应用程序,和驱动以及内核没有关系。从上面的指令中我们也看到system\bin\app_process32。也就是zygote的另一个名字。
接下来转入到zygote的初始化,转到路径framework\base\core\java\com\android\internal\os\zygoteinit.java.看到了如下的东东。
开始要进行Dalvik虚拟机框架启动的简要框架集成的初始化,随后对main函数的其他属性值进行检查赋值操作。图中圈大圈的部分。然后注册socket套接字,书写系统事件日志。为Dalvik虚拟机进行简要的框架环境注册之后,要进行预加载各种资源以及类,书中说要加载的类多大1200多个,时代在进步,目前已经有3000多个类要预先加载。使用gc进行建议性的回收,因为Java的回收我们是没有办法进行精准的控制。这样做的目的也是对之前预加载后进行空间上的资源释放。启动system server。runSelectLoop。关闭socket。会有疑惑,怎么关闭了socket了,难道zygote命要终结了?其实不是,在关闭之前,runselectloop被调用,里面是while(true){}。会不断响应其他请求。
对于system server启动,涉及好多服务类,以及对各个服务的守护,今天时间有限,改日了解记录。
先来个基本启动流程框架图:
1 招兵买马
古语云:机会总是留给有准备的人。为了这场战役,我准备了如下几个利器。深入理解Android卷I书籍一本
有关博客数篇,大小不限,高矮胖瘦都不限。
可以随时百度的百度。
本新手一个,所以实力有限,招兵买马也仅限于此。实在是难登大雅之堂。
2 打探敌情
战不得不战,打非得打。但也不能蛮打不是,蛮打多么没素质,没品位呢。得智取。于是乎,了解一下对方的实力吧。敌手实力不容小视,单单一个Android系统启动流程就屯兵百万。
瞎话就不叙述了,进入正题,据探子回报:
底层linux kernel
Android源代码于底层linux搭边的在System\core…里。而存放各种待解析的文件则在System\core\rootdir里面。比如init.rc,uevent.rc,init.zygote32.rc等,以rc为文件后缀存放的,类似于编译原理的各种规定的语法格式,以便后面文件进行解析。
次底层的libraries以及Android Runtime的Dalvik 虚拟机
这里面包含了引用库。一般都存放在模块的子目录里。
主要包含C语言和JNI等编写的程序。
次顶层的Application Framework
是各种服务的管理者,activity manager,resource manager,view System等。主要存在于framwork\base\里。包含Java语言,c++语言,以及native的JNI。
顶层的Application
这个就不多说了,各种api,各种服务都给你准备好了,只等调用了。
本次关于启动的研究,没深入敌营到如此深的地步,止步于次底层。
3 大战开始
本想从别的地方找找开打的地方,但是基于程序员的潜意识,总觉得init是个梦开始的地方。哈哈。那就从这研究吧。int main(int argc, char **argv) { int fd_count = 0; struct pollfd ufds[4]; char *tmpdev; char* debuggable; char tmp[32]; int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; bool is_charger = false; if (!strcmp(basename(argv[0]), "ueventd")) return ueventd_main(argc, argv); if (!strcmp(basename(argv[0]), "watchdogd")) return watchdogd_main(argc, argv); /* clear the umask */ umask(0); /* Get the basic filesystem setup we need put * together in the initramdisk on / and then we'll * let the rc file figure out the rest. */ mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); /* indicate that booting is in progress to background fw loaders, etc */ close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000)); ........... ............. INFO("reading config file\n"); init_parse_config_file("/init.rc"); action_for_each_trigger("early-init", action_add_queue_tail); for(;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); if (!property_set_fd_init && get_property_set_fd() > 0) { ufds[fd_count].fd = get_property_set_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; property_set_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) timeout = 0; #if BOOTCHART if (bootchart_count > 0) { if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) timeout = BOOTCHART_POLLING_MS; if (bootchart_step() < 0 || --bootchart_count == 0) { bootchart_finish(); bootchart_count = 0; } } #endif nr = poll(ufds, fd_count, timeout); if (nr <= 0) continue; for (i = 0; i < fd_count; i++) { if (ufds[i].revents & POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0; }
单单一个main函数就又高又壮,看的头都大了。那就umask(0)为何是权限最大值,请查阅相关资料,这给个链接啊http://zhidao.baidu.com/link?url=EM6Z49OctQaxCVa38HloyfgpnIqVguMRWRW7T16dt3njaY1ykN4UlkFGHli-PJnTYfFmR51WjrtS9ImAr4f7Z
Pc_)。然后不能浪费上面给的权力啊,因此会执行各种目录的建立,挂载,关于init.rc的解析,解析后会产生响应的属性配置list表,进行属配置,配置后启动相应的service_list,这里会启动zygo后面就会属性启动,例如:来大麻烦。最后不断的检测和重启挂掉的服务。对于service的结构体的定义书《深入理解Android》有介绍,里面各种属性被赋值,各种服务所携带的属性值也就不同了,后面就会属性启动,例如:zygote的svc(为service的结构体)svc->classname为default属性。解决掉init的main函数之后,再去找找附带的喽喽兵看看。
来到init.rc的文件下,看看所谓的用规定语法格式进行指令书写的文件的是什么样。截图如下:
注意到了没,以on和service的关键字的前面没有缩进啊,说明这两个是要存在什么问题的,查看keyword.h的里面的宏定义,发现对应SECTION,同时还存在其它几种,opinion和command。这样解析的时候就会差别对待。
4 乘胜追击
对于初始化起来的各项服务有很多,除了基本的内核通信之类的服务之外,哪个服务是给后期Android启动铺路的呢?这需要研究研究。在init.zygote32_64.rc的文件中,发现了这个。里面有Android_power以及power state on。入口是这啊。且慢,最上面一行的又是啥东东?system\bin下面的app_process32 和后面的start system_server…..socket-name = zygote?
实际上,深入浅出Android书里已说明,zygote本身是一个native的应用程序,和驱动以及内核没有关系。从上面的指令中我们也看到system\bin\app_process32。也就是zygote的另一个名字。
接下来转入到zygote的初始化,转到路径framework\base\core\java\com\android\internal\os\zygoteinit.java.看到了如下的东东。
开始要进行Dalvik虚拟机框架启动的简要框架集成的初始化,随后对main函数的其他属性值进行检查赋值操作。图中圈大圈的部分。然后注册socket套接字,书写系统事件日志。为Dalvik虚拟机进行简要的框架环境注册之后,要进行预加载各种资源以及类,书中说要加载的类多大1200多个,时代在进步,目前已经有3000多个类要预先加载。使用gc进行建议性的回收,因为Java的回收我们是没有办法进行精准的控制。这样做的目的也是对之前预加载后进行空间上的资源释放。启动system server。runSelectLoop。关闭socket。会有疑惑,怎么关闭了socket了,难道zygote命要终结了?其实不是,在关闭之前,runselectloop被调用,里面是while(true){}。会不断响应其他请求。
对于system server启动,涉及好多服务类,以及对各个服务的守护,今天时间有限,改日了解记录。
相关文章推荐
- Android 5.0源码分析---Content Provider的启动过程分析
- 【转】Android 4.0 Launcher2源码分析——启动过程分析
- Android 4.0 Launcher2源码分析——启动过程分析
- Android 8.0系统源码分析--startService启动过程源码分析
- Android应用程序启动过程——Launcher源码分析
- Android 应用程序进程启动过程源码分析 .
- Android系统源码阅读(4):Service在新进程中启动过程
- Android系统SystemServer进程启动过程源码分析
- 从源码角度解析android APP启动过程中各类及其方法的调用
- Android Telephony启动过程源码分析
- Android源码剖析之-----Activity的启动过程
- Android Content Provider的启动过程源码分析
- Android系统默认Home应用程序(Launcher)的启动过程源码分析
- Android 4.0 Launcher2源码分析——启动过程分析
- Android源码解析之Dalvik虚拟机的启动过程分析
- Android源码分析-Activity的启动过程
- Android进程启动过程源码分析整理.
- 源码分析Android 应用进程的启动过程
- Android源码学习-系统启动过程
- Android SurfaceFlinger服务启动过程源码分析