Android 开机底层优化

作者: 小草凡 | 来源:发表于2017-06-03 21:30 被阅读0次

    本篇博文作为Android 开机优化 的续篇,之前的博文在排查底层耗时比较粗糙。本篇作为补充,提供剖析底层耗时的方法。

    优化Bootloader

    • 减少不必要的log,最近遇到的开机慢问题就发现UART log没有关闭,这里一般而言能优化1s左右的时间。UART关闭改动kernel config文件的如下:
    CONFIG_SERIAL_MSM_HSL=n
    CONFIG_SERIAL_MSM_HSL_CONSOLE=n
    

    Android 开机优化 里也提到了可以移除部分无用的kernel config,为了方便check,编写了一个python脚本,可以方便查看哪些无用config依然包含在项目中。

    #!/usr/bin/env python
    '''
    @author: azhengye
    '''
    import difflib
    import sys
    
    _DEFAULT_CAN_REMOVE_CONFIG = [
        'CONFIG_SCHED_DEBUG\n',
        'CONFIG_DEBUG_KMEMLEAK\n',
        'CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE\n',
        'CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF\n',
        'CONFIG_DEBUG_SPINLOCK\n',
        'CONFIG_DEBUG_MUTEXES\n',
        'CONFIG_DEBUG_ATOMIC_SLEEP\n',
        'CONFIG_DEBUG_STACK_USAGE\n',
        'CONFIG_DEBUG_LIST\n',
        'CONFIG_FAULT_INJECTION_DEBUG_FS\n',
        'CONFIG_LOCKUP_DETECTOR\n'
        'CONFIG_DEBUG_PAGEALLOC\n',
        'CONFIG_PAGE_POISONING\n',
        'CONFIG_RMNET_DATA_DEBUG_PKT\n',
        'CONFIG_MMC_PERF_PROFILING\n',
        'CONFIG_DEBUG_BUS_VOTER\n',
        'CONFIG_SLUB_DEBUG\n',
        'CONFIG_DEBUG_BUGVERBOSE\n',
        'CONFIG_ALLOC_BUFFERS_IN_4K_CHUNK\n',
        'CONFIG_SERIAL_CORE\n',
        'CONFIG_SERIAL_CORE_CONSOLE\n',
        'CONFIG_SERIAL_MSM_HSL\n',
        'CONFIG_SERIAL_MSM_HSL_CONSOLE\n',
        'CONFIG_MSM_TZ_LOG\n',
        'CONFIG_DYNAMIC_DEBUG\n',
        'CONFIG_ANDROID_LOGGER\n',
        'CONFIG_IMX134\n',
        'CONFIG_IMX132\n',
        'CONFIG_OV9724\n',
        'CONFIG_OV5648\n',
        'CONFIG_USB_MON\n',
        'CONFIG_USB_STORAGE_DATAFAB\n',
        'CONFIG_USB_STORAGE_FREECOM\n',
        'CONFIG_USB_STORAGE_ISD200\n',
        'CONFIG_USB_STORAGE_USBAT\n',
        'CONFIG_USB_STORAGE_SDDR09\n',
        'CONFIG_USB_STORAGE_SDDR55\n',
        'CONFIG_USB_STORAGE_JUMPSHOT\n',
        'CONFIG_USB_STORAGE_ALAUDA\n',
        'CONFIG_USB_STORAGE_KARMA\n',
        'CONFIG_USB_STORAGE_CYPRESS_ATACB\n',
        'CONFIG_SEEMP_CORE\n',
        'CONFIG_MSM_SMEM_LOGGING\n',
        'CONFIG_IOMMU_DEBUG\n',
        'CONFIG_IOMMU_DEBUG_TRACKING\n',
        'CONFIG_IOMMU_TESTS\n',
        'CONFIG_MOBICORE_DRIVER\n',
        'CONFIG_MSDOS_FS\n',
    ]
    
    def main(argv):
      if len(argv) != 2:
         print '%s: invalid arguments' % argv[0]
         return 2
      filename1 = argv[1]
      try:
        with open(filename1, "r") as f1:
          str1 = f1.readlines();
          list1 =[]
          for string in str1:
              if string.startswith('#') or len(string) <= 6:
                  continue
              list1.append(string.split('=')[0]+'\n')
        diffs = difflib.unified_diff(
            _DEFAULT_CAN_REMOVE_CONFIG, list1)
      except Exception as e:
        print "something wrong: %s" % e
        return 1
      status_code = 0
      for diff in diffs:
        if diff.startswith('+') or diff.startswith('-') or diff.startswith('@'):
            continue
        sys.stdout.write('follow config can be remove====>')
        sys.stdout.write(diff)
        status_code = 1
      return status_code
    
    if __name__ == '__main__':
      sys.exit(main(sys.argv))
    

    特别说明下脚本中_DEFAULT_CAN_REMOVE_CONFIG只是一个通用的可移除config列表,在移除之前一定要跟具体项目挂钩check。

    脚本使用方法:
    a: 先单独编译user版本的kernel,然后去out目录下找到生成的.config文件。
    b: 保持上述脚本为check-config.py。 运行check-config.py .config
    输出如下类似结果:

    follow config can be remove====> CONFIG_MMC_PERF_PROFILING
    follow config can be remove====> CONFIG_MSM_TZ_LOG
    
    • 内核编译完成后会生成zImage内核镜像文件。然后bootloader加载zImage,这之后就需要解压zImage.默认的压缩算法是GZIP,使用LZ4压缩算法能缩短时间。可以参考该patch[https://patchwork.kernel.org/patch/6810841/] 来修改。这块节省的时间有限,不到1s,权衡利弊后,最终没有take到实际项目中,追求完美的你可以试试。风险自担-_-

    boot签名校验优化

    最近新项目上出现的这个坑,由于项目是高通平台,同时自定义了一套自己的签名规则,在自定义签名出问题时,又会重新走高通的签名。拉长了启动时间。之前怀疑过这块,但苦于找不到证据。最终还是在查看/proc下面的一堆节点时找到了线索,cat /proc/morelog找到了证据:

    [730] boot_verifier: Signature decrypt failed! Signature invalid = -1
    [790] Your device has loaded a different operating system.
    Wait for 5 seconds before proceeding
    

    拿到这个证据,找负责签名的同事更改这块,优化了不少时间。

    同时还发现了一个好东西/proc/bootprof,之前没有关注过这个节点,cat一下看到了非常有用的信息,列出来感受下。

    ----------------------------------------
    0       BOOT PROF (unit:msec)
    ----------------------------------------
           953        : preloader
           779        : first logo
          2671        : lk
    ----------------------------------------
            20.233999 : ON
           135.360846 :    1-swapper/0       : initcall: arm64_device_init    49.639539ms
           218.746846 :    1-swapper/0       : initcall: event_trace_init    33.785154ms
           236.874461 :    1-swapper/0       : probe: probe=platform_drv_probe drv=mt-pmic(ffffffc001076840)    15.639385ms
           236.918615 :    1-swapper/0       : initcall: pmic_mt_init    16.109692ms
           311.124539 :    1-swapper/0       : initcall: populate_rootfs    71.181924ms
           381.334693 :    1-swapper/0       : probe: probe=platform_drv_probe drv=musb-hdrc(ffffffc0010829f0)    17.795231ms
           381.360769 :    1-swapper/0       : probe: probe=platform_drv_probe drv=musb-mtu3d(ffffffc001082c30)    17.965769ms
           381.861308 :    1-swapper/0       : initcall: mtu3d_driver_init    18.712692ms
          1717.001003 :    1-swapper/0       : probe: probe=i2c_device_probe drv=bq25890(ffffffc00110cc58)  1248.854233ms
          1717.779465 :    1-swapper/0       : initcall: bq25890_init  1249.733311ms
          1828.548927 :    1-swapper/0       : probe: probe=platform_drv_probe drv=mtkfb(ffffffc001096780)    29.705308ms
          1829.394927 :    1-swapper/0       : initcall: mtkfb_init    30.689154ms
         //省略内容
    

    还有/proc/bootmsg节点也非常有用。
    这里正好弥补了Android 开机优化 中perftool的不足,能看到更底层的启动耗时。

    systrace debug 开机问题

    systrace的根基是linux 的ftrace,它不仅能分析上层的性能问题,底层问题同样也可以使用,不过需要对底层代码做些修改。具体如下:

    • 修改frameworks/native/cmds/atrace/atrace.rc
      打开默认关闭的trace开关。
    -    write /sys/kernel/debug/tracing/tracing_on 0
    +    #write /sys/kernel/debug/tracing/tracing_on 0
    
    • 适当的位置加入如下改动,之所以适当,因为不同平台编译文件有差异,这个需要结合项目代码去寻找位置。高通平台可以在device/qcom/common/common.mk文件中添加:
    PRODUCT_PROPERTY_OVERRIDES += debug.atrace.tags.enableflags=802922
    
    • 同样适当的make文件中加入如下修改,比如BoardConfig.mk文件
    BOARD_KERNEL_CMDLINE += trace_buf_size=64M trace_event=sched_wakeup,sched_switch,sched_blocked_reason,sched_cpu_hotplug,block,ext4
    
    • 项目的init.rc文件加入如下修改,目的是结束trace记录。
     on property:sys.boot_completed=1
        start qrngp
    +   write /d/tracing/tracing_on 0
    +   write /d/tracing/events/ext4/enable 0
    +   write /d/tracing/events/block/enable 0
    

    做完上述修改后编译烧录镜像文件,待开机结束后执行:

    adb root && adb shell "cat /d/tracing/trace" > boot_trace
    

    然后执行

    external/chromium-trace/catapult/tracing/bin/trace2html boot_trace 
    

    上述命令可以将trace log转成systrace文件,用chrome浏览器打开,方便分析。


    这里写图片描述

    总结

    开机优化问题涉及的模块很多,通过这两篇博文,大致给出了从底层到上层的分析方法和部分解决方案。欢迎大家一起探讨分享。

    相关文章

      网友评论

        本文标题:Android 开机底层优化

        本文链接:https://www.haomeiwen.com/subject/dsvmfxtx.html