轉自: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 zhousijie@192.168.2.1:/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