ARM(Colibri imx6) Linux 啓動優化詳解【轉】

轉自:https://blog.csdn.net/qq_27149449/article/details/109329017

Linux 啓動優化
Uboot 優化
Kernel 優化
User space 優化
開機啓動應用程序
摘要:

以下優化過程使用到的工具和參考資料下載
Uboot 優化
1. 顯示整個系統的運行時間:

sudo grabserial -d /dev/ttyUSB0 -t

2. 通過在Uboot命令行中:

setenv bootdelay 0
saveenv

3. 註釋掉 include/configs/colibri_imx6.h 部分功能:

移除一些功能有助於減少分配時間和初始化這些功能的時間。例如移除USB Client和DFU功能 uboot size 從 364k => 348k , 啓動時間縮短

4. 減少串口的數據輸出

5. 配置和編譯uboot:

make colibri_imx6_defconfig
make

Kernel 優化
1. 顯示內核啓動的運行時間:

sudo grabserial -d /dev/ttyUSB0 -t -m "^Starting kernel*" -q "^\[ *[]0-9.]* Freeing unused kernel memory.*"
1
2. 指定日誌的級別 printk(),減少信息的輸出等待時間(內核參數 quiet(靜默模式)同時添加環境變量 initcall_debug 與 printk.time 爲 bootgraph.pl 圖形化分析做準備):

setenv defargs 'enable_wait_mode=off galcore.contiguousSize=50331648 initcall_debug printk.time=1 quiet'
saveenv
1
2
然而,這也將屏蔽我們測試啓動時間的字符信息(“Freeing unused kernel memory”)。最簡單的方法輸出這些信息是利用日誌級別輸出特定的信息。在’mm/page_alloc.c’中搜索“Freeing %s memory”。我將使用‘pr_info => pr_alert’( 將系統的級別 6 變成級別 1 ,控制檯只輸出比系統級別小的數 )( 爲printk定義的宏,打印日誌等級,沒有指定的日誌級別默認爲 4 )輸出信息 。

3. make menuconfig 移除功能,減小內核尺寸:
裁剪前:
裁剪後:


'dmesg’命令設備故障的診斷非常重要。 在‘dmesg’命令的幫助下進行硬件的連接或斷開連接操作時,我們可以看到硬件的檢測或者斷開連接的信息。'dmesg’常常配合管道符 | 使用。 如: dmesg | more 、dmesg | less 、 dmesg | grep sda 、 dmesg | grep -i usb dmesg | grep -i dma ……


內核啓動時各個功能所消耗的時間,可通過Linux源碼中 scripts/bootgraph.pl腳本,將啓動日誌進行圖形化分析。
同時確保 內核配置開啓下面選項,Toradex 默認的配置已經開啓:

root@colibri-imx6:~# zcat /proc/config.gz |grep CONFIG_PRINTK_TIME
CONFIG_PRINTK_TIME=y
root@colibri-imx6:~# zcat /proc/config.gz |grep CONFIG_KALLSYMS
CONFIG_KALLSYMS=y

dmesg > boot.log # 在開發板的Linux中
scp boot.log [email protected]:/home/zhousijie # 拷貝到上位機

cat boot.log | perl scripts/bootgraph.pl > kernel.svg #上位機中
firefox/google-chrome kernel.svg #顯示圖形化的啓動時間佔比

4. 配置和編譯kernel:

make colibri_imx6_defconfig
make -j3 zImage LOADADDR=10008000
1
2

User space 優化
># 屏蔽掉所有的內核printk打印,那麼我只需要把第一個數值調到最小值1或者0。
echo 1 4 1 7 > /proc/sys/kernel/printk
echo 0 4 0 7 > /proc/sys/kernel/printk
1
2
3
systemd 和 system V 的主要區別:

systemd :在多核系統中,並行啓動,但依賴關係複雜,優化困難
system v:串行啓動,按順序啓動,便於優化。

  根據實際應用,一個嵌入式系統可能是相對靜態的,因此,並不需要Systemd的動態功能。此外,Systemd並不是一個很模塊化的系統,各個模塊之間由相互依賴關係,這使得精簡Systemd變得困難。
=> 嵌入式系統用system v優化。 (判斷初始化系統 : stat /proc/1/exe)


1. 使用Systemd(主流)系統初始化 init :

systemd 的最大特點有兩個: (systemctl命令格式)

令人驚奇的激進的併發啓動能力,極大地提高了系統啓動速度;
用 CGroup 統計跟蹤子進程,乾淨可靠。
1. 我們使用“Freeing unused kernel memory”作爲測量基準時間,測量第一個 init 進程到用戶登錄所用的時間
sudo grabserial -d /dev/ttyUSB0 -t -m "^\[ *[]0-9.]* Freeing unused kernel memory.*"
init總是Linux的1號進程,是一切進程的父進程。
除了系統初始化,init還負責重啓、關機、單用戶恢復模式。inittab把條目分到不同運行級別。

2. systemctl工具可以查看所有的啓動項目
systemctl status
Systemd提供了systemd-analyze工具,當使用“blame”時,能夠打印出各個服務以及其啓動的時間。這個可以發現最消耗啓動時間的服務。
但是,其中的值可能具有迷惑性,因爲測量的時間是實際流逝的時間。服務有可能處於睡眠狀態,這時的CPU其實在處理其他任務。
所以在列表頂部的服務不一定是最耗時的,特別是在單核系統上。默認的BSP中並沒有包含 systemd-analyze,可以通過下面的命令,在線安裝。
opkg update
opkg install systemd-analyze

3. systemd-analyze plot也可以用圖形的形式輸出啓動項的情況
systemd-analyze plot > systemd.svg
firefox systemd.svg

啓動服務可以使用disable命令來關閉。有些服務(特別是Systemd自身提供的)可能需要掩碼才能關閉它們。另外有一些可能是系統運行所需的。因此,在關閉服務時需要特別小心,而且一次只能處理一個。

Toradex的BSP中,採用ConnMan作爲網絡管理工具,可以很靈活的管理無線網絡連接。 但ConnMan的啓動會消耗較多的時間。
對於不使用網絡或僅用有線網絡的情況,/etc/systemd/network/wired.network配置可以有效降低啓動時間。
systemctl disable connman.service

/etc/systemd/network/wired.network
--------------------------------------
[Match]
Name=eth0

[Network]
DHCP=ipv4
--------------------------------------

在不需要記錄系統日誌的應用中,將日誌存儲功能禁用後,也可以在一定程度上縮減啓動時間。
/etc/systemd/journald.conf
--------------------------------------
[Journal]
Storage=none
#Compress=yes
--------------------------------------

內核參數中的quiet,同樣也適用於Systemd。這個有助於Systemd的啓動時間。

2. system V 系統初始化 init ,利用搭建好的 Openembedded 架構:

在很長一段時間內,Linux 也使用 SysV 作爲標準的 init 系統。由於基於腳本的系統,這是模塊化的,並且可以相對容易地精簡系統。
特別是對相對靜態的系統,並不需要 Systemd 的設備激活和 socket 激活。此時,SysV可以是很好的選擇。
Toradex 的 Linux BSP 基於 OpenEmbedded 框架發佈,用戶可以很方便的配置 SysV。

重新編譯使用 SysV 的鏡像
--------------------------------------
toradex@tdx-lab-linux:~/Toradex/oe-core/v2.5/oe-core/build$ bitbake console-trdx-image
--------------------------------------

在使用上面的鏡像更新目標板後,在 Linux 執行
--------------------------------------
root@colibri-imx6:~# /usr/sbin/resize.sh
--------------------------------------

如果使用的是 Colibri I.MX6D 512MB , 在 U-boot 中執行
--------------------------------------
Colibri iMX6 # patch_ddr_size
--------------------------------------

在使用 SysV 的系統上,同樣也可以將一些不需要的啓動項刪除。
--------------------------------------
root@colibri-imx6:~#update-rc.d -f bootlogd remove
root@colibri-imx6:~#update-rc.d -f mountall.sh remove
root@colibri-imx6:~#update-rc.d -f networking remove
--------------------------------------

按照上述的優化,User space 啓動到Login 的時間爲 ~1.1 秒。
--------------------------------------
[1.594064 0.371247] [ 0.661430] Freeing unused kernel memory: 280K (805f6000 - 8063c000)
[0.057864 0.057864] INIT: version 2.88 booting
……
[1.098062 0.000060] colibri-imx6 login:
--------------------------------------

在 /etc/init.d 建立啓動腳本加載應用
--------------------------------------
root@colibri-imx6:vi /etc/init.d/drawing.sh
### BEGIN INIT INFO
# Provides: toradex
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: draw rectangles on fb0
### END INIT INFO
/home/root/rectangles &
root@colibri-imx6:chmod a+x drawing.sh
root@colibri-imx6:update-rc.d drawing.sh defaults
--------------------------------------

到此,使用上述方法,應用程序能在 2.55 秒時間內啓動。
--------------------------------------
ban@LinuxDev:~/software/grabserial-1.8.1$ sudo ./grabserial -d /dev/ttyUSB0 -t
[0.000002 0.000002]
[0.162820 0.162818]
[0.162917 0.000097] U-Boot 2015.04 (Apr 14 2016 - 10:09:25)
……
[0.690563 0.001000] Starting kernel ...
……
[2.633291 0.000076] colibri-imx6 login:

開機啓動應用程序
通過systemd啓動

更快顯示圖形界面步驟:

a.將serialtcp放入/sbin目錄下

b. uboot中輸入:setenv defargs $defargs init=/sbin/serialtcp
        saveenv
[進入內核後,儘管很快顯示圖形界面,但部分接口沒完成初始化,導致上述應用可能加載失敗,而該方案對環境變量的設置非常有用]
————————————————
版權聲明:本文爲CSDN博主「end_宿命」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_27149449/article/details/109329017

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章