Linux kernel起来后运行的第一个应用程序就是init,
Init属于linux下一个应用程序,其源码在 system/core/init中,main是应用程序的入口。从main()函数就可以知道init主要功能。 main()
(1)安装SIGCHLD信号。(如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。因此需要对SIGCHLD信号做出处理,回收僵尸进程的资源,避免造成不必要的资源浪费。
act.sa_handler = sigchld_handler;
act.sa_flags = SA_NOCLDSTOP;
act.sa_mask = 0;
act.sa_restorer = NULL;
sigaction(SIGCHLD, &act, 0);
(2)为rootfs建立必要的文件夹,并挂载适当的分区。
mkdir("/dev", 0755);
mkdir("/proc", 0755);
mkdir("/sys", 0755);
mount("tmpfs", "/dev", "tmpfs", 0, "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);
(3)创建/dev/null和/dev/kmsg节点。
open_devnull_stdio();
log_init();
(4)解析/init.rc,将所有服务和操作信息加入链表。
parse_config_file("/init.rc");
(5)从/proc/cmdline中提取信息内核启动参数,并保存到全局变量。
/* pull the kernel commandline and ramdisk properties file in */
qemu_init();
import_kernel_cmdline(0);
(6)先从上一步获得的全局变量中获取硬件信息和版本号,如果没有则从/proc/cpuinfo中提取,并保存到全局变量。
get_hardware_name();
(7)根据硬件信息选择一个/init.%hardware%.rc,并解析,将服务和操作信息加入链表。
snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
parse_config_file(tmp);
(8)执行链表中带有“early-init”触发的的命令。
action_for_each_trigger("early-init", action_add_queue_tail);
drain_action_queue();
(9)遍历/sys文件夹,是内核产生设备添加事件(为了自动产生设备节点)。
device_init();
{int fd;
fd = open_uevent_socket();
if(fd < 0) return -1;
fcntl(fd, F_SETFD, FD_CLOEXEC);
fcntl(fd, F_SETFL, O_NONBLOCK);
coldboot(fd, "/sys/class");
coldboot(fd, "/sys/block");
coldboot(fd, "/sys/devices");
return fd;
}
(10)初始化属性系统,并导入初始化属性文件。
property_init();
(11)从属性系统中得到ro.debuggable,若为1,则初始化keychord
debuggable = property_get("ro.debuggable");
if (debuggable && !strcmp(debuggable, "1"))
keychord_fd = open_keychord();
(12)打开console,如果cmdline中没有指定console,则打开却省的/dev/console。
if (console[0]) {
snprintf(tmp, sizeof(tmp), "/dev/%s", console);
console_name = strdup(tmp);
}
fd = open(console_name, O_RDWR);
if (fd >= 0)
have_console = 1;
close(fd);
(14)读取/initlogo.rle(一张565 rle 压缩的位图logo),如果成功则在/dev/graphics/fb0显示出Logo,如果失败,则将/dev/tty0设置为TEXT模式并打开/dev/tty0,输出“ANDROID”字符串。
if( load_565rle_image(/initlogo.rle) ) {
fd = open("/dev/tty0", O_WRONLY);
if (fd >= 0) {
const char *msg;
msg = "/n" "/n"
A N D R O I D ";
write(fd, msg, strlen(msg));
close(fd);
}
}
(15)判断cmdline 中的参数,并设置属性系统中的参数:
if (qemu[0])
import_kernel_cmdline(1);
if (!strcmp(bootmode,"factory"))
property_set("ro.factorytest", "1");
else if (!strcmp(bootmode,"factory2"))
property_set("ro.factorytest", "2");
else
property_set("ro.factorytest", "0");
property_set("ro.serialno", serialno[0] ? serialno : "");
property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
property_set("ro.baseband", baseband[0] ? baseband : "unknown");
property_set("ro.carrier", carrier[0] ? carrier : "unknown");
property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");
property_set("ro.hardware", hardware);
snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
property_set("ro.revision", tmp);
(16)执行所有触发标识为init的action。
/* execute all the init actions to get us started */
action_for_each_trigger("init", action_add_queue_tail);
drain_action_queue();
(17)开始property service
/* read any property files on system or data and
* fire up the property service. This must happen
* after the ro.foo properties are set above so
* that /data/local.prop cannot interfere with them.
*/
property_set_fd = start_property_service();
(18)为sigchld handler创建信号机制。
/* create a signalling mechanism for the sigchld handler */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {
signal_fd = s[0];
signal_recv_fd = s[1];
fcntl(s[0], F_SETFD, FD_CLOEXEC);
fcntl(s[0], F_SETFL, O_NONBLOCK);
fcntl(s[1], F_SETFD, FD_CLOEXEC);
fcntl(s[1], F_SETFL, O_NONBLOCK);
}
(19) 执行所有触发标识为early-boot和boot的action
/* execute all the boot actions to get us started */
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
drain_action_queue();
(20)基于当前property状态,执行所有触发标识为property的action
/* run all property triggers based on current state of the properties */
queue_all_property_triggers();
drain_action_queue();
(21)注册轮询事件:
- device_fd
- property_set_fd
-signal_recv_fd
-如果有keychord,则注冊keychord_fd
ufds[0].fd = device_fd;
ufds[0].events = POLLIN;
ufds[1].fd = property_set_fd;
ufds[1].events = POLLIN;
ufds[2].fd = signal_recv_fd;
ufds[2].events = POLLIN;
fd_count = 3;
if (keychord_fd > 0) {
ufds[3].fd = keychord_fd;
ufds[3].events = POLLIN;
fd_count++;
}
(22)进入无限循环,确保这个init进程永驻不退出
在这个循环体内,将通过poll模式POLLIN来监视device/property-set/chid-process-exit等事件,
|
相关推荐
android init启动分析,是分析android的启动过程,可以辅助你对android启动过程的理解
分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为 init 是内核进入文件系统后第一个运行的程序,通常我们可以在linux的命令行中指定内核第一个调用谁,
Androidinit启动过程分析.pdf
Android启动流程分析,对于Android只是触及皮毛的我,看到: init、ServiceManger、Zygote、SystemServer这些东东,完全联系不起来,总之是支离破碎呀! 下面我来梳理梳理自己那满天飞的思绪
Androidinit启动过程分析[归类].pdf
android启动过程中的init.c源码注释,init.rc语法分析
Android启动,第一大阶段,init启动。 Linux内核启动之后,执行第一个进程 Init,init会启动本地服务,创建Zygote进程,并最终到达systemserver,systemserver再往上启动framework层相关服务和进程,启动launcher等完成整个...
分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为 init 是内核进入文件系统后第一个运行的程序,通常我们可以在linux的命令行中指定内核第一个调用谁
介绍android系统启动第二阶段,即init进程开始到systemserver启动详细流程
较详细的分析了android启动过程的源代码,设计到解析init.rc,启动各个命令等方面。源码主要是system/init/相关的部分。
Android init.rc 启动流程图 1.ZygoteInit是如何启动的以及如何启动SystemService 2.ActivityManagerService如何通过Zygote来创建Activity Pid 3.命令如何启动Pm.java
Android 启动过程分析 首先看看整体开机流程。这个对于软件开发测试工作非常有用,特别是在项目初期的时候,通常出在驱动或者启动参数上面的问题比较多,比如关机充电,连接charger关机等问题。 一般开机过程大致...
于Android启动过程复杂,涉及C、C++及java部分内容,本文以流程分析为主线旨在让大家在分析Android系统时有个清晰的思路。鉴于本人水平有限,如有阐述不正之处,还请不吝指正,感激不尽! 系统启动大致可分为一下几...
Android 系统 Linux系统 内核kernel启动流程 init 进程介绍,init进程初始化,内核启动三个阶段深入浅出介绍,简单易懂 。kernel_init() 函数介绍,ramdisk_execute_command,execute_command /sbin/init,/etc/init,...
3.Android编译过程分析 4.android.mk初识 5.Android.mk学习1 6.Android.mk学习2 7.Android.mk学习3 8.Android启动课程大纲 9.Android启动模式 10.init启动分析 11.走入init启动脚本 12.init脚本解析分析 13.init脚本...
详细分析了android启动流程,从uboot到Kernel再到android的流程,从汇编到启动第一个进程init结束
紧接上两篇《 Android启动-init介绍》和《Android启动-Zygote启动介绍》Linux内核启动之后,执行第一个进程 Init-->init创建Zygote-->fork出SystemServer。 这里我们就来研究一下SystemServer的创建过程。
init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程...
Android启动,第二大阶段,Zygote启动。...紧接上一篇《 Android启动-init介绍》Linux内核启动之后,执行第一个进程 Init,init会启动本地服务,创建Zygote等。 这里我们就来研究一下Zygote启动过程。
讲述android 开机流程 从boot rom---bootloader---init--zygote---systemserver---ams 并附上自己整理的每个流程的流程图 ,清晰熟悉android 启动流程