`

android启动init流程分析

 
阅读更多

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等事件,

比如,SD卡插入时,init中device_fd将能收到卡插入事件,以便可以创建节点。

另外,所有其他的重要进程都是init的子进程,一旦这些子进程出现意外,init的signal_recv_fd将收到SIGCHLD,系统将可以做后续处理。

分享到:
评论

相关推荐

    android init启动分析

    android init启动分析,是分析android的启动过程,可以辅助你对android启动过程的理解

    Android init 启动过程分析

    分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为 init 是内核进入文件系统后第一个运行的程序,通常我们可以在linux的命令行中指定内核第一个调用谁,

    Androidinit启动过程分析.pdf

    Androidinit启动过程分析.pdf

    Android启动流程分析

    Android启动流程分析,对于Android只是触及皮毛的我,看到: init、ServiceManger、Zygote、SystemServer这些东东,完全联系不起来,总之是支离破碎呀! 下面我来梳理梳理自己那满天飞的思绪

    Androidinit启动过程分析[归类].pdf

    Androidinit启动过程分析[归类].pdf

    Android 启动流程(init.c 和init.rc分析)

    android启动过程中的init.c源码注释,init.rc语法分析

    Android启动-init启动介绍

    Android启动,第一大阶段,init启动。 Linux内核启动之后,执行第一个进程 Init,init会启动本地服务,创建Zygote进程,并最终到达systemserver,systemserver再往上启动framework层相关服务和进程,启动launcher等完成整个...

    Android_init_启动过程分析

    分析android的启动过程,从内核之上,我们首先应该从文件系统的init开始,因为 init 是内核进入文件系统后第一个运行的程序,通常我们可以在linux的命令行中指定内核第一个调用谁

    android系统从init进程开始到systemserver启动详细流程

    介绍android系统启动第二阶段,即init进程开始到systemserver启动详细流程

    android启动源代码分析(init.c)

    较详细的分析了android启动过程的源代码,设计到解析init.rc,启动各个命令等方面。源码主要是system/init/相关的部分。

    Android init.rc 启动流程图

    Android init.rc 启动流程图 1.ZygoteInit是如何启动的以及如何启动SystemService 2.ActivityManagerService如何通过Zygote来创建Activity Pid 3.命令如何启动Pm.java

    Android_启动过程分析

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

    Android-start-boot-analyze-.rar_android_android bootloader_andro

    于Android启动过程复杂,涉及C、C++及java部分内容,本文以流程分析为主线旨在让大家在分析Android系统时有个清晰的思路。鉴于本人水平有限,如有阐述不正之处,还请不吝指正,感激不尽! 系统启动大致可分为一下几...

    Android 系统 Linux系统 内核kernel启动流程 init 进程介绍

    Android 系统 Linux系统 内核kernel启动流程 init 进程介绍,init进程初始化,内核启动三个阶段深入浅出介绍,简单易懂 。kernel_init() 函数介绍,ramdisk_execute_command,execute_command /sbin/init,/etc/init,...

    探索Android FrameWork底层开发视频全套

    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启动流程.pptx

    详细分析了android启动流程,从uboot到Kernel再到android的流程,从汇编到启动第一个进程init结束

    Android启动-SystemServer的启动过程介绍

    紧接上两篇《 Android启动-init介绍》和《Android启动-Zygote启动介绍》Linux内核启动之后,执行第一个进程 Init--&gt;init创建Zygote--&gt;fork出SystemServer。 这里我们就来研究一下SystemServer的创建过程。

    android开机启动流程

    init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程...

    Android启动-Zygote启动介绍

    Android启动,第二大阶段,Zygote启动。...紧接上一篇《 Android启动-init介绍》Linux内核启动之后,执行第一个进程 Init,init会启动本地服务,创建Zygote等。 这里我们就来研究一下Zygote启动过程。

    android从bootloader到launcher启动流程整理

    讲述android 开机流程 从boot rom---bootloader---init--zygote---systemserver---ams 并附上自己整理的每个流程的流程图 ,清晰熟悉android 启动流程

Global site tag (gtag.js) - Google Analytics