優(yōu)化啟動(dòng)時(shí)間

原文:https://source.android.com/devices/tech/perf/boot-times

本文檔提供了有關(guān)改進(jìn)特定 Android 設(shè)備的啟動(dòng)時(shí)間的合作伙伴指南。啟動(dòng)時(shí)間是系統(tǒng)性能的重要組成部分,因?yàn)橛脩舯仨毜却龁?dòng)完成后才能使用設(shè)備辑舷。對(duì)于較常進(jìn)行冷啟動(dòng)的汽車等設(shè)備而言滓玖,較短的啟動(dòng)時(shí)間至關(guān)重要(沒(méi)有人喜歡在等待幾十秒后才能輸入導(dǎo)航目的地)歪脏。

Android 8.0 支持一系列組件的多項(xiàng)改進(jìn)弟劲,以縮短啟動(dòng)時(shí)間绩聘。下表對(duì)這些性能改進(jìn)(在 Google Pixel 和 Pixel XL 設(shè)備上測(cè)得)進(jìn)行了總結(jié)。

組件 改進(jìn)
引導(dǎo)加載程序 * 通過(guò)移除 UART 日志節(jié)省了 1.6 秒盲憎; * 通過(guò)從 GZIP 更改為 LZ4 節(jié)省了 0.4 秒
設(shè)備內(nèi)核 * 通過(guò)移除不使用的內(nèi)核配置和減少驅(qū)動(dòng)程序大小節(jié)省了 0.3 秒; * 通過(guò) dm-verity 預(yù)提取優(yōu)化節(jié)省了 0.3 秒胳挎; * 通過(guò)移除驅(qū)動(dòng)程序中不必要的等待/測(cè)試饼疙,節(jié)省了 0.15 秒; * 通過(guò)移除 CONFIG_CC_OPTIMIZE_FOR_SIZE慕爬,節(jié)省了 0.12 秒
I/O 調(diào)整 * 正常啟動(dòng)時(shí)間節(jié)省了 2 秒窑眯; * 首次啟動(dòng)時(shí)間節(jié)省了 25 秒;
init.*.rc * 通過(guò)并行運(yùn)行 init 命令節(jié)省了 1.5 秒医窿; * 通過(guò)及早啟動(dòng) zygote 節(jié)省了 0.25 秒伸但; * 通過(guò) cpuset 調(diào)整節(jié)省了 0.22 秒
啟動(dòng)動(dòng)畫(huà) * 在未觸發(fā) fsck 的情況下,啟動(dòng)動(dòng)畫(huà)的開(kāi)始時(shí)間提前了 2 秒留搔,而觸發(fā) fsck 時(shí)啟動(dòng)動(dòng)畫(huà)則大得多更胖; * 通過(guò)立即關(guān)閉啟動(dòng)動(dòng)畫(huà)在 Pixel XL 上節(jié)省了 5 秒
SELinux 政策 通過(guò) genfscon 節(jié)省了 0.2 秒

優(yōu)化引導(dǎo)加載程序

要優(yōu)化引導(dǎo)加載程序以縮短啟動(dòng)時(shí)間,請(qǐng)遵循以下做法:

  • 對(duì)于日志記錄:
    • 停止向 UART 寫(xiě)入日志隔显,因?yàn)槿绻罩居涗浐芏嗳捶粒瑒t可能需要很長(zhǎng)時(shí)間來(lái)處理。(在 Google Pixel 設(shè)備上括眠,我們發(fā)現(xiàn)這會(huì)使引導(dǎo)加載程序的速度減慢 1.5 秒)彪标。
    • 僅記錄錯(cuò)誤情況,并考慮將其他信息存儲(chǔ)到具有單獨(dú)檢索機(jī)制的內(nèi)存中掷豺。
  • 對(duì)于內(nèi)核解壓縮捞烟,請(qǐng)考慮為當(dāng)代硬件使用 LZ4 而非 GZIP(例如補(bǔ)丁程序)薄声。請(qǐng)注意,不同的內(nèi)核壓縮選項(xiàng)具有不同的加載和解壓縮時(shí)間题画,對(duì)于特定硬件默辨,某些選項(xiàng)可能比其他選項(xiàng)更適合。
  • 檢查進(jìn)入去抖動(dòng)/特殊模式過(guò)程中是否有不必要的等待時(shí)間苍息,并最大限度地減少此類時(shí)間缩幸。
  • 將在引導(dǎo)加載程序中花費(fèi)的啟動(dòng)時(shí)間以命令行的形式傳遞到內(nèi)核。
  • 檢查 CPU 時(shí)鐘并考慮內(nèi)核加載和初始化 I/O 并行進(jìn)行(需要多核支持)竞思。

優(yōu)化內(nèi)核

請(qǐng)按照以下提示優(yōu)化內(nèi)核以縮短啟動(dòng)時(shí)間表谊。

最大限度地減少設(shè)備 defconfig

最大限度地減少內(nèi)核配置可以減小內(nèi)核大小,從而更快速地進(jìn)行加載盖喷、解壓縮爆办、初始化并縮小受攻擊面。要優(yōu)化設(shè)備 defconfig课梳,請(qǐng)執(zhí)行以下操作:

  • 識(shí)別未使用的驅(qū)動(dòng)程序押逼。查看 /dev/sys 目錄,并查找?guī)в谐R?guī) SELinux 標(biāo)簽的節(jié)點(diǎn)(這種標(biāo)簽表示相應(yīng)節(jié)點(diǎn)未配置為可由用戶空間訪問(wèn))惦界。如果找到此類節(jié)點(diǎn)挑格,請(qǐng)將其移除。
  • 取消設(shè)置未使用的配置沾歪。查看由內(nèi)核版本生成的 .config 文件漂彤,以明確取消設(shè)置所有已默認(rèn)啟用但并未使用的配置。例如灾搏,我們從 Google Pixel 中移除了以下未使用的配置:
    CONFIG_ANDROID_LOGGER=y
    CONFIG_IMX134=y
    CONFIG_IMX132=y
    CONFIG_OV9724=y
    CONFIG_OV5648=y
    CONFIG_GC0339=y
    CONFIG_OV8825=y
    CONFIG_OV8865=y
    CONFIG_s5k4e1=y
    CONFIG_OV12830=y
    CONFIG_USB_EHCI_HCD=y
    CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y
    CONFIG_IKCONFIG=y
    CONFIG_RD_BZIP2=y
    CONFIG_RD_LZMA=y
    CONFIG_TI_DRV2667=y
    CONFIG_CHR_DEV_SCH=y
    CONFIG_MMC=y
    CONFIG_MMC_PERF_PROFILING=y
    CONFIG_MMC_CLKGATE=y
    CONFIG_MMC_PARANOID_SD_INIT=y
    CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_TEST=y
    CONFIG_MMC_SDHCI=y
    CONFIG_MMC_SDHCI_PLTFM=y
    CONFIG_MMC_SDHCI_MSM=y
    CONFIG_MMC_SDHCI_MSM_ICE=y
    CONFIG_MMC_CQ_HCI=y
    CONFIG_MSDOS_FS=y 
    # CONFIG_SYSFS_SYSCALL is not set
    CONFIG_EEPROM_AT24=y
    # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
    CONFIG_INPUT_HBTP_INPUT=y
    # CONFIG_VGA_ARB is not set
    CONFIG_USB_MON=y
    CONFIG_USB_STORAGE_DATAFAB=y
    CONFIG_USB_STORAGE_FREECOM=y
    CONFIG_USB_STORAGE_ISD200=y
    CONFIG_USB_STORAGE_USBAT=y
    CONFIG_USB_STORAGE_SDDR09=y
    CONFIG_USB_STORAGE_SDDR55=y
    CONFIG_USB_STORAGE_JUMPSHOT=y
    CONFIG_USB_STORAGE_ALAUDA=y
    CONFIG_USB_STORAGE_KARMA=y
    CONFIG_USB_STORAGE_CYPRESS_ATACB=y
    CONFIG_SW_SYNC_USER=y
    CONFIG_SEEMP_CORE=y
    CONFIG_MSM_SMEM_LOGGING=y
    CONFIG_IOMMU_DEBUG=y
    CONFIG_IOMMU_DEBUG_TRACKING=y
    CONFIG_IOMMU_TESTS=y
    CONFIG_MOBICORE_DRIVER=y
    # CONFIG_DEBUG_PREEMPT is not set
  • 移除導(dǎo)致每次啟動(dòng)時(shí)運(yùn)行不必要測(cè)試的配置挫望。雖然此類配置(如 CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST)在開(kāi)發(fā)過(guò)程中很有用,但應(yīng)從正式版內(nèi)核中移除狂窑。

最大限度地減小驅(qū)動(dòng)程序大小

如果未使用相應(yīng)功能媳板,則可以移除設(shè)備內(nèi)核中的某些驅(qū)動(dòng)程序,以便進(jìn)一步減小內(nèi)核大小泉哈。例如蛉幸,如果 WLAN 通過(guò) PCIe 連接,則不會(huì)用到 SDIO 支持丛晦,因此應(yīng)在編譯時(shí)將其移除诱贿。有關(guān)詳情老虫,請(qǐng)參閱 Google Pixel 內(nèi)核:網(wǎng)絡(luò):無(wú)線:CNSS:添加選項(xiàng)以停用 SDIO 支持延刘。

移除針對(duì)大小的編譯器優(yōu)化

移除 CONFIG_CC_OPTIMIZE_FOR_SIZE 的內(nèi)核配置魂那。此標(biāo)記是在最初假設(shè)較小的代碼大小會(huì)產(chǎn)生熱緩存命中(因此速度更快)時(shí)引入的。然而锌蓄,隨著現(xiàn)代移動(dòng) SoC 變得更加強(qiáng)大升筏,這一假設(shè)不再成立撑柔。

此外,移除此標(biāo)記可以使編譯器針對(duì)未初始化的變量發(fā)出警告您访,當(dāng)存在 CONFIG_CC_OPTIMIZE_FOR_SIZE 標(biāo)記時(shí)铅忿,這一功能在 Linux 內(nèi)核中是停用的(僅這一項(xiàng)更改就已幫助我們?cè)谀承?Android 設(shè)備驅(qū)動(dòng)程序中發(fā)現(xiàn)了很多有意義的錯(cuò)誤)。

延遲初始化

很多進(jìn)程都在設(shè)備啟動(dòng)期間啟動(dòng)洋只,但只有關(guān)鍵路徑 (bootloader > kernel > init > file system mount > zygote > system server) 中的組件才會(huì)直接影響啟動(dòng)時(shí)間。在內(nèi)核啟動(dòng)期間執(zhí)行 initcall 來(lái)識(shí)別啟動(dòng)速度緩慢且對(duì)啟動(dòng) init 進(jìn)程不重要的外設(shè)/組件昼捍,然后通過(guò)將這些外設(shè)/組件移入可加載的內(nèi)核模塊將其延遲到啟動(dòng)過(guò)程的后期來(lái)啟動(dòng)识虚。移入異步設(shè)備/驅(qū)動(dòng)程序探測(cè)還有助于并行啟動(dòng)內(nèi)核 > init 重要路徑中啟動(dòng)速度緩慢的組件。

BoardConfig-common.mk:
    BOARD_KERNEL_CMDLINE += initcall_debug ignore_loglevel

driver:
    .probe_type = PROBE_PREFER_ASYNCHRONOUS,

:必須添加 EPROBEDEFER 支持來(lái)妥善解決驅(qū)動(dòng)程序依賴問(wèn)題妒茬。

優(yōu)化 I/O 效率

提高 I/O 效率對(duì)縮短啟動(dòng)時(shí)間來(lái)說(shuō)至關(guān)重要担锤,對(duì)任何不必要內(nèi)容的讀取都應(yīng)推遲到啟動(dòng)之后再進(jìn)行(在 Google Pixel 上,啟動(dòng)時(shí)大約要讀取 1.2GB 的數(shù)據(jù))乍钻。

調(diào)整文件系統(tǒng)

當(dāng)從頭開(kāi)始讀取某個(gè)文件或依序讀取塊時(shí)肛循,預(yù)讀的 Linux 內(nèi)核便會(huì)啟動(dòng),這就需要調(diào)整專門(mén)用于啟動(dòng)的 I/O 調(diào)度程序參數(shù)(與普通應(yīng)用的工作負(fù)載特性不同)银择。

支持無(wú)縫 (A/B) 更新的設(shè)備在首次啟動(dòng)時(shí)會(huì)極大地受益于文件系統(tǒng)調(diào)整(例如多糠,Google Pixel 的啟動(dòng)時(shí)間縮短了 20 秒)。例如浩考,我們?yōu)?Google Pixel 調(diào)整了以下參數(shù):

on late-fs
  # boot time fs tune
    # boot time fs tune
    write /sys/block/sda/queue/iostats 0
    write /sys/block/sda/queue/scheduler cfq
    write /sys/block/sda/queue/iosched/slice_idle 0
    write /sys/block/sda/queue/read_ahead_kb 2048
    write /sys/block/sda/queue/nr_requests 256
    write /sys/block/dm-0/queue/read_ahead_kb 2048
    write /sys/block/dm-1/queue/read_ahead_kb 2048

on property:sys.boot_completed=1
    # end boot time fs tune
    write /sys/block/sda/queue/read_ahead_kb 512
    ...

其他

  • 使用內(nèi)核配置 DM_VERITY_HASH_PREFETCH_MIN_SIZE(默認(rèn)大小為 128)來(lái)啟用 dm-verity 哈希預(yù)提取大小夹孔。
  • 為了提升文件系統(tǒng)穩(wěn)定性及取消每次啟動(dòng)時(shí)的強(qiáng)制檢查,請(qǐng)?jiān)?BoardConfig.mk 中設(shè)置 TARGET_USES_MKE2FS析孽,以使用新的 ext4 生成工具搭伤。

分析 I/O

要了解啟動(dòng)過(guò)程中的 I/O 活動(dòng),請(qǐng)使用內(nèi)核 ftrace 數(shù)據(jù)(systrace 也使用該數(shù)據(jù)):

trace_event=block,ext4 in BOARD_KERNEL_CMDLINE

要針對(duì)每個(gè)文件細(xì)分文件訪問(wèn)權(quán)限袜瞬,請(qǐng)對(duì)內(nèi)核進(jìn)行以下更改(僅限開(kāi)發(fā)版內(nèi)核怜俐;請(qǐng)勿在正式版內(nèi)核中應(yīng)用這些更改):

diff --git a/fs/open.c b/fs/open.c
index 1651f35..a808093 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -981,6 +981,25 @@
 }
 EXPORT_SYMBOL(file_open_root);
 
+static void _trace_do_sys_open(struct file *filp, int flags, int mode, long fd)
+{
+       char *buf;
+       char *fname;
+
+       buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return;
+       fname = d_path(&filp-<f_path, buf, PAGE_SIZE);
+
+       if (IS_ERR(fname))
+               goto out;
+
+       trace_printk("%s: open(\"%s\", %d, %d) fd = %ld, inode = %ld\n",
+                     current-<comm, fname, flags, mode, fd, filp-<f_inode-<i_ino);
+out:
+       kfree(buf);
+}
+
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
 {
        struct open_flags op;
@@ -1003,6 +1022,7 @@
                } else {
                        fsnotify_open(f);
                        fd_install(fd, f);
+                       _trace_do_sys_open(f, flags, mode, fd);

使用以下腳本來(lái)幫助分析啟動(dòng)性能。

  • system/extras/boottime_tools/bootanalyze/bootanalyze.py:負(fù)責(zé)衡量啟動(dòng)時(shí)間邓尤,并詳細(xì)分析啟動(dòng)過(guò)程中的重要步驟拍鲤。
  • system/extras/boottime_tools/io_analysis/check_file_read.py boot_trace:提供每個(gè)文件的訪問(wèn)信息。
  • system/extras/boottime_tools/io_analysis/check_io_trace_all.py boot_trace:提供系統(tǒng)級(jí)細(xì)分信息汞扎。

優(yōu)化 init.*.rc

Init 是從內(nèi)核到框架建立之前的銜接過(guò)程殿漠,設(shè)備通常會(huì)在不同的 init 階段花費(fèi)幾秒鐘時(shí)間。

并行運(yùn)行任務(wù)

雖然當(dāng)前的 Android init 差不多算是一種單線程進(jìn)程佩捞,但您仍然可以并行執(zhí)行一些任務(wù)绞幌。

  • 在 Shell 腳本服務(wù)中執(zhí)行緩慢命令,然后通過(guò)等待特定屬性一忱,在稍后加入莲蜘。Android 8.0 通過(guò)新的 wait_for_property 命令支持此用例谭确。
  • 識(shí)別 init 中的緩慢操作。系統(tǒng)會(huì)記錄 init 命令 exec/wait_for_prop 或任何所需時(shí)間較長(zhǎng)的操作(在 Android 8.0 中票渠,指所需時(shí)間超過(guò) 50 毫秒的任何命令)逐哈。例如:
init: Command 'wait_for_coldboot_done' action=wait_for_coldboot_done returned 0 took 585.012ms

查看此日志可能會(huì)發(fā)現(xiàn)可以改進(jìn)的機(jī)會(huì)。

  • 啟動(dòng)服務(wù)并及早啟用關(guān)鍵路徑中的外圍設(shè)備问顷。例如昂秃,有些 SOC 需要先啟動(dòng)安全相關(guān)服務(wù),然后再啟動(dòng) SurfaceFlinger杜窄。在 ServiceManager 返回“wait for service”(等待服務(wù))時(shí)查看系統(tǒng)日志 - 這通常表明必須先啟動(dòng)依賴服務(wù)肠骆。
  • 移除 init.*.rc 中所有未使用的服務(wù)和命令。只要是早期階段的 init 中沒(méi)有使用的服務(wù)和命令塞耕,都應(yīng)推遲到啟動(dòng)完成后再使用蚀腿。

:“屬性”服務(wù)是 init 進(jìn)程的一部分,因此扫外,在啟動(dòng)期間調(diào)用 setproperty 可能會(huì)導(dǎo)致較長(zhǎng)時(shí)間的延遲(如果 init 忙于執(zhí)行內(nèi)置命令)莉钙。

使用調(diào)度程序調(diào)整

使用調(diào)度程序調(diào)整,以便及早啟動(dòng)設(shè)備筛谚。以下是取自 Google Pixel 的示例:

on init
    # update cpusets now that processors are up
    write /dev/cpuset/top-app/cpus 0-3
    write /dev/cpuset/foreground/cpus 0-3
    write /dev/cpuset/foreground/boost/cpus 0-3
    write /dev/cpuset/background/cpus 0-3
    write /dev/cpuset/system-background/cpus 0-3
    # set default schedTune value for foreground/top-app (only affects EAS)
    write /dev/stune/foreground/schedtune.prefer_idle 1
    write /dev/stune/top-app/schedtune.boost 10
    write /dev/stune/top-app/schedtune.prefer_idle 1

部分服務(wù)在啟動(dòng)過(guò)程中可能需要進(jìn)行優(yōu)先級(jí)提升磁玉。例如:

init.zygote64.rc:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
...

及早啟動(dòng) zygote

采用文件級(jí)加密的設(shè)備可以在 zygote-start 觸發(fā)器的早期階段啟動(dòng) zygote(默認(rèn)情況下,zygote 會(huì)在 main 類中啟動(dòng)驾讲,比 zygote-start 晚得多)蜀涨。這樣做時(shí),請(qǐng)確保允許 zygote 在所有 CPU 中運(yùn)行(因?yàn)殄e(cuò)誤的 cpuset 設(shè)置可能會(huì)強(qiáng)制 zygote 在特定 CPU 中運(yùn)行)蝎毡。

停用節(jié)電設(shè)置

在設(shè)備啟動(dòng)期間厚柳,可以停用 UFS 和/或 CPU 調(diào)節(jié)器等組件的節(jié)電設(shè)置。

請(qǐng)注意:為了提高效率沐兵,應(yīng)在充電器模式下啟用節(jié)電設(shè)置别垮。

on init
    # Disable UFS powersaving
    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 0
    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 0
    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 0
    write /sys/module/lpm_levels/parameters/sleep_disabled Y
on property:sys.boot_completed=1
    # Enable UFS powersaving
    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1
    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1
    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1
    write /sys/module/lpm_levels/parameters/sleep_disabled N
on charger
    # Enable UFS powersaving
    write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1
    write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1
    write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1
    write /sys/class/typec/port0/port_type sink
    write /sys/module/lpm_levels/parameters/sleep_disabled N

推遲非關(guān)鍵初始化

非關(guān)鍵初始化(如 ZRAM)可以推遲到 boot_complete。

on property:sys.boot_completed=1
   # Enable ZRAM on boot_complete
   swapon_all /vendor/etc/fstab.${ro.hardware}

優(yōu)化啟動(dòng)動(dòng)畫(huà)

請(qǐng)按照以下提示來(lái)優(yōu)化啟動(dòng)動(dòng)畫(huà)扎谎。

配置為及早啟動(dòng)

Android 8.0 支持在裝載用戶數(shù)據(jù)分區(qū)之前碳想,及早啟動(dòng)動(dòng)畫(huà)。然而毁靶,即使 Android 8.0 中使用了新的 ext4 工具鏈胧奔,系統(tǒng)也會(huì)出于安全原因定期觸發(fā) fsck,導(dǎo)致啟動(dòng) bootanimation 服務(wù)時(shí)出現(xiàn)延遲预吆。

為了使 bootanimation 及早啟動(dòng)龙填,請(qǐng)將 fstab 裝載分為以下兩個(gè)階段:

  • 在早期階段,僅裝載不需要運(yùn)行檢查的分區(qū)(例如 system/vendor/),然后啟動(dòng)啟動(dòng)動(dòng)畫(huà)服務(wù)及其依賴項(xiàng)(例如 servicemanager 和 surfaceflinger)岩遗。
  • 在第二個(gè)階段扇商,裝載需要運(yùn)行檢查的分區(qū)(例如 data/)。

啟動(dòng)動(dòng)畫(huà)將會(huì)更快速地啟動(dòng)(且啟動(dòng)時(shí)間恒定)宿礁,不受 fsck 影響案铺。

干凈利落地結(jié)束

在收到退出信號(hào)后,bootanimation 會(huì)播放最后一部分梆靖,而這一部分的長(zhǎng)度會(huì)延長(zhǎng)啟動(dòng)時(shí)間控汉。快速啟動(dòng)的系統(tǒng)不需要很長(zhǎng)的動(dòng)畫(huà)返吻,如果啟動(dòng)動(dòng)畫(huà)很長(zhǎng)姑子,在很大程度上就體現(xiàn)不出所做的任何改進(jìn)。我們建議縮短循環(huán)播放和結(jié)尾的時(shí)間思喊。

優(yōu)化 SELinux

請(qǐng)按照以下提示優(yōu)化 SELinux 以縮短啟動(dòng)時(shí)間壁酬。

  • 使用簡(jiǎn)潔的正則表達(dá)式 (regex)次酌。在為 file_contexts 中的 sys/devices 匹配 SELinux 政策時(shí)恨课,格式糟糕的正則表達(dá)式可能會(huì)導(dǎo)致大量開(kāi)銷。例如岳服,正則表達(dá)式 /sys/devices/.*abc.*(/.*)? 錯(cuò)誤地強(qiáng)制掃描包含“abc”的所有 /sys/devices 子目錄剂公,導(dǎo)致 /sys/devices/abc/sys/devices/xyz/abc 都成為匹配項(xiàng)。如果將此正則表達(dá)式修正為 /sys/devices/[^/]*abc[^/]*(/.*)? 吊宋,則只有 /sys/devices/abc 會(huì)成為匹配項(xiàng)纲辽。
  • **將標(biāo)簽移動(dòng)到 **genfscon。這一現(xiàn)有的 SELinux 功能會(huì)將文件匹配前綴傳遞到 SELinux 二進(jìn)制文件的內(nèi)核中璃搜,而內(nèi)核會(huì)將這些前綴應(yīng)用于內(nèi)核生成的文件系統(tǒng)拖吼。這也有助于修復(fù)錯(cuò)誤標(biāo)記的內(nèi)核創(chuàng)建的文件,從而防止用戶空間進(jìn)程之間可能出現(xiàn)的爭(zhēng)用情況(試圖在重新標(biāo)記之前訪問(wèn)這些文件)这吻。

工具和方法

請(qǐng)使用以下工具來(lái)幫助您收集用于優(yōu)化目標(biāo)的數(shù)據(jù)吊档。

bootchart

bootchart 可為整個(gè)系統(tǒng)提供所有進(jìn)程的 CPU 和 I/O 負(fù)載細(xì)分。該工具不需要重建系統(tǒng)映像唾糯,可以用作進(jìn)入 systrace 之前的快速健全性檢查怠硼。

要啟用 bootchart,請(qǐng)運(yùn)行以下命令:

$ adb shell 'touch /data/bootchart/enabled'
$ adb reboot

在設(shè)備啟動(dòng)后移怯,獲取啟動(dòng)圖表:

$ ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh

完成后香璃,請(qǐng)刪除 /data/bootchart/enabled 以防止每次都收集日期數(shù)據(jù)。

systrace

systrace 允許在啟動(dòng)期間收集內(nèi)核和 Android 跟蹤記錄舟误。 systrace 的可視化可以幫助分析啟動(dòng)過(guò)程中的具體問(wèn)題葡秒。(不過(guò),要查看整個(gè)啟動(dòng)過(guò)程中的平均數(shù)量或累計(jì)數(shù)量,直接查看內(nèi)核跟蹤記錄更為方便)同云。

要在啟動(dòng)過(guò)程中啟用 systrace糖权,請(qǐng)執(zhí)行以下操作:

  • frameworks/native/atrace/atrace.rc 中,將
write /sys/kernel/debug/tracing/tracing_on 0
更改為:
#write /sys/kernel/debug/tracing/tracing_on 0

這將啟用跟蹤功能(默認(rèn)處于停用狀態(tài))炸站。

  • device.mk 文件中星澳,添加下面這行內(nèi)容:
PRODUCT_PROPERTY_OVERRIDES +=    debug.atrace.tags.enableflags=802922
  • 在設(shè)備 BoardConfig.mk 文件中,添加以下內(nèi)容:
BOARD_KERNEL_CMDLINE := ... trace_buf_size=64M trace_event=sched_wakeup,sched_switch,sched_blocked_reason,sched_cpu_hotplug

要獲得詳細(xì)的 I/O 分析旱易,還需要添加塊和 ext4禁偎。

  • 在設(shè)備專用的 init.rc 文件中,進(jìn)行以下更改:
    • on property:sys.boot_completed=1(這會(huì)在啟動(dòng)完成后停止跟蹤)
    • write /d/tracing/tracing_on 0
    • write /d/tracing/events/ext4/enable 0
    • write /d/tracing/events/block/enable 0

在設(shè)備啟動(dòng)后阀坏,獲取跟蹤記錄:

$ adb root && adb shell "cat /d/tracing/trace" < boot_trace
./external/chromium-trace/catapult/tracing/bin/trace2html boot_trace --output boot_trace.html

注意:Chrome 無(wú)法處理過(guò)大的文件如暖。請(qǐng)考慮使用 tailheadgrep 分割 boot_trace 文件忌堂,以獲得必要的部分盒至。由于事件過(guò)多,I/O 分析通常需要直接分析獲取的 boot_trace士修。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枷遂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子棋嘲,更是在濱河造成了極大的恐慌酒唉,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沸移,死亡現(xiàn)場(chǎng)離奇詭異痪伦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)雹锣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)网沾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蕊爵,你說(shuō)我怎么就攤上這事辉哥。” “怎么了在辆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵证薇,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我匆篓,道長(zhǎng)浑度,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任鸦概,我火速辦了婚禮箩张,結(jié)果婚禮上甩骏,老公的妹妹穿的比我還像新娘。我一直安慰自己先慷,他們只是感情好饮笛,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著论熙,像睡著了一般福青。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脓诡,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天无午,我揣著相機(jī)與錄音,去河邊找鬼祝谚。 笑死宪迟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的交惯。 我是一名探鬼主播次泽,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼席爽!你這毒婦竟也來(lái)了意荤?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拳昌,失蹤者是張志新(化名)和其女友劉穎袭异,沒(méi)想到半個(gè)月后钠龙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體炬藤,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年碴里,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沈矿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咬腋,死狀恐怖羹膳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情根竿,我是刑警寧澤陵像,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站寇壳,受9級(jí)特大地震影響醒颖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜壳炎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一泞歉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦腰耙、人聲如沸榛丢。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晰赞。三九已至,卻和暖如春选侨,著一層夾襖步出監(jiān)牢的瞬間宾肺,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工侵俗, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锨用,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓隘谣,卻偏偏與公主長(zhǎng)得像增拥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寻歧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容