怎樣在1秒內啟動Linux
儘可能快的啟動系統,對於自動化裝置是非常重要的。系統能夠在使用者無法感知的時間內啟動,也就意味著在不需要工作時,可以完全切斷電源,而不是掛起進入休眠狀態。本文基於Atmel AT91系列片上系統和NAND快閃記憶體,經過一系列的優化,將Linux系統啟動時間,從最初的11秒,降低到最終的656毫秒。
背景知識
系統從上電到完全啟動,需要經過許多過程。一個簡化的啟動流程大概包含:
- 硬體重置
- 啟動載入程式(bootloader)
- 作業系統初始化
- 應用程式執行
其中硬體非常關鍵,但是硬體一般難以更改。後續的優化,主要針對載入程式、Linux核心和應用程式展開。
載入程式優化
載入程式主要完成對CPU的基礎設定,處理ARM標記(ATAGS,ARM TAGS)或裝置樹(device trees),切換儲存管理單元(MMU,Memory Management Unit)等工作。
對於U-Boot,常用的優化方式有:
- 刪除不不要的功能:如網路載入等,如果不需要,那麼直接移除這些程式碼吧;
-
關閉不需要的功能
- 關閉核心映象驗證
- 關閉載入程式輸出
- 關閉啟動延遲
- 將通用功能的載入程式修改成一個優化後的初始程式載入器(Initial Program Loader,IPL),對於U-Boot,可以通過SPL(Second Program Loader,第二階段程式載入器)來實現。
核心優化
Linux核心被設計的非常靈活,可以針對需要的功能做各種配置優化。因此,優化核心對於系統啟動速度是至關重要的。
首先,移除一切不要的驅動,儘可能的減少核心載入的內容,能夠大大縮短系統啟動時間。其次,還有很多核心選擇可能需要進一步嘗試,比如核心壓縮方式,對於嵌入式系統來說,LZO壓縮方式,通常會是一個不錯的選擇。最後,還可以通過定製一些啟動引數,達到加快啟動的目的。例如可以通過“lpj=”引數,預設每個迴圈需要的節拍數(loops per jiffy,lpj)的值,避免系統在啟動時自動推算。這樣在基於ARMv5的系統中,可以節省100ms以上的時間。
對於核心啟動的優化,可以通過bootgraph.pl指令碼(位於核心原始碼的script/bootgraph.pl)來繪製核心啟動耗時圖表,用以分析啟動最耗時的地方。這個指令碼使用非常簡單,直接將dmesg的輸出作為其輸入,即可生成svg圖表:
dmesg | perl scripts/bootgraph.pl > output.svg
生成的圖表如下圖,
圖中每一個色段表示一個功能的初始化耗時。可以簡單的關閉不需要的功能,或者針對功能進行特定的優化。
除了核心本身之外,核心所在的檔案系統也對系統啟動有著非常大的影響。對於使用快閃記憶體晶片作為儲存的系統來說,UbiFS是一個很好的選擇。它能夠容忍意外斷電,有著出色的掛載速度,以確保系統快速啟動。
應用程式優化
核心完成系統啟動之後,接來下就是執行應用程式。對於應用程式的優化,主要有兩部分,一部分是由應用程式來接管啟動的INIT程式,另一部分是優化應用程式的連結方式。
標準的SystemV INIT程式,需要執行一堆啟動指令碼。對於嵌入式系統來說,大部分是沒有意義的。另一部分(比如掛載檔案系統),可以由應用程式自己來實現。然後,可以在核心啟動引數中通過“init=”引數,將INIT程式直接指定為應用程式。
應用依賴的動態連結庫,會按照以下順序查詢:
- LD_PRELOAD環境變數指定的路徑(一般對應檔案/etc/ld.so.preload);
- ELF .dynamic節中DT_RPATH入口指定的路徑,若DT_RUNPATH入口不存在的話;
- 環境變數LD_LIBRARY_PATH指定的路徑,但如果可執行檔案有setuid/setgid許可權,則忽略這個路徑;編譯時指定--library-path會覆蓋這個路徑;
- ELF .dynamic節中DT_RUNPATH入口指定的路徑;
- ldconfig快取中的路徑(一般對應/etc/ld.so.cache檔案),若編譯時使用了-z nodeflib的連結選項,則此步跳過;
- /lib,然後/usr/lib路徑 ,若使用了-z nodeflib連結選項,則此步亦跳過;
因此,儘可能的將應用程式依賴的動態連結庫放到優先查詢的路徑,可以加快連結速度。對於交叉編譯環境特別需要注意,主機上的動態連結庫位置和目標系統上的位置可能不一致,這會增加應用程式執行時動態連結庫的載入時間。
總結
基於上面提到的三個優化點,可以將系統的啟動時間,從最初的11s降低到656ms(資料參考Jan Altenberg在都柏林舉行的嵌入式Linux會議上的演講稿)。從硬體到載入程式再到核心最後到應用程式,每個啟動步驟都有自己可優化的地方,經過一些簡單的優化,就可以減少系統的啟動時間。
相關文章
- 怎樣在 1 秒內啟動 LinuxLinux
- 在Windows中怎樣尋找自啟動程式(轉)Windows
- 怎樣在 PhpStorm 啟用 Laravel Resources 的自動完成PHPORMLaravel
- a元件在text元件內不能動態修改樣式,怎麼破?元件
- 怎樣在Mac上安排自動啟動或關閉,技巧來啦~Mac
- 在linux中怎麼讓程式開機自動啟動?Linux
- 怎樣在啟動OS X時禁止載入指定分割槽
- 怎樣可以在linux平臺上開啟oracle erp form?LinuxOracleORM
- excel在win10上怎樣快速啟動_excel在win10上設定快速啟動的方法ExcelWin10
- 怎樣在同一系統中啟動多個TOMCAT薦Tomcat
- 在Linux下怎樣讓top命令啟動之後就按記憶體使用排序(或CPU使用排序)?Linux記憶體排序
- 怎樣在 Ubuntu Linux 上安裝 MySQLUbuntuLinuxMySql
- tomcat在linux下自啟動TomcatLinux
- 在Windows下啟動Linux(轉)WindowsLinux
- linux 啟動jar包:在 Linux 上啟動 Java jar 包的方法LinuxJARJava
- 怎樣啟動停止重啟MySQL資料庫伺服器MySql資料庫伺服器
- 在linux下啟動tomcat命令LinuxTomcat
- Linux上oracle怎麼啟動OEMLinuxOracle
- systemctl 命令在 Linux 中啟動、停止和重新啟動服務Linux
- 在 21 世紀該怎樣編譯 Linux 核心編譯Linux
- 在Linux中,目錄結構是怎樣的?Linux
- 在Linux系統中讓ORACLE自動啟動LinuxOracle
- 怎樣開啟Terminal(命令)自動補全功能?
- 在linux環境下啟動時開啟numlock(轉)Linux
- 在Linux中,如何啟動、停止或重啟服務?Linux
- Linux怎麼知道服務是否啟動?Linux
- 在Linux下製作Linux&windows啟動盤LinuxWindows
- 在 Linux 中怎樣移除(刪除)符號連結Linux符號
- 怎樣在 Linux Mint 中建立和切換工作區Linux
- BIM 在國內的前景怎麼樣?在國外發展到了什麼程度?
- 怎樣啟動一個程式而不顯示它 (轉)
- 怎樣讓Windows XP啟動密碼更加強大(轉)Windows密碼
- 在linux中無法啟動mysqld 服務LinuxMySql
- linux mysql無法啟動怎麼解決?LinuxMySql
- linux下怎麼啟動oracle資料庫LinuxOracle資料庫
- 在Linux中,如何規劃⼀臺 Linux 主機,步驟是怎樣?Linux
- 【LINUX】怎樣配置 NFSv4 with kerberos 自動認證LinuxNFSROS
- Linux Mint 21.2和LMDE 6將在一個月內相繼推出 支援安全啟動功能Linux