android --------Init.c

1.内核参数
import_kernel_cmdline(0),   内核参数,就是写在grub 的menu.lst里面或者通过其他地方,是传给内核的参数。由各种boot loader (grub ,lilo, pxeloader 等)负责复制到内存指定位置,然后linux内核通过boot loader传递过来的 一个指针(cmdline pointer)可以获取到。然后建立起/proc/cmdline文件,应用程序可以通过读取这个文件来得到参数。解释见Linux内核自带的文档 Documentation/x86/boot.txt 。
import_kernel_cmdline(0)就是要去/proc/cmdline中解析出
qemu,console,bootmode,serialno,baseband,carrier,bootloader,hardware。
2.解析文件.rc文件
2. early-init
action_for_each_trigger("early-init", action_add_queue_tail);在初始化之前做的事情, init.rc启动脚本中有如下描述

on early-init

        start ueventd

这样就会调用ueventd,其源码位于system/core/init/ueventd.c。

这个action主要目的是通过early-init启动ueventd服务,这个服务负责uevent(user space event)的处理,uevent是内核向用户空间发出的一个时间通知,使应用程序能够有机会对该event做出反应。

3.builtin_action

        1.queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done").

         android 冷过程结束后会生成dev/.coldboot_done文件,wait_for_coldboot_done这个action会等待dev/.coldboot_done文件的生成,等待时长为5s。当然这个action不会阻塞android的冷启动过程,它会没查询一次就会休眠0.1s,直到冷启动结束.

       2.queue_builtin_action(property_init_action, "property_init")

      几种特殊的属性:
      1.ro.属性,它表示只读属性,它一旦被设置就不能被修改;
      2.net.属性,顾名思义,就是与网络相关的属性,net.属性中有一个特殊的属性:net.change,它记录了每一次最新设置和更新的net.属性,也就是每次设置和更新net.属性时则会自动的更新net.change属性,net.change属性的value就是这个被设置或者更新的net属性的name。例如我们更新了属性net.bt.name的值,由于net有属性发生了变化,那么属性服务就会自动更新net.change,将其值设置为net.bt.name。
     3.persist.属性,以文件的形式保存在/data/property路径下。persist.属性由于将其保存在了用户空间中,所以在property_init中是不能对其更新的,只能将其更新过程交给用户来处理。
    4.ctl.属性,虽然是以属性的形式来进行设置,其实它的目的是为了启动或关闭它指定的service
    初始化android的属性系统,整个的过程分为下面2步
    1.初始化属性区域(property area),主要工作是将属性设备节点/dev/properties映射到内存空间上,将整个的属性内容作为共享内存来处理,这个共享内存就是属性区域,当前android中使用全局变量__system_property_area__来标记属性区域。
    2.加载并设置/default.prop中定义的属性,default.prop中主要是一些“ro.”只读属性。
   3.queue_builtin_action(keychord_init_action, "keychord_init");

    键盘初始化

    4.queue_builtin_action(console_init_action, "console_init")

      1.如果/proc/cmdline指定了控制台终端,那么优先使用这个控制台,如果没有指定,那么将使用默认控制台终端/dev/console。
    2.加载开机图片,参考load_565rle_image函数
    a,通过ioctl函数修改dev/tty0(即终端控制台)为图像显示模式;
    b,尝试打开/initlogo.rle,如果失败,那么将dev/tty0恢复为文本显示模式,则开机时显示"ANDROID"文字;
    c,如果打开/initlogo.rle成功,那么init将会打开Framebuffer,将initlogo.rle数据写到Framebuffer中。

    3.可以自己设置开机动画

     5.queue_builtin_action(set_init_properties_action, "set_init_properties")

     设置与硬件载频相关的只读属性

3.init

   1.action_for_each_trigger("init", action_add_queue_tail)

    执行init.rc中init action字段中定义的处理.

   2.action_for_each_trigger("early-fs", action_add_queue_tail);
      action_for_each_trigger("fs", action_add_queue_tail);
      action_for_each_trigger("post-fs", action_add_queue_tail)
4.property_service_init

   queue_builtin_action(property_service_init_action, "property_service_init")

  1.读取/system/build.prop,/system/default.prop, /data/local.prop以及/data/property/下的属性并将其设置;
    2.创建一个服务器端UNIX Domain Socket,它的socket文件路径为/dev/socket/property_service,这个socket监听来自客户端的属性修改请求.


5.signal_init

queue_builtin_action(signal_init_action, "signal_init")

通过socketpair创建一对已连接的socket,将生成的两个socket设置为O_NONBLOCK模式,也就是将对socket句柄的读写操作设置为非阻塞模式。
6.check_startup

queue_builtin_action(check_startup_action, "check_startup")
确保property_service_init中属性设置socket文件描述符和signal_init中signal socket文件描述符,如果两个有其一不存在,那么将退出系统。
7.early-boot,boot
    action_for_each_trigger("early-boot", action_add_queue_tail);
    action_for_each_trigger("boot", action_add_queue_tail)
      boot action主要由两部分组成,
    1. 还是一些配置性的工作,例如基本的网络配置;ActivityManagerService中用到的进程管理和资源回收时,需要用到的优先级变量的设置等。
    2. 启动所有init.rc声明的未指定class的service;
    具体的command为 class_start default。
    在解析init.rc时,如果service未指定class选项的话,那么会给它的classname默认的指定为“default”,而目前的init.rc中的所有的service均未指定class选项,所以命令“class_start default”将按顺序启动所有的service。
    也可以为需要一起启动,一起关闭的services指定一个相同的class,那么就可以对这些service进行统一处理了。
    还需注意:如果service中定义了disabled选项,那么不能通过class_start来启动它,只能显示的一个一个的启动。被disabled修饰的service一般是在
8queue_propety_triggers
    根据init.rc中action指定的property值与属性中的值比较,如果相等则执行对应的command.
9 bootchart_init
    Bootchart 能够对系统的性能进行分析,并生成系统启动过程的图表,以便为你提供有价值的参考信息。综合所得的信息,你就可以进行相应的改进,从而加快你的 Linux 系统启动过程.
10.死循环
     1.execute_one_command
     执行action待执行队列中的所有command
    2.restart_processes
      重启所有需要重启的service
  3.注册属性设置property_set_fd,信号signal处理signal_recv_fd,keychord keychord_fd三个文件描述符的为轮询对象
   init进程将三个描述符均定义为了POLLIN事件响应,当描述符有可读数据时,对于socket描述符,有连接请求时ufds就会收到POLLIN事件。

 

你可能感兴趣的:(android --------Init.c)