嵌入式產(chǎn)品中,系統(tǒng)啟動速度是很關鍵的指標,對系統(tǒng)啟動速度的優(yōu)化,通常我們稱之為“ 要對系統(tǒng)啟動速度進行優(yōu)化,首先要知道如何統(tǒng)計系統(tǒng)啟動的時間。 下面介紹幾種統(tǒng)計內(nèi)核啟動耗時的方法,以及對內(nèi)核啟動速度優(yōu)化的幾個方法。 打開kernel配置: 登錄后復制 打開后,每個printk的前面都會顯示時間戳 主要用來測量內(nèi)核啟動過程各個階段的耗時 眾所周知, 在 登錄后復制 開啟后,就能打印每個 內(nèi)核自帶了一個工具用于統(tǒng)計啟動時間: 使用該工具需要打開內(nèi)核配置 系統(tǒng)啟動之后,執(zhí)行命令: 登錄后復制 用瀏覽器查看 這個工具有點類似于 除了內(nèi)核自帶的工具,也有開源的工具可用: bootchart是一個用于linux啟動過程性能分析的開源軟件工具,在系統(tǒng)啟動過程自動收集CPU占用率、進程等信息,并以圖形方式顯示分析結果,可用作指導優(yōu)化系統(tǒng)啟動過程。 最后也會成圖片供做分析,例如: 可以找一個在系統(tǒng)啟動過程中空閑的 通過示波器抓取波形可以得到各階段耗時。 通常該方法被用來測量整個啟動的耗時,或者各階段的耗時,該方法也是用的比較多的。 不同的壓縮格式,解壓速度就不同,通過比較不同壓縮方式的啟動時間和flash占用情況,選擇一種符合實際情況的,以此進行優(yōu)化。 內(nèi)核鏡像可以由 對于 即把加載地址和運行地址設置為不同地址,可以減少耗時。 裁剪內(nèi)核是必要的,如果內(nèi)核鏡像太大,那么解壓內(nèi)核就需要很長時間,所以內(nèi)核要盡量裁剪。 裁剪內(nèi)核,可以減少解壓耗時。初始化內(nèi)容少了,也會減少耗時。 因此裁剪內(nèi)核時,要考慮將不需要的功能都去掉。 如下 登錄后復制 如果沒有 如前面提到, 登錄后復制 根據(jù)打印信息,可以對耗時較多的 如果是多核,可以考慮將 目前內(nèi)核 加入 登錄后復制 只把必須要加進內(nèi)核的才編譯進內(nèi)核,其他的編譯成模塊。 例如將必要的 如果是 一般我們的程序都是放到 這項技術是必須要芯片支持才行,可以看看芯片手冊中對 以上對系統(tǒng)啟動速度的優(yōu)化,歸根結底是提供一些思路、一些方法。 要優(yōu)化啟動速度,通常來說需要對整個系統(tǒng)的啟動有比較深入的了解。 優(yōu)化無止境,需要根據(jù)目標來進行優(yōu)化,綜合考慮啟動速度和效果。快啟”。一、啟動耗時統(tǒng)計
printk time
kernel hacking --->
[*] Show timing information on printks
initcall_debug
kernel啟動時會執(zhí)行不同等級的initcall,而每個initcall的耗時也是可以統(tǒng)計的。kernel的cmdline中加入?yún)?shù)initcall_debug=1:initcall_debug=1
setargs_nand=setenv bootargs console=${console} earlyprintk=${earlyprintk} root=${nand_root} initcall_debug=${initcall_debug} init=${init}
initcall函數(shù)調(diào)用及耗時。bootgraph
scripts/bootgraph.plCONFIG_PRINTK_TIME=y,并且在cmdline中加上"initcall_debug=1"dmesg|perl $(kernel_dir)/script/bootgraph.pl > out.svg
out.svg文件,可以看到內(nèi)核啟動過程中各個階段的耗時。perf的火焰圖,可以統(tǒng)計啟動各階段的耗時。bootchart
bootchart。
kernel cmdline。將其中的init修改為“init=/sbin/bootchartd”。bootchartd會從/proc/stat,/proc/diskstat,/proc/[pid]/stat中采集信息,經(jīng)過處理后保存為bootchart.tgz文件pc上通過pybootchartgui.py工具將bootchart.tgz轉換為bootchart.png,方便分析bootchar主要用來測量掛載文件系統(tǒng)到主應用程序啟動過程中的耗時gpio+示波器
GPIO,在適當位置設置GPIO電平。二、內(nèi)核優(yōu)化方法
kernel壓縮方式
kernel有不同的壓縮格式,常見的如gz、xz、lzma等。加載位置
kernel自解壓,也可以由uboot進行解壓。kernel自解壓的情況,如果壓縮過的kernel與解壓后的kernel地址沖突,則會先把自己復制到安全的地方,然后再解壓,防止自我覆蓋。這就需要耗費復制的時間。內(nèi)核裁剪
預設置lpj數(shù)值
LPJ也就是loops_per_jiffy,每次啟動都會計算一次,但如果沒有做修改的話,這個值每次啟動算出來都是一樣的,可以直接提供數(shù)值跳過計算。log所示,有skipped,lpj由timer計算得來,不需要再校準calibrate了。[ 0.019918] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000)
skipped,則可以在cmdline中添加lpj=xxx進行預設initcall優(yōu)化
initcall耗時是可以打印出來的,在cmdline中設置initcall_debug=1,即可打印跟蹤所有內(nèi)核初始化過程中調(diào)用的順序以及耗時。[ 0.021772] initcall sunxi_pinctrl_init+0x0/0x44 returned 0 after 9765 usecs
[ 0.067694] initcall param_sysfs_init+0x0/0x198 returned 0 after 29296 usecs
[ 0.070240] initcall genhd_device_init+0x0/0x88 returned 0 after 9765 usecs
[ 0.080405] initcall init_scsi+0x0/0x90 returned 0 after 9765 usecs
[ 0.090384] initcall mmc_init+0x0/0x84 returned 0 after 9765 usecs
initcall進行優(yōu)化。內(nèi)核initcall_module并行
initcall有很多等級,但比較耗時的是module。module_initcall并行執(zhí)行來節(jié)省時間。do_initcalls是一個一個按照順序來執(zhí)行,可以修改成新建內(nèi)核線程來執(zhí)行減少pty/tty個數(shù)
initcall打印之后,發(fā)現(xiàn)pty/tty init耗時很多,可減少個數(shù)來縮短init時間。initcall pty_init+0x0/0x3c4 returned 0 after 239627 usecs
initcall chr_dev_init+0x0/0xdc returned 0 after 36581 usecs
內(nèi)核module
clock、tty、pinctrl等編譯進內(nèi)核三、其他優(yōu)化
uboot
RISC-V架構,可以考慮去掉uboot。XIP
xip:eXecute In Place。即芯片內(nèi)執(zhí)行,是指CPU直接從存儲器中讀取程序代碼執(zhí)行,而不用再讀到內(nèi)存中。flash中,系統(tǒng)啟動時,把程序從flash拷貝到ddr中執(zhí)行,而xip技術則不需要拷貝程序到ddr,所以速度會很快。SPI的描述是否支持XIP功能。四、總結
以上就是很有用的速度優(yōu)化:讓系統(tǒng)啟動速度更快的詳細內(nèi)容,更多請關注www.92cms.cn其它相關文章!






