Android5.0开关机模块——init进程

    最近项目组把Android5.0的开关机模块分给我,以前只是很简单的接触过Android的开关机流程,刚好借助这次机会,深入研究一下Android5.0的开关机模块。
    Android的开关机流程可以按照整个手机设备的分层结构来理解:
    1、硬件层(Hardware)。用户手指长按电源键触发硬件产生电信号
    2、内核层(Kernel)。硬件的电信号会触发bootloader,bootloader会引导kernel的启动
    3、系统层(System)。Kernel起来以后,才是真正的Android系统被引导起来
    4、应用层(App)。Android系统起来后,用户最终看到的App才会显示在桌面(Launcher)上
    这4步是对Android启动流程的简要概括。第一步和第二步主要由硬件工程师和驱动工程师来负责,我只关注第三、四步。
    Kernel起来后,会启动Android系统的第一个进程——init进程
    从init进程的ID号也可以看出,它的进程ID是1,说明是第一个进程
    root      1     0     948    704   c01f80d0 00028100 S /init
    就从init进程开始入手分析,init进程的源代码在system/core/init/init.c中
    分析init进程从main函数入手
    main函数在定义相关的变量之后,首先就是uevent和watchdog
<span style="font-size:18px;">    if (!strcmp(basename(argv[0]), "ueventd"))
        return ueventd_main(argc, argv);

    if (!strcmp(basename(argv[0]), "watchdogd"))
        return watchdogd_main(argc, argv);</span>
system/core/init/Android.mk是init进程的编译脚本,它有下面一段话
    # Make a symlink from /sbin/ueventd and /sbin/watchdogd to /init
SYMLINKS := \
	$(TARGET_ROOT_OUT)/sbin/ueventd \
	$(TARGET_ROOT_OUT)/sbin/watchdogd
    这说明ueventd和watchdogd是init的两个软连接,当执行ueventd或者watchdogd这两个服务时,执行的还是init进程,init会根据命令行的参数名决定是否进入ueventd_main或者watchdogd_main
    ueventd伺服程序将解析/ueventd.rc文件,并创建相应的设备结点。watchdogd伺服程序是一个看门狗程序,它的任务就是定期向看门狗设备文件执行写操作,以判断系统是否正常运行。
    接下来就是创建几个必须的目录,并挂载tmpfs,devpts,proc,sysfs文件系统,将通过创建文件"/dev/.booting"来表示目前正处于启动中的状态。
    /* 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));</span>
接下来,将创建两个设备结点:/dev/__null__以及/dev/__kmsg__,并打开标准输入流,输出流以及错误输出流,并将它们重定向到/dev/__null__,所以,此时是不能直接调用printf系列的函数直接打印Log输出,而是利用klog输出日志。
    open_devnull_stdio();
    klog_init();
    property_init();</span>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值