探索 Linux bootloader 的佳作

790阅读 0评论2013-03-04 dlwcn
分类:嵌入式

探索 Linux bootloader 的目的才不是為了多重開機或讓自己陷於一堆無趣的指令操作,重點在於:

最後一項看似唐突,事實上在專案開發或研究上,是我們必須面對的議題。以手持式裝置來說,"anti-hacking" 成為相當重要的考量,但採用開放系統又是必經之路,該如何立足於較有利之處呢?自 2003 年起,許多 bootloader 逐漸應用密碼學的範疇技術,整個 kernel image 乃至 partition 都是經過特定加密處理,如何在兼顧實用性與安全性,bootloader 就被賦予重大的使命。又,像 [SoG] 學長以知名的 bootloader [] 為基礎,發展了一套 RTOS,就是創造了新價值,特別在 time-critical 的系統,更能彰顯。

之前的 blog [Micromonitor 簡介] 提過服務於 Lucent 的 [Ed Sutter] 詳盡介紹 Firmware 相關技術與指導如何使用並移植 MicroMonitor 的大作,不過如果要更深入探索,一定要拜讀 Christopher Hallinan 的大作《Embedded Linux Primer》裡面的第七章〈Bootloaders〉。Christopher Hallinan 大名鼎鼎,我想也不需多加介紹,MontaVista software 有太多創作是出自此大師之手,同時,也感謝 Christopher Hallinan 願意將〈Chapter 7: Bootloaders〉開放下載,請參考以下資訊: 該章節包含五個子主題: 這讓我想到面試新人時,常問及一個問題: 這個問題算是一種 pattern,因為還可套用在特定的硬體架構,比方說 ARM、MIPS,或者 PowerPC 等等,端看應試者的技術背景。x86 bootloader 是個特例,而 Linux bootloader 也可說是一種典型設計下的產物,事實上能發揮的空間很大,比方說 "no-kernel design" 或 exokernel 思維下,bootloader 的身份就有極大的轉變,bootloader 與 kernel 共存是可能的,而且也是相當務實的考量 (想像 watchdog 一類的應用)。不過,這個問題的答案到底是什麼呢?最重要的當然是「適當」去初始化硬體裝置並給予「適當」的狀態,其中需要考量的重點就像是 Flash memory,光是其排列的方式就會引發許多細部的問題。

許多入門書籍總是以一系列的方塊圖,悄悄帶過 bootloader 的原理,好似 kernel 載入前那段「美好時光」中發生的變化、當試著以機械語文與電腦硬體對話時,只是哲學性地闡述海德格的名言:「語言乃存在之家園」,不,黑格爾告訴我們:「存在必合理」。Christopher Hallinan 一針見血指出 boot loader 設計上面臨的挑戰: C Programming Language 設計的首要目標就是撰寫作業系統,但有意思的是,即使簡單的 C 程式如 "Hello World" 者,都涉及許多軟體與硬體的交互作用 (微觀角度),對於程式開發者而言,RAM 顧名思義就是「隨機存取」的「記憶體」(按:此說法有爭議,事實上,多數的記憶裝置的確在某些程度上都算「隨機」性「存取」,不過這裡不細究),想當然爾可用 C 語言最美妙與強大的 pointer 進行操作,而這也涉及 C Runtime stack 的微妙變化,不過,這些對 bootloader 來說,都是艱鉅的挑戰,因為 bootloader 得挑起初始化與基本配置的責任,更明確來說,開機初期根本沒有 stack 的概念與具體呈現。

問題才要開始,"7.2.3 Image Complexity" 指出許多經典的議題,C compiler & linker 怎麼去安排機械碼與目的輸出,一般而言,程式設計師不需要太花時間思索,不過對 bootloader 的設計可全然不是這麼一回事。這夢魘的開端就是 C runtime stack,於是作者指出: 所以 "execution context" 的建立成為如此以 C 語言為主體的作業系統或環境之首要任務 (對許多系統是如此,不過像是 Forth 一類的系統則巧妙的以自身的 stack 處理)。再者,自 Flash memory 到 RAM 作重新定址的動作相當重要,如此低階的動作與 image layout 息息相關。所以說,困難處就在於需要建立一套與處理器啟動程序相容的 startup code,而且開頭要符合硬體架構規範之位址,書中提到一個典型的個案: 為了明確處理這個問題,作者引導我們接觸眾多 ld (Linker) script,接下來繼續探討 "execution context" 的細節。思考之前提到 "Hello World" 的例子,我們面臨的挑戰如作者指出: 以剛剛提到 PowerPC 405GP 硬體來說,實際的狀況就是: 我們可發現,在 PowerPC 硬體架構來說,我們發現 bootloader 竟然須顧及如此低階的行為,才得以讓後續的作業環境得以維護 "execution context"。然而,組合語言並非萬靈丹,如何兼顧快速開發與多種平台支援,又是新的挑戰,為此,[] 於是生焉。不過這裡就不作導讀,因為 Christopher Hallinan 所作深入的探討實在太精彩,不容我等愚人置喙,總之,那是篇值得反覆拜讀與思索的佳文,唯一的缺點就是 PowerPC 對不少開發者 (包含小弟我) 是不熟悉的硬體架構,所以組合語言列表比較沒有感覺。

另外,大陸網友詹榮開三年前在 IBM developerWorks 發表了一篇文章 [嵌入式系統 Boot Loader 技術內幕] 也很值得一看,建議可搭配以上兩篇文章閱讀,其中有許多圖文恰好可互補,又其中一者談 [] ,另一者談 [],真是恰到好處。有了上述的基礎後,再回頭研讀 ARM-Linux hacker - Vincent Sanders - 的經典作品 [],就可得心應手。
上一篇:Linux 实时技术与典型实现分析, 第 1 部分: 介绍
下一篇:面试时最难的25个问题 ————真的太实际了