歡迎光臨
每天分享高質量文章

讓 Linux 啟動更快 | Linux 中國

進行 Linux 內核與韌體開發的時候,往往需要多次的重啟,會浪費大把的時間。

— Stewart Smith

 

在所有我擁有或使用過的電腦中,啟動最快的那台是 20 世紀 80 年代的電腦。在你把手從電源鍵移到鍵盤上的時候,BASIC 解釋器已經在等待你輸入命令了。對於現代的電腦,啟動時間從筆記本電腦的 15 秒到小型家庭服務器的數分鐘不等。為什麼它們的啟動時間有差別?

那台直接啟動到 BASIC 命令列提示符的 20 世紀 80 年代微電腦,有著一顆非常簡單的 CPU,它在通電的時候就立即開始從一個記憶體地址中獲取和執行指令。因為這些系統的 BASIC 在 ROM 裡面,基本不需要載入的時間——你很快就進到 BASIC 命令提示符中了。同時代更加複雜的系統,比如 IBM PC 或 Macintosh,需要一段可觀的時間來啟動(大約 30 秒),儘管這主要是因為需要從軟盤上讀取操作系統的緣故。在可以加載操作系統之前,只有很小一部分時間是花費在韌體上的。

現代服務器往往在從磁盤上讀取操作系統之前,在韌體上花費了數分鐘而不是數秒。這主要是因為現代系統日益增加的複雜性。CPU 不再能夠只是運行起來就開始全速執行指令,我們已經習慣於 CPU 頻率變化、節省能源的待機狀態以及 CPU 多核。實際上,在現代 CPU 內部有數量驚人的更簡單的處理器,它們協助主 CPU 核心啟動並提供運行時服務,比如在過熱的時候壓制頻率。在絕大多數 CPU 架構中,在你的 CPU 內的這些核心上運行的代碼都以不透明的二進制 blob 形式提供。

在 OpenPOWER 系統上,所有運行在 CPU 內部每個核心的指令都是開源的。在有 OpenBMC[1](比如 IBM 的 AC922 系統和 Raptor 的 TALOS II 以及 Blackbird 系統)的機器上,這還延伸到了運行在基板管理控制器Baseboard Management Controller上的代碼。這就意味著我們可以一探究竟,到底為什麼從接入電源線到顯示出熟悉的登錄界面花了這麼長時間。

如果你是內核相關團隊的一員,你可能啟動過許多內核。如果你是韌體相關團隊的一員,你可能要啟動許多不同的韌體映像,接著是一個操作系統,來確保你的韌體仍能工作。如果我們可以減少硬體的啟動時間,這些團隊可以更有生產力,並且終端用戶在搭建系統或重啟安裝韌體或系統更新的時候會對此表示感激。

過去的幾年,Linux 發行版的啟動時間已經做了很多改善。現代的初始化系統在處理並行和按需任務上做得很好。在一個現代系統上,一旦內核開始執行,它可以在短短數秒內進入登錄提示符界面。這裡短短的數秒不是優化啟動時間的下手之處,我們要到更早的地方:在我們到達操作系統之前。

在 OpenPOWER 系統上,韌體通過啟動一個儲存在韌體閃存芯片上的 Linux 內核來加載操作系統,它運行一個叫做 Petitboot[2] 的用戶態程式去尋找用戶想要啟動的系統所在磁盤,並通過 kexec[3] 啟動它。有了這些優化,啟動 Petitboot 環境只占了啟動時間的百分之幾,所以我們還得從其他地方尋找優化項。

在 Petitboot 環境啟動前,有一個先導韌體,叫做 Skiboot[4],在它之前有個 Hostboot[5]。在 Hostboot 之前是 Self-Boot Engine[6],一個晶圓切片(die)上的單獨核心,它啟動單個 CPU 核心並執行來自 Level 3 快取的指令。這些組件是我們可以在減少啟動時間上取得進展的主要部分,因為它們花費了啟動的絕大部分時間。或許這些組件中的一部分沒有進行足夠的優化或盡可能做到並行?

另一個研究路徑是重啟時間而不是啟動時間。在重啟的時候,我們真的需要對所有硬體重新初始化嗎?

正如任何現代系統那樣,改善啟動(或重啟)時間的方案已經變成了更多的並行執行、解決遺留問題、(可以認為)作弊的結合體。

赞(0)

分享創造快樂