Android Init Language

android 7.0上文件位置:alps/system/core/init/readme.txt。

 

一、简述

The Android Init Language consists of five broad classes of statements, which are Actions, Commands, Services, Options, and Imports.

Android Init Language(后简写为AIL)包含了五种类型的语句:Actions, Commands, Services, Options, Imports。

All of these are line-oriented, consisting of tokens separated by whitespace.  The c-style backslash escapes may be used to insert whitespace into a token.  Double quotes may also be used to prevent whitespace from breaking text into multiple tokens.  The backslash, when it is the last character on a line, may be used for line-folding.

这些语句以行为单位进行处理,每个标记之间通过空格符来间隔。标记含有空格时,需要用转义符号反斜线对空格进行转义。也可以用双引号将含有空格的标记括起来,以避免空格将一个标记分隔为多个。当反斜线是一行的最后一个字符时,一般是用于行折叠。

Lines which start with a # (leading whitespace allowed) are comments.

以#号开始的行(后可接空格)是注释行。

Actions and Services implicitly declare a new section.  All commands or options belong to the section most recently declared.  Commands or options before the first section are ignored.

Actions和Services隐性声明了一个新的section。所有的commands或options属于离它们最近的被声明的section。而第一个被声明的section之前的commands和options会被忽略。

Actions and Services have unique names.  If a second Action is defined with the same name as an existing one, its commands are appended to the commands of the existing action.  If a second Service is defined with the same name as an existing one, it is ignored and an error message is logged.

Actions和Services都有一个独立的名字。如果一个action的名字被定义成与一个已有action的名字相同,那这个action的commands将附加到已有action中去。如果一个Service的名字被定义成与一个已有Service的名字相同,那这个Service会被忽略,并且日志会记录一个错误。

 

二、Init.rc Files

The init language is used in  plaintext files that take the .rc file extension.  These are typically multiple of these in multiple
locations on the system, described below.

AIL用于以.rc结尾的纯文本文件。在system目录下有多个这样的文件,具体描述如下。

/init.rc is the primary .rc file and is loaded by the init executable at the beginning of its execution.  It is responsible for the initial
set up of the system.  It imports /init.${ro.hardware}.rc which is the primary vendor supplied .rc file.

/init.rc文件是主要的.rc文件,它会在init执行程序的一开始就被加载。它主要负责system的初始设置。它会导入由vendor提供的.rc文件,这些文件命名格式为/init.${ro.hardware}.rc。

During the mount_all command, the init executable loads all of the files contained within the /{system,vendor,odm}/etc/init/ directories. These directories are intended for all Actions and Services used after file system mounting.

在mount_all命令中,init程序会导入/{system,vendor,odm}/etc/init/目录下的所有文件。在文件系统挂载后,这些目录为所有的Actions和Services作准备。

One may specify paths in the mount_all command line to have it import .rc files at the specified paths instead of the default ones listed above. This is primarily for supporting factory mode and other non-standard boot modes.  The three default paths should be used for the normal boot process.

当然也可以在mount_all命令行中指定路径,从而去指定路径中导入.rc文件,替代上面列举的默认目录中的.rc文件。这个主要用于支持工厂模式和其他的非标准启动模式。而一般的启动进程应该使用上面的三个默认目录。

The intention of these directories is as follows

   1) /system/etc/init/ is for core system items such as SurfaceFlinger, MediaService, and logcatd.
   2) /vendor/etc/init/ is for SoC vendor items such as actions or daemons needed for core SoC functionality.
   3) /odm/etc/init/ is for device manufacturer items such as actions or daemons needed for motion sensor or other peripheral
      functionality.

这些目录的用意如下:

1) /system/etc/init/ 用于如SurfaceFlinger, MediaService, logcatd等核心系统项。

2) /vendor/etc/init/ 用于SoC vendor项,比如SoC核心功能所需的actions和daemons。

3) /odm/etc/init/ 用于设备制造商项,比如运动传感器或其他外设所需的actions和daemons。

All services whose binaries reside on the system, vendor, or odm partitions should have their service entries placed into a
corresponding init .rc file, located in the /etc/init/ directory of the partition where they reside.  There is a build system macro, LOCAL_INIT_RC, that handles this for developers.  Each init .rc file should additionally contain any actions associated with
its service.

所有二进制数据放置于system, vendor或odm分区的services,都需要把它们的服务入口放在对应分区下的/etc/init/目录中的.rc文件中。编译系统宏指令LOCAL_INIT_RC用于处理这个功能。每个 init.rc 文件应该额外包含一些与它的service关联的actions。

An example is the logcatd.rc and Android.mk files located in the system/core/logcat directory.  The LOCAL_INIT_RC macro in the Android.mk file places logcatd.rc in /system/etc/init/ during the build process.  Init loads logcatd.rc during the mount_all command and allows the service to be run and the action to be queued when appropriate.

以/system/core/logcat目录下的logcatd.rc和Android.mk文件为例。在Android.mk文件中的LOCAL_INIT_RC宏指令,在编译过程中把logcatd.rc放到了/system/etc/init/。Init执行程序在mount_all命令中加载logcatd.rc文件,并在适当的时候让这个service运行,让其action被排进队列中去。   (Android.mk中有语句:  LOCAL_INIT_RC := logcatd.rc)

This break up of init.rc files according to their daemon is preferred to the previously used monolithic init.rc files.  This approach
ensures that the only service entries that init reads and the only actions that init performs correspond to services whose binaries are in fact present on the file system, which was not the case with the monolithic init.rc files.  This additionally will aid in merge
conflict resolution when multiple services are added to the system, as each one will go into a separate file.

基于其虚拟机的init.rc 文件的这种分解要优于之前使用的一体的 init.rc 文件。这种方法证实 init 读取的那些 services 的唯一入口
和 init 执行的那些 actions 与其二进制文件在文件系统上的那些服务相关,它们与 那些一体的 init.rc 文件不是一回事。当多个Service被添加到系统中时,这样做有助于合并冲突解决,而其中的每一个service会进入一个独立的文件。

 

三、Actions

Actions are named sequences of commands.  Actions have a trigger which is used to determine when the action should occur.  When an event occurs which matches an action's trigger, that action is added to the tail of a to-be-executed queue (unless it is already on the queue).

Actions是一系列的命令。Actions有用于决定其中的action何时触发的触发器。当发生的某一事件匹配了某个action的触发器时,这个action会被添加到to-be-executed队列的末尾(除非它已被添加进去了)。

Each action in the queue is dequeued in sequence and each command in that action is executed in sequence.  Init handles other activities (device creation/destruction, property setting, process restarting) "between" the execution of the commands in activities.

队列中的每个action按序出列(应该是指FIFO吧),action中的每个命令也是按顺序执行。Init 程序在这些命令执行间隙处理其他事务(设备创建或销毁,设置,进程重启)。

Actions take the form of:
on <trigger> [&& <trigger>]*
   <command>
   <command>
   <command>

Actions的格式。

 

四、Services

Services are programs which init launches and (optionally) restarts when they exit.  Services take the form of:
service <name> <pathname> [ <argument> ]*
   <option>
   <option>
   ...

Services是程序,init 会启动它们,或者当它们退出时会重启它们。

以下是alps/system/core/logcat/logcatd.rc中的service:

service logcatd /system/bin/logcat -b all -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n 256
    class late_start
    disabled
    # logd for write to /data/misc/logd, log group for read from log daemon
    user logd
    group log
    writepid /dev/cpuset/system-background/tasks
    oom_score_adjust -600

 

五、Options

-------
Options are modifiers to services.  They affect how and when init runs the service.

Options是services的修饰语。它们会影响 init 运行 service 的方式和时间。

5.1 critical
  This is a device-critical service. If it exits more than four times in four minutes, the device will reboot into recovery mode.

表明这是一个device-critical service。如果这个service在四分钟内退出了超过4次,这个设备将重启进入recovery 模式。

5.2 disabled
  This service will not automatically start with its class.
  It must be explicitly started by name.

表明这个service的class不会自动启动。它必须通过名字进行精确的启动。

5.3 setenv <name> <value>
  Set the environment variable <name> to <value> in the launched process.

在启动进程中设置环境变量,将<name>赋值给<value>。

5.4 socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]
  Create a unix domain socket named /dev/socket/<name> and pass its fd to the launched process.  <type> must be "dgram", "stream" or "seqpacket".
  User and group default to 0.
  'seclabel' is the SELinux security context for the socket.
  It defaults to the service security context, as specified by seclabel or computed based on the service executable file security context.

创建一个名为 /dev/socket/<name> 的unix域套接字,并把它的文件句柄传递给启动进程。<type>的值必须为"dgram"/"stream"/"seqpacker"三者之一。<user>和<group>的默认值为0。<seclabel>是socket的SELinux 安全上下文,其默认值预设为service的安全上下文,其值可以通过seclabel指定或基于service可执行文件安全上下文得到的计算值。

5.5 user <username>
  Change to username before exec'ing this service.
  Currently defaults to root.  (??? probably should default to nobody)
  As of Android M, processes should use this option even if they require linux capabilities.  Previously, to acquire linux   capabilities, a process would need to run as root, request the  capabilities, then drop to its desired uid.  There is a new   mechanism through fs_config that allows device manufacturers to add linux capabilities to specific binaries on a file system that should be used instead. This mechanism is described on http://source.android.com/devices/tech/config/filesystem.html.  When
  using this new mechanism, processes can use the user option to select their desired uid without ever running as root.

在执行这个service之前变更user为<username>。当前默认值是root(大概应该将默认值设置为nobody)。从Android M开始,即使进程请求linux capabilities,也应该使用这个选项。之前,为了请求linux capabilities,一个进程需要以root模式运行去请求这些capabilities,然后再回到它自己的uid去。现在有了一种新的机制,它通过 fs_config(允许设备制造商添加linux capabilities到必须改为使用的文件系统上的特定的二进制文件中)起作用。这个机制在 http://source.android.com/devices/tech/config/filesystem.html上有详细描述。当使用这个新的机制时,进程可以使用user选项去选择它们需要的uid而不用以root模式运行。

5.6 group <groupname> [ <groupname> ]*
  Change to groupname before exec'ing this service.  Additional groupnames beyond the (required) first one are used to set the
  supplemental groups of the process (via setgroups()).
  Currently defaults to root.  (??? probably should default to nobody)

在执行这个service之前变更group为<groupname>。除了必须的第一个groupname,额外的groupnames用于设置进程的辅助groups。

5.7 seclabel <seclabel>
  Change to 'seclabel' before exec'ing this service.
  Primarily for use by services run from the rootfs, e.g. ueventd, adbd.
  Services on the system partition can instead use policy-defined transitions based on their file security context.
  If not specified and no transition is defined in policy, defaults to the init context.

在执行这个service之前变更seclabel为<seclabel>。这个主要用于那些从根文件系统运行的services,比如ueventd、adbd等。在system分区的services可以使用基于它们自已的文件安全上下文的在方案中定义的transition(什么意思?)作为代替。如果既没有指定也没有在方案中定义,则默认值会设为init的上下文。

5.8 oneshot
  Do not restart the service when it exits.

当service退出时,不重启它。

5.9 class <name>
  Specify a class name for the service.  All services in a named class may be started or stopped together.  A service
  is in the class "default" if one is not specified via the class option.

为service指定一个class名称(这个class与类名是一个意思吗?)。使用相同的class名字的所有的services将会被一起启动或停止。如果一个服务没有在class选项中定义一个名字,那它的class名称是"default"。

5.10 onrestart
  Execute a Command (see below) when service restarts.

当service重启时会执行的命令。

5.11 writepid <file...>
  Write the child's pid to the given files when it forks. Meant for cgroup/cpuset usage.

当service fork后,将其child的pid写入给定的文件中。适用于cgroup/cpuset。

 

 

critical
disabled
setenv <name> <value>
socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]
user <username>
group <groupname> [ <groupname> ]*
seclabel <seclabel>
oneshot
class <name>
onrestart
writepid <file...>

 

六、Triggers

--------
Triggers are strings which can be used to match certain kinds of events and used to cause an action to occur.
Triggers are subdivided into event triggers and property triggers.

Triggers是一些字串,它们可被用于匹配确定类型的事件以及触发action。被分为事件触发器和属性触发器。

Event triggers are strings triggered by the 'trigger' command or by the QueueEventTrigger() function within the init executable.  These take the form of a simple string such as 'boot' or 'late-init'.

事件触发器是通过'trigger'命令或init执行程序中的QueueEventTrigger()函数被触发的字串。

Property triggers are strings triggered when a named property changes value to a given new value or when a named property changes value to any new value.  These take the form of 'property:<name>=<value>' and 'property:<name>=*' respectively.  Property triggers are additionally evaluated and triggered accordingly during the initial boot phase of init.
An Action can have multiple property triggers but may only have one event trigger.

属性触发器字串会在一个指定的属性值被改为一个给定的新的值或其他任何新值时被触发。分别使用'property:<name>=<value>'和'property:<name>=*'这样的形式。另外,属性触发器还会在init的初始启动阶段被评估(?)和触发。一个action可以有多个属性触发器,但只能有一个事件触发器。

For example:
'on boot && property:a=b' defines an action that is only executed when the 'boot' event trigger happens and the property a equals b.

'on boot && property:a=b'语句定义的action,当'boot'事件触发器发生且属性a的值是b时,这个action被执行。

'on property:a=b && property:c=d' defines an action that is executed at three times,
   1) During initial boot if property a=b and property c=d
   2) Any time that property a transitions to value b, while property c already equals d.
   3) Any time that property c transitions to value d, while property a already equals b.

'on property:a=b && property:c=d'语句定义的action会被执行三次:
1) 在初始化启动中,如果属性a的值等于b且属性c的值等于d;
2) 任意时候当属性a的值转变成b且属性c的值还等于d时;
3) 任意时候当属性c的值转变成d且属性a的值还等于b时;

 

七、Commands

--------
7.1 bootchart_init
   Start bootcharting if configured (see below).  This is included in the default init.rc.

如果bootcharting配置了的话,启动它。它被包含在默认的 init.rc 中。

7.2 chmod <octal-mode> <path>
   Change file access permissions.  修改文件存取权限。

7.3 chown <owner> <group> <path>
   Change file owner and group.  修改文件的owner和group。

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

对于class name为<serviceclass>的所有services,如果没有处于运行状态,启动它们。

7.5 class_stop <serviceclass>
   Stop and disable all services of the specified class if they are  currently running.

对于class name为<serviceclass>的所有services,如果它们处于运行状态,停止并禁用它们。

7.6 class_reset <serviceclass>
   Stop all services of the specified class if they are currently running, without disabling them. They can be restarted later using class_start.

对于class name为<serviceclass>的所有services,如果它们处于运行状态,停止但不禁用它们。它们可以通过class_start被重新启动。

7.7 copy <src> <dst>
   Copies a file. Similar to write, but useful for binary/large amounts of data.

复制一个文件。与写相似,对于二进制文件和大数据文件很有用。

7.8 domainname <name>
   Set the domain name. 设置域名。

7.9 enable <servicename>
   Turns a disabled service into an enabled one as if the service did not specify disabled. If the service is supposed to be running, it will be started now. Typically used when the bootloader sets a variable that indicates a specific service should be started when needed.     E.g.     on property:ro.boot.myfancyhardware=1
                               enable my_fancy_service_for_my_fancy_hardware

将一个被禁用的service转为可用。如果这个service需要被运行,那就马上启动它。典型用法是,bootloader设置一个变量,这个变量代表了一个确定的service,而这个service在需要的时候应该被启动起来。紧接着的例子应该是通过属性触发器来enable这个service。

7.10 exec [ <seclabel> [ <user> [ <group> ]* ] ] -- <command> [ <argument> ]*
   Fork and execute command with the given arguments. The command starts after "--" so that an optional security context, user, and supplementary groups can be provided. No other commands will be run until this one finishes. <seclabel> can be a - to denote default.

用给定的参数复刻和执行命令。命令项以"--"开始,前面可以提供可选项<seclabel>  <user>  <group> 等的值。这个命令执行完才能执行其他命令。<seclabel>可以设置成'-',表示它使用的是默认值。

7.11 export <name> <value>
   Set the environment variable <name> equal to <value> in the global environment (which will be inherited by all processes
   started after this command is executed)

在全局环境中,设置环境变量<name>的值为<value>。设置后,在这个命令执行后启动的所有进程都会继承这个环境变量的值。

7.12 hostname <name>
   Set the host name.  设置主机名。

7.13 ifup <interface>
   Bring the network interface <interface> online.  把网络接口<interface>激活联网。

7.14 insmod <path>
   Install the module at <path>    在<path>路径安装模块。

7.15 load_all_props
   Loads properties from /system, /vendor, et cetera.
   This is included in the default init.rc.

从/system, /vendor等路径加载属性。 这个被包含在默认init.rc文件中。

7.16 load_persist_props
   Loads persistent properties when /data has been decrypted.
   This is included in the default init.rc.

当/data被解码后,从其中加载持久性属性。这个被包含在默认init.rc文件中。

7.17 loglevel <level>
   Sets the kernel log level to level. Properties are expanded within <level>.

把kernel log的等级设为等级<level>。 在等级<level>中,属性会被扩展。

7.18 mkdir <path> [mode] [owner] [group]
   Create a directory at <path>, optionally with the given mode, owner, and group. If not provided, the directory is created with permissions 755 and owned by the root user and root group. If provided, the mode, owner and group will be updated if the directory exists already.

根据<path>值创建目录,可选参数有mode, owner, group。 如果不带这些参数,创建的目录的权限是755,owner是根用户,group是根组。如果带了这些参数,即使这个目录已经存在,它的这些属性也会被更新。

7.19 mount_all <fstab> [ <path> ]*
   Calls fs_mgr_mount_all on the given fs_mgr-format fstab and imports .rc files at the specified paths (e.g., on the partitions just mounted). Refer to the section of "Init .rc Files" for detail.

根据给定的fs_mgr-format <fstab>调用fs_mgr_mount_all。在指定路径(如刚挂载上的分区)导入.rc文件。具体参考前面的章节。

7.20 mount <type> <device> <dir> [ <flag> ]* [<options>]
   Attempt to mount the named device at the directory <dir>
   <device> may be of the form mtd@name to specify a mtd block device by name.
   <flag>s include "ro", "rw", "remount", "noatime", ...
   <options> include "barrier=1", "noauto_da_alloc", "discard", ... as a comma separated string, eg: barrier=1,noauto_da_alloc

将<device>挂载到路径<dir>;
<device>格式可能是mtd@name形式,其中的mtd指定了一个mtd block;
<flag>的值包括"ro", "rw", "remount", "noatime", ...
<options>的值包括"barrier=1", "noauto_da_alloc", "discard", ...   是一个用逗号分开的字串,如barrier=1,noauto_da_alloc

7.21 powerctl
   Internal implementation detail used to respond to changes to the "sys.powerctl" system property, used to implement rebooting.

内部实现细节用于回应对"sys.powerctl"系统属性的改变,用于实现重启操作。

7.22 restart <service>
   Like stop, but doesn't disable the service. 和stop相似,但不禁用service。

7.23 restorecon <path> [ <path> ]*
   Restore the file named by <path> to the security context specified in the file_contexts configuration.
   Not required for directories created by the init.rc as these are automatically labeled correctly by init.

恢复文件(文件名是<path> )的安全上下文为file_contexts配置设置的安全上下文。

7.24 restorecon_recursive <path> [ <path> ]*
   Recursively restore the directory tree named by <path> to the security contexts specified in the file_contexts configuration.

递归恢复文件上下文。包含<path>的当前目录文件及子目录文件(?)。

7.25 rm <path>
   Calls unlink(2) on the given path. You might want to use "exec -- rm ..." instead (provided the system partition is already mounted).

在指令路径调用unlink(2)。 用户可能想使用"exec -- rm ..." (提供已挂载的系统分区)。

7.26 rmdir <path>
   Calls rmdir(2) on the given path. 对于给定路径使用rmdir(2)。

7.27 setprop <name> <value>
   Set system property <name> to <value>. Properties are expanded within <value>.

设置系统属性<name>的值为<value>。

7.28 setrlimit <resource> <cur> <max>
   Set the rlimit for a resource. 为一个资源设置rlimit。

7.29 start <service>
   Start a service running if it is not already running. 开始一个service。

7.30 stop <service>
   Stop a service from running if it is currently running. 停止一个正在运行的service。

7.31 swapon_all <fstab>
   Calls fs_mgr_swapon_all on the given fstab file. 在给定的<fstab>文件上调用fs_mgr_swapon_all。

7.32 symlink <target> <path>
   Create a symbolic link at <path> with the value <target> 创建符号链接。

7.33 sysclktz <mins_west_of_gmt>
   Set the system clock base (0 if system clock ticks in GMT)  设置系统时钟基准。

7.34 trigger <event>
   Trigger an event.  Used to queue an action from another action. 触发<event>事件。用于给action排队。

7.35 verity_load_state
   Internal implementation detail used to load dm-verity state. 用于加载dm-verity状态的内部实现。

7.36 verity_update_state <mount_point>
   Internal implementation detail used to update dm-verity state and set the partition.<mount_point>.verified properties used by adb remount because fs_mgr can't set them directly itself.

用于更新dm-verity状态,和用adb remount(因fs_mgr不能设置)去设置partition.<mount_point>.verified 属性。

(关于dm-verity: Android 中的dm-verity

7.37 wait <path> [ <timeout> ]
   Poll for the existence of the given file and return when found, or the timeout has been reached. If timeout is not specified it
   currently defaults to five seconds.

基于给定文件名查询其是否存在,当其被找到或超时,则返回。如果不指定超时时间,则使用默认时间5s。

7.38 write <path> <content>
   Open the file at <path> and write a string to it with write(2).
   If the file does not exist, it will be created. If it does exist, it will be truncated. Properties are expanded within <content>.

打开文件<path>,并通过write(w)写内容进去。如果文件不存在,则创建它。如果已存在,它会被截断(什么意思?)。文件属性基于<content>被扩展(什么意思?)。

 

八、Imports

-------
The import keyword is not a command, but rather its own section and is handled immediately after the .rc file that contains it has finished being parsed.  It takes the below form:

import关键字不是一个命令而是它自己的部分,且在包含了它的 .rc文件被解析完毕后,它会立即执行。它的格式如下:

import <path>
   Parse an init config file, extending the current configuration. If <path> is a directory, each file in the directory is parsed as a config file. It is not recursive, nested directories will not be parsed.

解析阿一个初始配置文件,添加到当前配置中去。如果<path>是一个目录,则目录下的每个文件都会作为一个配置文件被解析。但它不是递归的,它并不会去解析子目录内容。

There are only two times where the init executable imports .rc files,
   1) When it imports /init.rc during initial boot
   2) When it imports /{system,vendor,odm}/etc/init/ or .rc files at specified paths during mount_all

init 程序导入 .rc 文件只发生两次,
1) 在初始化启动中导入/init.rc时
2) 在mount_all过程中,它导入/{system,vendor,odm}/etc/init/ or 指定路径的 .rc 文件时

 

九、Properties

----------
Init provides information about the services that it is responsible for via the below properties.

Init 程序通过以下属性提供它负责的services 的信息:

init.svc.<name>
   State of a named service ("stopped", "stopping", "running", "restarting")

给定名称的service的状态,状态值有"stopped", "stopping", "running", "restarting"

 

十、Bootcharting

------------
This version of init contains code to perform "bootcharting": generating log files that can be later processed by the tools provided by www.bootchart.org.

init 包含了执行 "bootcharting" 的代码,其作用是:生成log文件,它们可以通过www.bootchart.org提供的工具被处理。

On the emulator, use the -bootchart <timeout> option to boot with bootcharting activated for <timeout> seconds.

在模拟器上,使用 -bootchart <timeout> 选项来携带 bootcharging 启动,激活的有效时长是<timeout>秒。

On a device, create /data/bootchart/start with a command like the following:

在设备上,则通过下面的命令创建 /data/bootchart/start

 

adb shell 'echo $TIMEOUT > /data/bootchart/start'

Where the value of $TIMEOUT corresponds to the desired bootcharted period in seconds. Bootcharting will stop after that many seconds have elapsed.

 

$TIMEOUT值以秒为单位,代表了bootcharted需要的时长。

You can also stop the bootcharting at any moment by doing the following: 

adb shell 'echo 1 > /data/bootchart/stop'   #使用这个命令语句可以随时终止bootcharting

Note that /data/bootchart/stop is deleted automatically by init at the end of the bootcharting. This is not the case with /data/bootchart/start, so don't forget to delete it when you're done collecting data.

 

/data/bootchart/stop文件会在bootcharting结束后,被 init 自动删除。这与/data/bootchart/start 不同,因此在结束收集数据后,要去手动删除 start 文件。

The log files are written to /data/bootchart/. A script is provided to retrieve them and create a bootchart.tgz file that can be used with the bootchart command-line utility:

log文件都被写到了 /data/bootchart/ 目录。 下面的脚本用于获取这些文件,然后打包成可被bootchart命令行使用的bootchart.tgz文件。

  sudo apt-get install pybootchartgui
  # grab-bootchart.sh uses $ANDROID_SERIAL.
  $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh

One thing to watch for is that the bootchart will show init as if it started running at 0s. You'll have to look at dmesg to work out when the kernel actually started init.

 

需要注意一点,如果bootchart在0s时(?)开始运行,那它会记录init。需要通过dmesg去计算kernel事件启动init的时间。

(注,dmesg显示开机信息。kernel会将开机信息存储在ring buffer中。若是开机时来不及查看信息,可利用dmesg来查看。开机信息亦保存在/var/log目录中,名称为dmesg的文件里。)

Comparing two bootcharts
------------------------
A handy script named compare-bootcharts.py can be used to compare the start/end time of selected processes. The aforementioned grab-bootchart.sh will leave a bootchart tarball named bootchart.tgz at /tmp/android-bootchart. If two such barballs are preserved on the host machine under different directories, the script can list the timestamps differences. For example:

名为compare-bootcharts.py的脚本可以方便的比较选中进程的开始或结束时间。上节中提到的grab-bootchart.sh会把一个名为bootchart.tgz的bootchart包放在/tmp/android-bootchart目录下。如果有两个这样的包文件被保存在同一主机的两个不同目录下,那么脚本compare-bootcharts.py就可以列出时间点的不同之处。示例如下:

Usage: system/core/init/compare-bootcharts.py base_bootchart_dir exp_bootchart_dir
process: baseline experiment (delta)
 - Unit is ms (a jiffy is 10 ms on the system) (以ms为单位,system上10ms为一个记录)
------------------------------------
/init: 50 40 (-10)
/system/bin/surfaceflinger: 4320 4470 (+150)
/system/bin/bootanimation: 6980 6990 (+10)
zygote64: 10410 10640 (+230)
zygote: 10410 10640 (+230)
system_server: 15350 15150 (-200)
bootanimation ends at: 33790 31230 (-2560)

 

 

十一、Systrace

--------
Systrace (http://developer.android.com/tools/help/systrace.html) can be used for obtaining performance analysis reports during boot time on userdebug or eng builds. Here is an example of trace events of "wm" and "am" categories:

Systrace用于获取userdebug或eng版本在开机阶段的性能分析报告。以下示例是跟踪"wm"和"am"项:

 $ANDROID_BUILD_TOP/external/chromium-trace/systrace.py wm am --boot

This command will cause the device to reboot. After the device is rebooted and the boot sequence has finished, the trace report is obtained from the device and written as trace.html on the host by hitting Ctrl+C.

这个命令会让设备重启。设备重启且开机事项都完成后,跟踪报告可以从设备上获取到,报告名为trace.html


LIMITATION

 

Recording trace events is started after persistent properties are loaded, so the trace events that are emitted before that are not recorded. Several services such as vold, surfaceflinger, and servicemanager are affected by this limitation since they are started before persistent properties are loaded. Zygote initialization and the processes that are forked from the zygote are not affected.

 

只有在persistent属性全部加载完之后才会记录trace事件,如果trace事件是在这些属性被加载完成之前发生,则不会被记录。因此原因被影响到的服务有vold, surfaceflinger, servicemanager。Zygote初始化和从zygote fork出来的进程不受影响。

 

 

十二、Debugging init

--------------
By default, programs executed by init will drop stdout and stderr into /dev/null. To help with debugging, you can execute your program via the Android program logwrapper. This will redirect stdout/stderr into the Android logging system (accessed via logcat).For example

被init执行的程序,默认会把标准输出和标准错误输入到/dev/null中。为便于debugging,可以使用Android程序logwrapper来执行自己的程序。logwrapper 会把 stdout/stderr 重定向到Android 日志系统,它可以通过logcat访问。示例如下:

service akmd /system/bin/logwrapper /sbin/akmd

(下面是做什么的?)

For quicker turnaround when working on init itself, use:

  mm -j
  m ramdisk-nodeps
  m bootimage-nodeps
  adb reboot bootloader
  fastboot boot $ANDROID_PRODUCT_OUT/boot.img

Alternatively, use the emulator: 

emulator -partition-size 1024 -verbose -show-kernel -no-window

You might want to call klog_set_level(6) after the klog_init() call so you see the kernel logging in dmesg (or the emulator output).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值