AndroidT(13) Log 系统 -- logd的编译及启动(五)

1. 概览

  之前几章介绍了native层的LOG输出以及分析其实现,但那都是客户端,如果只有客户端组装发送数据而没有服务端进行处理的话,LOG的输出也是无法实现的。logd也就是这些客户端的服务端了,概览图见《natvie LOG 输出的实现》章节。下面就来看看 logd 的编译脚本以及它在 Android 系统中如何被启动的。

2.logd的编译 – Android.bp

  AOSP T 版本中,logd已经使用 Android.bp 来描述编译了,下面是对应的文件

//system\logging\logd\Android.bp
cc_defaults {
    name: "logd_defaults",

    shared_libs: [
        "libbase",
        "libz",
    ],
    ...
}

cc_binary {
    name: "logd",
    defaults: ["logd_defaults"],
    init_rc: ["logd.rc"],
    srcs: [
        ...
        "main.cpp",
        ...
    ],
    ...
}

  编译完后则位于 system 分区下,其以 logd 命名。logd.rc 则会被放置到 system/etc/init 目录下,在 Android 启动的时候由 init 进程解析并执行。
值得注意的是 logd_defaults 的内容则是被继承了。源码部分 main.cpp 则包含了 logd 执行时的入口函数 main 。

/system/bin/logd

3. logd 服务定义

  在 Android 中系统服务的启动,是 init 根据所给的 rc 配置文件 fork 而来的。logd同样也不例外,其对应的rc文件则是 logd.rc,定义如下

//system\logging\logd\logd.rc
service logd /system/bin/logd
    #a
    socket logd stream 0666 logd logd
    #b
    socket logdr seqpacket 0666 logd logd
    #c
    socket logdw dgram+passcred 0222 logd logd
    #d
    file /proc/kmsg r
    file /dev/kmsg w
    #e
    onrestart setprop logd.ready false

  上面rc主要做了如下几件事
    a)创建socket logd,用于接收控制 logd 本身的请求。
    b)创建socket logdr,用于client来读取由 logd 管理的log,例如logcat显示的log则是通过该节点获得。
    c)创建socket logdw,用于client写入log,例如在java代码中使用接口Slog打印的log,这些log可以通过logcat获取并显示。
    d)提前打开 kernel log相关的文件,file 命令被 init 所支持,其用于优化代码执行过程的效率,把原来程序执行所需要执行的指令放到了初始化阶段。下面是 init 中对file命令的说明,很清晰

file <path> <type>
Open a file path and pass its fd to the launched process. _type_ must be
  "r", "w" or "rw".  For native executables see libcutils android_get_control_file().

      所以e阶段的含义是,在init启动logd的时候就打开/proc/kmsg及/dev/kmsg这两个文件,前者以仅读权限打开,后者以仅写权限打开。后续 logd 想获取对应文件的 fd 通过 libcutils 的接口(android_get_control_file)获取。
    e)初始化属性,logd.ready 为 false,该属性值代表logd的功能是否初始化完成,例如,如果此属性被logd设置为true后,logcat工具以及代码中系列LOG接口就可以正常使用了。

4. logd 服务的启动

4.1 logd 的启动阶段

  logd.rc 中虽然申明了logd 服务但并不会直接启动,下面是 logd 的启动点,

//system/etc/init/hw/init.rc
on init
    ...
    # Start logd before any other services run to ensure we capture all of their logs.
    start logd

  可见它的启动则是位于 init.rc 中的 init 阶段,即系统初始化到init阶段时则会启动logd服务。
  下面则 init 中所支持的各个启动点,用户可以在自己的rc文件中配置其合适的启动点

//file:system/core/init/README.md
Trigger Sequence
----------------
Init uses the following sequence of triggers during early boot. These are the
built-in triggers defined in init.cpp.

   1. early-init
        - The first in the sequence, triggered after cgroups has been configured
      but before ueventd's coldboot is complete.
   2. init
        - Triggered after coldboot is complete.
   3. charger
        - Triggered if ro.bootmode == "charger".
   4. late-init
        - Triggered if ro.bootmode != "charger", or via healthd triggering a boot from charging mode.
   5. early-fs
        - Start vold.
   6. fs
        - Vold is up. Mount partitions not marked as first-stage or latemounted.
   7. post-fs
        - Configure anything dependent on early mounts.
   8 late-fs
        - Mount partitions marked as latemounted.
   9. post-fs-data
        - Mount and configure "/data";
        set up encryption. "/metadata" is reformatted here if it could not mount in first-stage init.
   10. zygote-start
        - Start the zygote.
   11. early-boot
        - After zygote has started.
   12. boot
        - After `early-boot` actions have completed.

  可见 logd 的启动还是非常的早的,因为 log 对于调试来说还是非常的重要及方便的。

4.2 logd 服务的执行入口

  实际上 service 后面的内容就是服务的启动命令,和在 linux 命令行窗口启动并无二至

logd /system/bin/logd

  从logd服务的启动配置来看,它是无参数启动。所以对于 main 我们是无需更新 argc、argv的。

//system\logging\logd\main.cpp
int main(int argc, char* argv[]) {

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值