Android 開機(jī)底層優(yōu)化

本篇博文作為Android 開機(jī)優(yōu)化 的續(xù)篇,之前的博文在排查底層耗時(shí)比較粗糙。本篇作為補(bǔ)充,提供剖析底層耗時(shí)的方法。

優(yōu)化Bootloader

  • 減少不必要的log,最近遇到的開機(jī)慢問題就發(fā)現(xiàn)UART log沒有關(guān)閉,這里一般而言能優(yōu)化1s左右的時(shí)間。UART關(guān)閉改動(dòng)kernel config文件的如下:
CONFIG_SERIAL_MSM_HSL=n
CONFIG_SERIAL_MSM_HSL_CONSOLE=n

Android 開機(jī)優(yōu)化 里也提到了可以移除部分無用的kernel config,為了方便check,編寫了一個(gè)python腳本,可以方便查看哪些無用config依然包含在項(xiàng)目中。

#!/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只是一個(gè)通用的可移除config列表,在移除之前一定要跟具體項(xiàng)目掛鉤check。

腳本使用方法:
a: 先單獨(dú)編譯user版本的kernel,然后去out目錄下找到生成的.config文件。
b: 保持上述腳本為check-config.py。 運(yùn)行check-config.py .config
輸出如下類似結(jié)果:

follow config can be remove====> CONFIG_MMC_PERF_PROFILING
follow config can be remove====> CONFIG_MSM_TZ_LOG
  • 內(nèi)核編譯完成后會(huì)生成zImage內(nèi)核鏡像文件。然后bootloader加載zImage,這之后就需要解壓zImage.默認(rèn)的壓縮算法是GZIP,使用LZ4壓縮算法能縮短時(shí)間。可以參考該patch[https://patchwork.kernel.org/patch/6810841/] 來修改。這塊節(jié)省的時(shí)間有限,不到1s,權(quán)衡利弊后,最終沒有take到實(shí)際項(xiàng)目中,追求完美的你可以試試。風(fēng)險(xiǎn)自擔(dān)-_-

boot簽名校驗(yàn)優(yōu)化

最近新項(xiàng)目上出現(xiàn)的這個(gè)坑,由于項(xiàng)目是高通平臺,同時(shí)自定義了一套自己的簽名規(guī)則,在自定義簽名出問題時(shí),又會(huì)重新走高通的簽名。拉長了啟動(dòng)時(shí)間。之前懷疑過這塊,但苦于找不到證據(jù)。最終還是在查看/proc下面的一堆節(jié)點(diǎn)時(shí)找到了線索,cat /proc/morelog找到了證據(jù):

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

拿到這個(gè)證據(jù),找負(fù)責(zé)簽名的同事更改這塊,優(yōu)化了不少時(shí)間。

同時(shí)還發(fā)現(xiàn)了一個(gè)好東西/proc/bootprof,之前沒有關(guān)注過這個(gè)節(jié)點(diǎn),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
     //省略內(nèi)容

還有/proc/bootmsg節(jié)點(diǎn)也非常有用。
這里正好彌補(bǔ)了Android 開機(jī)優(yōu)化 中perftool的不足,能看到更底層的啟動(dòng)耗時(shí)。

systrace debug 開機(jī)問題

systrace的根基是linux 的ftrace,它不僅能分析上層的性能問題,底層問題同樣也可以使用,不過需要對底層代碼做些修改。具體如下:

  • 修改frameworks/native/cmds/atrace/atrace.rc
    打開默認(rèn)關(guān)閉的trace開關(guān)。
-    write /sys/kernel/debug/tracing/tracing_on 0
+    #write /sys/kernel/debug/tracing/tracing_on 0
  • 適當(dāng)?shù)奈恢眉尤肴缦赂膭?dòng),之所以適當(dāng),因?yàn)椴煌脚_編譯文件有差異,這個(gè)需要結(jié)合項(xiàng)目代碼去尋找位置。高通平臺可以在device/qcom/common/common.mk文件中添加:
PRODUCT_PROPERTY_OVERRIDES += debug.atrace.tags.enableflags=802922
  • 同樣適當(dāng)?shù)膍ake文件中加入如下修改,比如BoardConfig.mk文件
BOARD_KERNEL_CMDLINE += trace_buf_size=64M trace_event=sched_wakeup,sched_switch,sched_blocked_reason,sched_cpu_hotplug,block,ext4
  • 項(xiàng)目的init.rc文件加入如下修改,目的是結(jié)束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

做完上述修改后編譯燒錄鏡像文件,待開機(jī)結(jié)束后執(zhí)行:

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

然后執(zhí)行

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

上述命令可以將trace log轉(zhuǎn)成systrace文件,用chrome瀏覽器打開,方便分析。


這里寫圖片描述

總結(jié)

開機(jī)優(yōu)化問題涉及的模塊很多,通過這兩篇博文,大致給出了從底層到上層的分析方法和部分解決方案。歡迎大家一起探討分享。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 問題描述 開機(jī)時(shí)間相對參考機(jī)過慢,大約慢15s左右。Android 系統(tǒng)7.0。 問題分析 開機(jī)問題涉及的層次較多...
    小草凡閱讀 14,972評論 1 27
  • 1:InputChannel提供函數(shù)創(chuàng)建底層的Pipe對象 2: 1)客戶端需要新建窗口 2)new ViewRo...
    自由人是工程師閱讀 5,715評論 0 18
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • ANR問題,相信是每位開發(fā)日常都會(huì)遇到的問題,對于這類問題的分析,按照官方的推薦,或網(wǎng)絡(luò)博客的總結(jié)思路能解決一定的...
    tiger桂閱讀 18,281評論 5 28
  • Android 8.0 支持一系列組件的多項(xiàng)改進(jìn),因而可以縮短啟動(dòng)時(shí)間。下表對這些性能改進(jìn)(在 Google Pi...
    youseewhat閱讀 1,845評論 0 3

友情鏈接更多精彩內(nèi)容