android系统启动流程之init.rc详细分析笔记

本文详细介绍Android系统中的init.rc文件,包括其语法结构、关键概念如Actions、Commands、Services及Options的作用,以及如何触发不同的系统行为和服务。同时提供了一些实用的例子帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        对于android系统的学习掌握,除了对一些语言基础的要求,如C,C++,java,shell,makefile等,更要整体去把握系统的架构。对于架构的熟悉入门,首先应该分析android的编译系统结构。而对于系统的启动流程的掌握,最好是深入分析init.rc、init.xx.rc等文件。这些文件相对来说代码量少,比较简单,而且对系统的整体认识有很大的帮助。以前在工作中经常要用到init.rc相关的知识,但是没有系统的去分析整体,最近写成了笔记,分享出来!


关于init.rc的几点说明:
1).在android源码目录下面jb\system\core\init\readme.txt文件中有init.rc语法的详细定义
  注意:readme.txt没有和android的版本一起更新,所以在新版本的android中,增加了一些commands、options等,在readme.txt中 没有介绍。 还是看init目录下面的源码最为准确

2).解析init.rc,init.xx.rc的相关文件目录system/core/init/

3).init.c 、init.rc init.xx.rc 等最终会编译到ramdisk.img(根文件系统)中,和kernel一起打包成boot.img。android启动后每次都会从boot.img中解压出init.c等文件到内存,所以要修改必须修改替换boot.img。

4).在init.rc中启动的服务,都是以一个进程的形式运行,属于android的本地服务。通过在终端输入PS命令可以查看在运行的相应进程,他们的ppid都为1,代表init进程。 init进程也是android系统启动的第一个应用进程

5).init.rc中所有的语句都是以行为单位的(每个语句都是单独写在一行里面)

6).注释行以“#”开头

7).Actions 和 Services表示一个新的段落section的开始。
 所有的commands和options 都是归属于上方最近的一个段落。在第一个段落之前的commands和options是无效的。

8).Actions and Services
不能重名,如果重名,后面的定义会被忽略(readme.txt说明)。
但是实际项目中同一个init.xx.rc中有重名的action,也可以正常使用。多个init.xx.rc中action也允许有重名, 比如 boot,init 等在多个rc文件中出现。services应该不能重名


init.rc (Android Init Language)语法详解:

1.init语法的四个组成原件:
Actions  :动作 ,使用格式: on <Triggers>,下面行跟各种command
Commands :命令  
Services :服务  使用格式 : service <name> <pathname> [ <argument> ]* ,下面行可以添加Options
Options : 选项

2.init.rc中三大模块:
1). import 导入其他的init.xx.rc文件。
2). 以action动作为触发点的一系列命令
3). 带有各种Options的一系列services的定义


import /init.${ro.hardware}.rc
通过cat proc/cpuinfo可以查看ro.hardware的值=Hardware的值

on <trigger>    //action 模型
   <command>
   <command>
   <command>
   ....
  
service <name> <pathname> [ <argument> ]*   (services可以带有多个参数和选项)
   <option>
   <option>
   ...  

3.对Actions官方描述的一些理解 :
当action的trigger被匹配后,action会被加入到动作执行队列中,在队列中的action按队列顺序被执行,每个action下面的command也是按顺序执行。按这个理论,在init.rc中action、command、service的执行顺序主要是和它们的触发时间有关,如果都是开机启动时执行,应该也和代码顺序有关。(有兴趣可以验证一下、想深入了解解析过程,可以查看源码目录init下面的init_parser.c等文件)


4.Triggers : 跟在on后面的动作名,用来触发action下面command的执行

1).android常用的triggers的名字:
  early-init,init,early-fs,fs,post-fs,early-boot,boot (这些都是在init.c中触发)

2).可以自定义一些triggers,并选择合适的触发方式 (例如:关机充电功能,可以只启动charger服务进程)

3).<name>=<value> 形式,如:on property:ro.debuggable=1

4). device-added-<path>
    device-removed-<path>      
   Triggers of these forms occur when a device node is added or removed
   一个设备节点/dev/XXX添加或者删除时可以触发一个action,这个可以很好的去利用
 
5).service-exited-<name>  
   Triggers of this form occur when the specified service exits.
   当某个服务退出时,可以触发一个action


5.option 选项:(用于services下面)
android新版本上增加的一些options可以通过源码查看对应作用
init_parser.c--》lookup_keyword(const char *s)--》parse_line_service() 或者 --》parse_line_action()


1).class <class_name>  
说明服务属于class_name这个类。缺省值service属于 “default” 类。同一个class下面的服务可以一起启动或停止。

2).disabled 
表示当这个服务所在的class启动的时候,服务不会自动启动,
要用start server_name 或 property_set("ctl.start", server_name);才能启动。
 
3).oneshot  
当服务退出后,不会再重新启动,如果没有加这个option,则服务默认退出后又会重新重启

4).user <username> 
   执行服务之前,先声明服务的用户名,缺省值应该为root用户.
   如果你的进程要求具有linux内核能力,必须保证它的用户为root(没有完全明白,实例?)


5).group <groupname> [ <groupname> ]*
  执行服务之前,先声明服务所属组名,可以一次声明属于多个组。
   声明多个组时,除第一个组名外,其他的为服务的补充组名(调用接口 setgroups()).
  
6).onrestart   + command
服务重启的时,会执行onrestart后面的command.
eg:onrestart restart media 重启名为media的服务
   
7).setenv <name> <value>      
在当前服务进程中设置环境变量name的值为value。
注意:setenv定义的环境变量仅在本进程内生效,退出该进程,或者关闭相应的程序运行窗口,该环境变量即无效)
程序中可通过getenv("name")接口获取这个环境变量的值
setenv和export 的区别:
setenv  csh ,本进程生效,退出后,变量无效
export  bash ,全局生效,一直存在
格式:
export key=value
setenv key value

8).critical   
声明为设备的循环服务。如果服务在四分钟内退出了四次,则设备会进入recovery模式
使用实例servicemanager、ueventd等服务

9).socket <name> <type> <perm> [ <user> [ <group> ] ]  
创建名为/dev/socket/<name>的unix domain socket ,并把它的句柄fd传给本服务进程
 <type> 必须为 "dgram", "stream" or "seqpacket".User and group default to 0 ,也就是root.
 
  
6.command   :(action下面的一系列命令)

常用命令:

1).import <filename>        
  导入init.XX.rc、xxx.conf等文件
   Parse an init config file, extending the current configuration.

2).chmod <octal-mode> <path>
   Change file access permissions.

3).chown <owner> <group> <path>
   Change file owner and group.
  
4).chdir <directory>
   Change working directory.
  
5).chroot <directory> 
  改变进程根目录
  
6).insmod <path>   
  加载XX.ko驱动模块

7).start <service>
   Start a service running if it is not already running.

8).stop <service>
   Stop a service from running if it is currently running.

9).class_start <serviceclass>
   Start all services of the specified class if they are not already running.

10).class_stop <serviceclass>
   Stop all services of the specified class if they are currently running.
     
   class_reset <serviceclass>   //重启class下面所有的服务
     
11).setprop <name> <value>  
   Set system property <name> to <value>.
   通过getprop命令可以查看当前系统的属性值
  
12).export <name> <value>       
  设置全局环境变量,这个变量值可以被所有进程访问(全局的,一直存在)
  在代码中通过value = getenv("name")接口可以获取这个环境变量的值
  
13).mkdir <path> [mode] [owner] [group]
   创建目录,后面项缺省值为 mode,owner,group: 0755 root root

14).trigger <event>
   Trigger an action.  Used to queue an action from another action.
   例:trigger post-fs-data

15).exec <path> [ <argument> ]*     
   执行<path>指定的Program,并可以带有执行参数。
   exec在调用进程内部执行一个可执行文件,并会阻塞当前进程,直到运行完成。
   最好避免和那些builtin commands一样使用exec命令,否则容易造成阻塞 or stuck ( maybe there should be a timeout?)

16).ifup <interface>
   启动某个网络接口,使其为up状态,通过netcfg可以查看,ifup eth0  等价于 netcfg eth0 up 功能一样
  
17).hostname <name>
   设置设备的主机名,一般默认设置为localhost,可以在终端通过hostname new_name进行修改

18).domainname <name>
   设置网络域名localdomain

19).mount <type> <device> <dir> [ <mountoption> ]*
    把device挂接到dir目录下面,文件系统类型为type。
   <mountoption>s include "ro", "rw", "remount", "noatime", “nosuid”......,具体可查看linux的mount命令说明
  
20).setkey
   TBD  == to be determined 暂时没有使用

21).setrlimit <resource> <cur> <max>
  设置本服务进程的资源上限值。(使用例子??)

22).symlink <target> <path>   
   path 链接到 ---》target ;创建符号链接

23).sysclktz <mins_west_of_gmt>  
  设置系统时区(0 if system clock ticks in GMT)

24).wait <path> [ <timeout> ]
 轮询查找给定的文件path是否存在,如果找到或者超时则返回默认超时为5秒。(使用实例???)

25).write <path> <string> [ <string> ]*
   打开一个文件,利用write命令写入一个或多个字符串


7. Properties
----------
Init updates some system properties to provide some insight into
what it's doing:

init.action
   Equal to the name of the action currently being executed or "" if none

init.command
   Equal to the command being executed or "" if none.

init.svc.<name>
   State of a named service ("stopped", "running", "restarting")
  属性状态,getprop命令可以查看。property_set接口函数、ctl.start、ctl.stop来设置


8.实际的一些例子,基于android4.2.1:


1).readme.txt自带的一些例子(只是整理一些有代表性的):


on boot
   export PATH /sbin:/system/sbin:/system/bin

   mount tmpfs tmpfs /dev
  mount yaffs2
mtd@system /system

   write /proc/cpu/alignment 4
  
   import /system/etc/init.conf 
   //导入相应的配置文件

on device-added-/dev/compass
   start akmd

on device-removed-/dev/compass
   stop akmd

service akmd /sbin/akmd
   disabled
   user akmd
   group akmd


Debugging notes 调试注意点:
---------------
默认的,在系统init进程中启动的程序(如XX.rc中定义的服务等) ,不能通过logcat查看相关log信息
为了调试,需要增加执行logwrapper,才能通过logcat查看log信息,(之前调试可以直接查看log信息啊,有待验证)
如:service akmd /system/bin/logwrapper /sbin/akmd 
可以通过logcat查看akmd服务中的log信息。


2).实际项目中的一些典型例子(只是整理一些有代表性的)

init.rc文件中的一些参考例子:
           
import /init.${ro.hardware}.rc
on early-init

    write /proc/1/oom_adj -16

    # Set the security context for the init process.
    # This should occur before anything else (e.g. ueventd) is started.
    setcon u:r:init:s0 
    
    start ueventd
    mkdir /mnt 0775 root system

on init

sysclktz 0
loglevel 3    设置log输出等级

# setup the global environment
    export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
    export ANDROID_BOOTLOGO 1

    symlink /system/etc /etc     
    mount tmpfs tmpfs /mnt/secure mode=0700,uid=0,gid=0
    write /proc/sys/kernel/panic_on_oops 1
  
    mount cgroup none /dev/cpuctl cpu
    chown system system /dev/cpuctl
    chmod 0660 /dev/cpuctl/tasks

on fs
# mount mtd partitions
    #mount yaffs2
mtd@system /system ro remount
 
on post-fs
    mount rootfs rootfs / shared rec
    mount tmpfs tmpfs /mnt/secure private rec
    # We restorecon /cache in case the cache partition has been reset.
    restorecon /cache  

on post-fs-data
   
    write /proc/apanic_console 1
    mkdir /data/misc 01771 system misc
   mkdir /data/misc/adb 02750 system shell 
    setprop vold.post_fs_data_done 1


on boot

# basic network init
    ifup lo
    hostname localhost
    domainname localdomain

# set RLIMIT_NICE to allow priorities from 19 to -20
    setrlimit 13 40 40

    class_start core
    class_start main

on charger
    class_start charger

on property:vold.decrypt=trigger_reset_main
    class_reset main

on property:vold.decrypt=trigger_load_persist_props
    load_persist_props
    //加载用户空间设置的系统属性persist_props 

on property:vold.decrypt=trigger_post_fs_data
    trigger post-fs-data

service ueventd /sbin/ueventd
    class core
    critical
    seclabel u:r:ueventd:s0 

on property:selinux.reload_policy=1
    restart ueventd
    restart installd

service console /system/bin/sh
    class core
    console       //requires console
    disabled
    user shell
    group log

on property:ro.debuggable=1
    start console

# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /sbin/adbd
    class core
    socket adbd stream 660 system system
    disabled
    seclabel u:r:adbd:s0
    ioprio rt 4 
  ioprio be 2
IoSchedClass, usage: ioprio <rt|be|idle> <ioprio 0-7>\n . 
  
service servicemanager /system/bin/servicemanager
    class core
    user system
    group system
    critical  //添加了此选项,如果servicemanager在四分钟内退出了四次,则设备会进入recovery模式
    onrestart restart zygote  //如果servicemanager服务重启,则zygote服务也会重启

 
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server   (后面都是所带参数app_process)
    class main
    socket zygote stream 660 root system
    socket keystore stream 666
    onrestart write /sys/power/state on  //如果zygote服务重启,则执行write命令,写state为on

 
init.hardware.rc内容 :

import /init.usb.rc

on init
    export EXTERNAL_STORAGE /mnt/sdcard    getenv("EXTERNAL_STORAGE") 获取变量值/ dalvik_system_Zygote.cpp
    mkdir /mnt/sdcard 0000 system system  
    symlink /mnt/sdcard /sdcard
   
  #通过USB接口的U盘虚拟成SD卡的操作
  #export EXTERNAL_STORAGE /mnt/usb/sda1
    #mkdir /mnt/usb/sda1 0000 system system
    #symlink /mnt/usb/sda1 /sdcard
    #symlink /mnt/usb/sda1 /mnt/sdcard
  
on early-init
    mount tmpfs tmpfs /mnt/usb mode=0755,gid=1000

on init
    mkdir /var 0775 system system

on fs
  mount -o size=110m -t tmpfs tmpfs /dev/cache mode=0777,gid=1000 
    mount ext4 /dev/block/mmcblk0p4 /system wait ro noatime block_validity nodiscard data=ordered journal_checksum 
    mount ext4 /dev/block/mmcblk0p5 /data wait nosuid nodev noatime block_validity nodiscard data=ordered journal_checksum
    mount ext4 /dev/block/mmcblk0p7 /tvservice wait ro noatime block_validity nodiscard data=ordered journal_checksum
 
on post-fs
    command
   
on post-fs-data
    write /proc/sys/kernel/core_pattern /var/coredump.%p.gz

on boot

# After launcher is displayed, trigger related drivers initialization
on property:init.svc.bootanim=stopped// 开机后启动加载或者启动某些服务,提高开机速度
    insmod /system/lib/modules/usb-storage.ko
   
# bugreport is triggered by holding down volume down, volume up and power
service bugreport /system/bin/bugmailer.sh -v
    class main
    disabled
    oneshot
    keycodes 114 115 116   
 //keycodes for triggering this service via /dev/keychord 。参见init.h





<think>好的,我现在需要帮助用户查找关于全志T527快速启动时间的文档或解决方案。首先,我应该回忆一下用户提供的引用内容。用户给出了两个引用,引用[1]是关于使用telnet下载和调试嵌入式系统的步骤,可能涉及RTOS(实时操作系统)的示例,比如FreeRTOS。引用[2]则提到了Android开机动画流程和相关的源码修改资源,特别是Android 12的Setting模块代码。 用户的问题是关于全志T527的快速启动时间,这通常涉及系统启动优化,可能包括硬件初始化加速、Bootloader优化、内核裁剪、文件系统优化以及应用层启动流程优化等方面。全志T527是一款处理器,可能用于嵌入式设备或智能设备,所以快速启动可能对用户体验很重要,比如在汽车电子、智能家居或工业控制等领域。 首先,我需要确定用户提到的引用是否与全志T527相关。引用[1]中的内容涉及RTOS的示例,可能适用于嵌入式系统的实时任务处理,而引用[2]涉及Android开机动画,这可能与Android设备的启动流程有关。全志T527可能运行Android或Linux系统,所以需要分别考虑这两种情况。 接下来,我应该考虑如何结合用户提供的引用来给出解决方案。对于嵌入式系统使用RTOS的情况,可以参考引用[1]中的调试和程序加载方法,优化启动流程。例如,通过优化Bootloader阶段,减少不必要的硬件初始化时间,或者使用更高效的程序加载方式。此外,裁剪内核和优化驱动初始化步骤也是常见的方法。 对于Android系统的情况,引用[2]提到的开机动画流程和源码修改可能相关。Android启动时间优化通常涉及减少系统服务启动时间、优化zygote进程、预加载类、以及缩短开机动画的播放时间等。用户可能需要查看Android启动流程文档,修改相关模块的代码,比如在Setting模块中禁用不必要的服务。 另外,用户可能需要全志官方提供的文档或应用笔记,这些通常会在全志的开发者平台或SDK中找到。例如,全志可能会提供关于快速启动的配置指南,如何调整电源管理策略,或者使用特定的启动模式(如快速启动模式或休眠唤醒机制)。 在硬件层面,快速启动可能涉及电源管理IC的配置,加快时钟源的稳定时间,或者使用低功耗状态的快速恢复。软件层面则需要优化各启动阶段的任务并行化,延迟非关键服务的初始化,以及使用更高效的文件系统(如squashfs或initramfs)。 可能的挑战包括确定启动时间的瓶颈,这通常需要使用 profiling 工具来分析各阶段的耗时。例如,在Linux系统中,可以通过在内核启动参数中添加`initcall_debug`来跟踪每个初始化调用的时间,或者使用bootchart工具来分析整个启动过程。 总结起来,我需要建议用户查阅全志T527的官方文档,特别是关于启动优化的部分,并结合RTOS或Android系统的具体优化方法。同时,引用中提到的调试和源码修改方法可以作为实际操作中的参考步骤。</think>### 全志T527快速启动时间优化方案 针对全志T527快速启动时间的优化,需从硬件初始化、系统软件配置和应用层优化三个层面入手。以下是具体建议: #### 1. **硬件初始化优化** - **缩短时钟稳定时间** 调整时钟源配置,选择启动更快的晶振或启用内部RC振荡器作为临时时钟源,待系统稳定后切换至外部高频晶振。 - **电源管理优化** 使用预配置的电源管理策略(如DVFS动态调频),在启动阶段跳过非关键电压域的校准过程[^1]。 #### 2. **Bootloader优化** - **精简U-Boot功能** 移除非必要驱动和命令,仅保留基础存储、网络加载功能。例如: ```c // 在U-Boot配置文件中禁用USB、HDMI等驱动 # CONFIG_USB is not set # CONFIG_VIDEO is not set ``` - **启用并行初始化** 对互不依赖的外设(如存储控制器与GPIO)采用并行初始化策略,利用多核处理能力加速启动。 #### 3. **Linux内核裁剪** - **内核模块动态加载** 将非关键驱动编译为模块,在系统启动后按需加载。修改内核配置: ```makefile CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y ``` - **减少初始化调用时间** 通过`initcall_debug=1`启动参数分析耗时初始化函数,对耗时超过50ms的驱动进行延迟加载或优化。 #### 4. **文件系统优化** - **使用Initramfs替代完整根文件系统** 将关键启动文件打包进内核镜像,避免存储设备初始化延迟: ```shell # 生成cpio格式的initramfs cd rootfs && find . | cpio -o -H newc > ../initramfs.cpio ``` - **挂载优化** 对`/var`、`/tmp`等非关键目录使用`noatime`挂载选项,减少元数据更新开销。 #### 5. **Android系统优化(若适用)** - **缩短开机动画** 修改`bootanimation.zip`的`desc.txt`,减少帧数和播放时长: ``` 480 800 15 p 1 0 part0 ``` 参考Android开机动画流程文档[^2]调整动画播放逻辑。 - **服务延迟启动** 在`system/core/rootdir/init.rc`中为非关键服务添加`class late_start`: ```rc service vendor.sample_service /system/bin/sample_daemon class late_start user root ``` #### 6. **快速启动模式** - **实现休眠唤醒机制** 配置系统进入深度休眠(suspend-to-disk),唤醒时直接恢复内存镜像: ```shell echo platform > /sys/power/disk echo disk > /sys/power/state ``` 需确保存储设备支持快速读写(如eMMC的HS400模式)。 ### 相关文档与工具 1. **全志官方资源** - 《T527_Boot_Time_Optimization_Guide》 (需在全志开发者平台申请下载) - SDK中的`docs/bsp/startup_analysis.pdf` 2. **调试工具链** - 使用telnet调试启动流程: ```shell telnet 192.168.1.100 4444 reset init halt reg r0-r15 # 检查关键寄存器状态 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值