UEFI技術普及(轉自網絡)



(譯)UEFI 啓動:實際工作原理

本文是我翻譯自國外技術博客的一篇文章,其中講述了 UEFI 的一些基本概念和細節。

本文的原始鏈接位於:https://www.happyassassin.net/2014/01/25/uefi-boot-how-does-that-actually-work-then/

本人的翻譯水平有限,難免多有疏漏。廢話不多說,請看正文:

又到 AdamW 的講課時間了,如果你不想聽我的長篇大論,那麼請出門右拐。

Kamil Paral 說我有寫作癖,知道自己的壞習慣也是件好事。

可能你已經在互聯網上閱讀過有關 UEFI 的大量資料。但是有一些重要事項需要了解:這些資料中的

本文是我翻譯自國外技術博客的一篇文章,其中講述了 UEFI 的一些基本概念和細節。

本文的原始鏈接位於:https://www.happyassassin.net/2014/01/25/uefi-boot-how-does-that-actually-work-then/

本人的翻譯水平有限,難免多有疏漏。廢話不多說,請看正文:

又到 AdamW 的講課時間了,如果你不想聽我的長篇大論,那麼請出門右拐。

Kamil Paral 說我有寫作癖,知道自己的壞習慣也是件好事。

可能你已經在互聯網上閱讀過有關 UEFI 的大量資料。但是有一些重要事項需要了解:這些資料中的 95% 都毫無價值。如果你認爲你已經對 UEFI 有所瞭解,但是如果你的知識來源並不可靠,那麼所掌握的知識就不過是一堆誤解、謬論、一己之見、信口開河和彌天大謊。先把這些都忘了吧。如果想真正瞭解有關 UEFI 的權威知識,不妨訪問 UEFI 規範、mjg59 的博客、其他靠譜一點的文章/權威人士——包括 Rod SmithPeter Jones、Chris Murphy,或者閱讀一些小衆操作系統的文檔,前提是這些操作系統的開發人員確實瞭解 UEFI。

好,準備工作做完了。我主要想討論啓動加載,因爲對於大多數用戶而言,固件在其中扮演着重要角色,同時,不少網站也針對這一過程喋喋不休,由此產生不少誤解。

術語

首先,我們瞭解一些術語。BIOS UEFI 都是計算機的固件類型。BIOS 固件(主要)用於 IBM PC 兼容計算機。UEFI 的通用性更強,可用在非“IBM PC 兼容”系列的計算機上。

不存在“UEFI BIOS”。沒有任何一臺計算機會有“UEFI BIOS”。請不要再說“UEFI BIOS”。BIOS 不是所有 PC 固件的通用術語,它只是 PC 固件的一種特定類型。計算機中包含固件。如果你有一臺 IBM PC 兼容計算機,那麼固件幾乎肯定就是 BIOS 或 UEFI。如果你運行的是 Coreboot,那麼恭喜,你是個例外,引以爲傲吧。

安全啓動 (Secure Boot) 與 UEFI 不是同一個概念。請不要將這些術語混淆使用。安全啓動 (Secure Boot) 實際上是 UEFI 規範的一項可選功能,於 UEFI 規範版本 2.2 引入。我們稍後會詳細討論安全啓動 (Secure Boot) 到底是什麼,但是目前而言,只需要記住它和 UEFI 不同即可。你需要區分安全啓動 (Secure Boot) 和 UEFI 的差異,在任何場合,你都應當瞭解你實際上討論的是其中哪一個。我們首先討論 UEFI,然後我們將把安全啓動 (Secure Boot) 作爲 UEFI 的一項“擴展”來進行討論,因爲這就是安全啓動 (Secure Boot) 的本質。

註釋:UEFI 不是由微軟開發的,也從來不受微軟控制。它的前身和基礎——EFI,是由 Intel 開發和發佈的。UEFI 由 UEFI 論壇進行管理。微軟是 UEFI 論壇的成員之一。Red Hat、Apple、幾乎所有主要 PC 製造商、Intel(顯然)、AMD 和一大批其他主要和次要硬件、軟件和固件公司及組織也都是 UEFI 論壇的成員。UEFI 是一套業已達成廣泛共識的規範,其中當然也包含各種混亂(我們稍後會專門討論其中一部分)。UEFI 並不由任何一家公司獨裁掌控。

參考資料

如果想真正瞭解 UEFI,閱讀 UEFI 規範是個不錯的方法。這件事並不難,也不需要什麼代價。閱讀 UEFI 規範相當枯燥乏味,但是會讓你受益匪淺。你可以從官方 UEFI 網站下載 UEFI 規範。儘管下載 UEFI 規範需要先同意某些條款和條件,但是不會帶來損失。在我撰寫本文時,UEFI 規範的最新版本是 2.4 Errata A(譯者注:現在更新到了 2.4 Errata B),本文所寫內容也基於這一版本。

BIOS 沒有制定相應規範。BIOS 本身就是一項事實標準,從 20 世紀 80 年代開始,BIOS 的工作方式就一成不變。這也是誕生 UEFI 的原因之一。

簡單起見,我們可以把 BIOS 和 UEFI 看成兩種不同的組合。其中一種是 UEFI和 GPT (我們稍後會討論 GPT)產生之前,IBM PC 兼容計算機(以下稱爲 PC)所廣泛採用的組合。大部分人可能對這種組合非常熟悉,對其中的細節瞭如指掌。那麼我們就先來討論在具有 BIOS 固件的 PC 上,啓動是如何工作的。

BIOS 啓動

事實上,BIOS 啓動的工作原理非常非常簡單。在老式 BIOS PC 上,裝有一個或多個磁盤,每個磁盤中包含 MBR。MBR 是另一套事實標準;大體而言,磁盤起始位置以特定格式描述磁盤上的分區,幷包含“啓動裝載程序 (boot loader)”,BIOS 固件知道如何執行這一小段啓動裝載程序代碼。啓動裝載程序的職責是啓動操作系統(現代啓動裝載程序的大小通常超出了 MBR 空間所能容納的範圍,因此必須採用多階段設計,其中 MBR 部分只知道如何從其他位置加載下一階段,我們現在先不着重討論這一過程)。

在啓動系統的過程中,BIOS 固件只能識別系統包含的磁盤。而作爲 BIOS 計算機的擁有者,你可以告訴 BIOS 固件你想從哪個磁盤啓動系統。而固件本身並不知道其他細節,它只會執行在指定磁盤的 MBR 部分所發現的啓動裝載程序,就這麼回事。在執行啓動裝載程序之後,固件本身就不再參與啓動。

在 BIOS 組合中,所有的多重啓動形式都肯定是在固件層上進行處理的。固件層無法真正識別啓動裝載程序或操作系統,甚至連分區都無法識別。固件所能執行的操作只是從磁盤的 MBR 中運行啓動裝載程序。你無法從固件外部配置啓動過程。

UEFI 啓動:背景

好,BIOS 組合的背景知識已經明確了。我們現在來看看 UEFI 計算機上的啓動原理。即使未掌握本文的細節,也請記住這一點:UEFI 與 BIOS 完全不同。UEFI 啓動原理與 BIOS 絕對不同。你不能把 BIOS 啓動的原理直接套用到原生 UEFI 啓動上。你不能把專爲 BIOS 啓動設計的工具應用到原生 UEFI 啓動的系統上。記住,UEFI 組合完全不同。

還需要了解一個重點:許多 UEFI 固件實現了某種 BIOS 兼容模式(有時候稱爲 CSM)。許多 UEFI 固件可以像 BIOS 固件一樣啓動系統,它們可以查找磁盤上的 MBR,然後從 MBR 中執行啓動裝載程序,接着將後續工作完全交給啓動裝載程序。有時候,其他人誤將此功能稱爲“禁用 UEFI”,從語言學角度而言,這種說法是荒謬的。系統固件是無法“禁用”的。這種說法很愚蠢,不要採用這種說法。但是在其他人這麼說的時候,應該瞭解他們真正想表達什麼。他們討論的是通過 UEFI 固件的一項功能,以“BIOS 風格”啓動系統,而不是採用原生 UEFI 方式啓動系統。

我想解釋一下原生 UEFI 啓動。如果你有一臺基於 UEFI 的計算機,其固件具有 BIOS 兼容功能,並且你打算一直使用這項兼容功能,在啓動過程中,你的計算機看起來就是基於 BIOS 的。你只需要像 BIOS 啓動一樣進行所需操作即可。如果你確實有此打算,那麼就不要中途變卦。對於你日常使用的操作系統,強烈建議不要混合使用原生 UEFI 啓動和 BIOS 兼容啓動,尤其不要在同一塊磁盤上混用。這麼做的話,你會痛不欲生。如果你決定混合使用原生 UEFI 啓動和 BIOS 兼容啓動,到時候就別找我哭訴。

爲了理清頭緒,我將假設磁盤採用 GPT,並且包含用於 EFI 的 FAT32 EFI 系統分區 (ESP)。根據你對這些知識的深入程度,你可能發現,在進行原生 UEFI 啓動時,GPT 磁盤和 EFI FAT32 ESP 並不是必要條件。但是 UEFI 規範和 GPT 磁盤以及 EFI FAT32 ESP 的聯繫程度相當密切。在99%的情況下,你要處理的也正是這樣的組合。除非你在使用 Mac(老實說,Mac 混亂不堪)。

編輯說明:以下章節(到缺陷爲止)在 2014 年 1 月 26 日(本文發佈的幾小時後)根據 Peter Jones 的反饋進行了大量修訂。本文可視爲 v2.0 版本。早期版本的寫作方式不夠嚴謹,而且內容可能會產生誤解。

UEFI 原生啓動:實際工作原理——背景

言歸正傳。本節將解釋原生 UEFI 啓動的實際工作原理。如果已掌握一定程度的背景知識,可能更容易深入理解本節內容。

在固件層,UEFI 的基礎架構更豐富,可用於處理系統啓動。UEFI 遠不像BIOS 那麼簡單。與 BIOS 不同,UEFI 確實可以(不同程度上)理解“磁盤分區”、“啓動裝載程序”以及“操作系統”的概念。

你可以稍微看看 BIOS 啓動過程,然後再看看 UEFI 啓動過程,瞭解 UEFI 啓動過程如何採用多種措施來解決特定問題。

在思考啓動過程時,你會發現 BIOS/MBR 查找啓動裝載程序的方法實在不怎麼樣。BIOS/MBR 非常奇葩:位於磁盤起始位置的這一小段空間包含神奇代碼 (magic code),而這段神奇代碼只作用於系統固件和寫入此神奇代碼的工具。這種方法有許多問題。

  • 處理不便——你需要特殊工具來寫入 MBR,如果要查看 MBR 中包含的內容,唯一的方法幾乎就是把 MBR dd 出來,然後進行檢查。
  • 如上所述,MBR 本身不足以容納許多現代啓動裝載程序。這些啓動裝載程序會將自身的一小部分安裝在 MBR 中,而將其他部分安裝到磁盤上的可用空間中。這段可用空間位於常規 MBR 末尾和第一個分區的起始位置之間。這就會造成很大的問題(其實這整個設計就是個大問題,不過無所謂)。對於第一個分區的起始位置,並沒有成文的可靠規定,因此難以確保空間足夠。只有一件事情是肯定的:這段空間不足以容納某些啓動裝載程序的配置。
  • 如果要選擇其他啓動目標(除磁盤以外),這種設計沒有提供任何標準化層或標準化機制,但是用戶希望選擇除磁盤以外的啓動目標。也就是說,他們希望實現多重可啓動對象——通常是操作系統。在 BIOS/MBR 組合中,實現這種目的的唯一方法是由啓動裝載程序進行處理;至於如何實現,並沒有進行獲得廣泛認可的規定。雖然實現的方法非常多,但是它們無法彼此協作,而且也都不是獲得廣泛認可的標準或規定。而在操作系統/操作系統安裝層編寫工具的難度很大,無法乾淨利落地處理多重啓動。因此這種設計非常混亂。
  • 這種設計沒有提供標準方法,讓用戶可以從除磁盤以外的目標進行啓動。本文不會就此問題進行詳細討論,但是請注意,UEFI 啓動的另一優勢爲:它提供了進行啓動(例如,從遠程服務器進行啓動)的標準方法。
  • 固件層以上的其他層無法配置固件的啓動行爲,BIOS 沒有提供相應機制。

可以想象,在 UEFI 設計之初,開發人員思考過這些問題,並最終提出解決方案。UEFI 固件並不僅僅可以識別磁盤,它也知道啓動裝載程序代碼在每個磁盤上所處的位置,而且在固件層,UEFI 的基礎架構更豐富,可用於處理啓動裝載。接下來,我們討論下 UEFI 規範中定義的相關內容。

EFI 可執行文件

UEFI 規範定義了一種可執行文件格式,並要求所有 UEFI 固件能夠執行此格式的代碼。當開發人員爲原生 UEFI 編寫啓動裝載程序時,就必須按照這種格式編寫。這種設計非常簡潔直觀,也無需進一步解釋:對於固件可以執行的代碼,固件規範真正定義了其通用格式,這是件好事。

GPT(GUID 分區表)格式

GUID 分區表格式與 UEFI 規範具有密切聯繫,而且,它並不特別複雜,無需多加解釋。GPT 是 UEFI 規範提供的良好基礎架構之一。GPT 僅僅是分區表的一種標準——磁盤起始位置的信息定義了磁盤所包含的分區。相比 MBR/MS-DOS 分區表,這種分區表對分區的定義要好得多,並且 UEFI 規範要求 UEFI 兼容固件必須能識別 GPT(也要求固件能識別 MBR,以保證向後兼容)。所有這些規範都是相當實用的基礎架構: UEFI 規範正建立某些功能,固件層上的一切都可依靠固件本身來實現這些功能。

EFI 系統分區

在修訂本文時,我才真正思考 EFI 系統分區的概念,讓我有如醍醐灌頂。實際上,“EFI 系統分區”的概念可以解決“奇葩”的 MBR 空間所產生的問題。在磁盤起始位置留出自由空間,用於存放啓動裝載程序代碼,但又不定義其容量,種設計糟糕透頂。這一點在上文已經討論過了。EFI 系統分區是 UEFI 用於解決這種問題的解決方案。1

具體的解決方案如下:我們要求固件層能夠讀取某些特定的文件系統類型。UEFI 規範要求兼容固件必須能讀取 FAT 格式的變種(包括 FAT12、FAT16 和 FAT32)。UEFI 規範實際扮演的角色就是編纂整理 FAT 文件系統格式的現有解釋,確保在採用 UEFI 時可以使用那些格式,並規定 UEFI 兼容固件必須能夠讀取那些格式。UEFI 規範針對這方面的具體規定如下:

“可擴展固件接口 (EFI) 支持的文件系統基於 FAT 文件系統。EFI 定義了可以明確記錄和測試的具體 FAT 版本。FAT 的唯一定義必須符合 EFI 規範及關聯參考文檔,對 FAT 唯一定義的實現必須支持 EFI。爲區分 EFI 文件系統與純 FAT,定義了新的分區文件系統類型。”

“EFI 系統分區”是採用 FAT 變種(UEFI 規範定義的變種之一)格式化的任意分區,該分區被賦予特定 GPT 分區類型,以幫助固件識別該分區。此分區的目的如上所述:固件層確實可以讀取“普通”磁盤分區中的數據。希望我已明確解釋爲何這種設計更佳:操作系統可以創建、格式化和掛載分區(採用廣泛理解的格式),並將啓動裝載程序的代碼和固件可能需要讀取的所有其他內容放到這個分區中,而不用像 MBR 磁盤一樣,將啓動裝載程序的代碼寫入磁盤的起始位置空間。

剛開始的時候,對我而言,整個 ESP 的設計看起來有點匪夷所思且令人困惑,因此我希望本節可以解釋爲何 ESP 實際上是非常優秀的設計——真正匪夷所思和令人困惑的設計是 BIOS/MBR。若要從操作系統層寫入某些內容,唯一的方法是將這些內容寫入磁盤起始位置的某部分(但不知道是多少)空間,而並沒有具體規定其中的具體實現。如果回過頭再看,這種設計並不明智,且難以理解。

正如我們稍後會強調的那樣,UEFI 規範試圖採用更直觀嚴格的方法——它很少禁止固件執行其他操作。UEFI 規範並不反對編寫固件,用於執行以其他格式寫成的代碼、讀取其他類型的分區表,以及讀取用UEFI 變種文件系統(非 FAT)格式化的分區。但是 UEFI 兼容固件必須至少能夠實現執行 EFI 可執行文件、讀取 GPT 分區表、以及讀取 ESP,因此如果你正編寫操作系統或其他東西,並且想要在 UEFI 兼容固件上運行的話,你也得遵循 UEFI 規範,這就是 EFI 系統分區的概念非常重要的原因:它允許(至少理論上)將 EFI 可執行文件放在以 UEFI FAT 格式化且 GPT 分區類型正確無誤的分區上,另外,系統固件要能夠讀取該分區。這種機制非常嚴謹,等價於 BIOS 中的“固件能夠執行放置在 MBR 空間中的啓動裝載程序代碼”。

UEFI 規範爲我們提供了三大重要基礎,這些重要基礎是上層架構正常運行的立足之本:

  • 讀取分區表
  • 訪問某些特定文件系統中的文件
  • 執行特定格式的代碼

相比 BIOS 固件所提供的功能,UEFI 的功能要豐富得多。但是,爲了完成固件層可以處理多重目標(而不僅僅是磁盤)啓動的願景,我們需要其他基礎:需要建立一種機制,通過這種機制,固件可以查找各種可能的啓動目標,並提供相應的配置方法。

UEFI 啓動管理器

UEFI 規範定義了名爲 UEFI 啓動管理器的一項功能(Linux發行版包含名爲efibootmgr 的工具,可用於更改 UEFI 啓動管理器的配置)。如果你確實閱讀過 UEFI 規範,那麼就會發現,UEFI 規範對 UEFI 啓動管理器作出瞭如下規定:

“UEFI 啓動管理器是一種固件策略引擎,可通過修改固件架構中定義的全局NVRAM 變量來進行配置。啓動管理器將嘗試按全局 NVRAM 變量定義的順序依次加載 UEFI 驅動和 UEFI 應用程序(包括 UEFI 操作系統啓動裝載程序)。”

好,既然已經明確了這一概念,那我們就繼續吧。不,先等等。我來先把那一項規定解釋清楚,便於理解。簡單來說,你可以把 UEFI 啓動管理器視爲啓動菜單。在 BIOS 固件上,固件層的“啓動菜單”(當然)是,啓動時連接到計算機的各個磁盤——不多不少。但是對於 UEFI 固件而言,情況有所不同。

UEFI 啓動管理器可以進行配置——簡言之,你可以向“啓動菜單”添加項或者從中刪除項。固件也可以(事實上, UEFI 規範也有此要求)根據連接到計算機的磁盤或根據某些固件配置,在此啓動菜單中“生成”有效項。你也可以檢查啓動菜單,確保正確無誤。

UEFI 提供了一種非常優秀的機制,可以從上層架構執行此操作:你可以從已啓動的操作系統中配置系統啓動行爲。如果已通過 UEFI 啓動 Linux,就可以使用 efibootmgr 工具來完成所有這些操作。Windows 也有相應的工具,但是我對 Windows 下的工具非常不熟悉。我們不妨看一些典型的 efibootmgr 輸出,這些是我從 Fedora 論壇轉過來的,稍微進行了調整:

[root@system directory]# efibootmgr -v
BootCurrent: 0002
Timeout: 3 seconds
BootOrder: 0003,0002,0000,0004
Boot0000* CD/DVD Drive  BIOS(3,0,00)
Boot0001* Hard Drive    HD(2,0,00)
Boot0002* Fedora        HD(1,800,61800,6d98f360-cb3e-4727-8fed-5ce0c040365d)File(\EFI\fedora\grubx64.efi)
Boot0003* opensuse      HD(1,800,61800,6d98f360-cb3e-4727-8fed-5ce0c040365d)File(\EFI\opensuse\grubx64.efi)
Boot0004* Hard Drive    BIOS(2,0,00)P0: ST1500DM003-9YN16G        .
[root@system directory]#

這個示例非常清晰。我們可以從中觀察細節。

第一行表示,目前你從“啓動菜單”的哪個項進行了啓動。第二行非常明顯(如果固件的 UEFI 啓動管理器顯示了類似啓動菜單的界面,那麼這一行表示繼續啓動默認項之前的超時)。BootOrder 是列表中啓動項的嘗試順序。其餘輸出顯示了實際的啓動項。我們稍後會說明每一個啓動項具體作用。

如果完全正常啓動 UEFI 固件,而不進行任何調整(我們稍後會討論),UEFI 固件將按照BootOrder 中列出的順序,嘗試從“啓動菜單”中的每個“項”進行啓動。因此,在這臺計算機上,UEFI 固件將嘗試啓動名爲“opensuse”的項,如果啓動失敗,然後再嘗試啓動名爲“Fedora”的項,然後再是“CD/DVD Drive”,接着是第二項“Hard Drive”。

UEFI原生啓動:實際工作原理——啓動管理器項

那麼,這些項的實際含義是什麼?實際上,UEFI 規範之所以顯得複雜,很大程度上是因爲其中的不確定因素太多。如果你正在閱讀 UEFI 規範,那麼先做好心理準備,然後前往 EFI_DEVICE_PATH_PROTOCOL 一節。但是請注意,這個協議是通用的,雖然這個協議不涉及啓動過程,但是有其他作用——這實際上就是 UEFI 官方的設備標識方法,這種標識方法可用於啓動管理器項以及各種其他用途。出於各種原因,並不是每一種潛在的 EFI 設備都像 UEFI 啓動管理器項一樣起作用(如果你想從視頻適配器啓動,很可能不會成功)。但是啓動菜單中顯然可以包含指向 PXE 服務器(而不是磁盤分區)的項。UEFI 規範進行了多項規定,可以向 UEFI 啓動管理器配置中添加除磁盤以外的啓動目標。

但是對我們而言,只需要考慮連接到計算機的一般磁盤即可。既然這樣,我們來討論下可能遇到的三種啓動項類型。

BIOS 兼容啓動項

在本示例中,Boot0000 和 Boot0004 實際上是 BIOS 兼容模式啓動項,而不是原生 UEFI 啓動項。這些啓動項不是通過外部工具添加到 UEFI 啓動管理器配置中的,而是由固件本身生成的——這也是 UEFI 固件實現 BIOS 兼容啓動的常見方式,通過生成 UEFI 啓動管理器項,可觸發指定設備的 BIOS 啓動。至於 UEFI 啓動管理器如何呈現給用戶,這是另一個問題,我們稍後討論。根據具體固件及其配置,其中有些項可能無法顯示。每一項只會具有一個名稱(“CD/DVD Drive”、“Hard Drive”),這表示“如果選中此項,那麼就以 BIOS 兼容模式啓動本磁盤”(其中,對於 Boot0000,“本磁盤”爲 3,0,00,對於 Boot0004,“本磁盤”爲 2,0,00)。

“回退路徑 (Fallback path)”UEFI 原生啓動項

Boot0001 項(我虛構的,實際操作中可能不存在,這裏只是爲了舉例說明)用於通知固件嘗試從特定磁盤啓動(以 UEFI 模式而不是 BIOS 兼容模式),但是並沒有向固件提供其他信息。它沒有指定磁盤上的具體啓動目標,而只是讓固件啓動磁盤。

UEFI 規範定義了一種“回退”路徑 (Fallback path),用於啓動此類啓動管理器項,其工作原理類似於 BIOS 驅動器啓動:它會在標準位置查找某些啓動裝載程序代碼。但是其中的細節和 BIOS 不同。

當嘗試以這種方式啓動時,固件真正執行的操作相當簡單。固件會遍歷磁盤上的每個 EFI 系統分區(按照磁盤上的分區順序)。在 ESP 內,固件將查找位於特定位置的具有特定名稱的文件。在 x86-64 PC 上,固件會查找文件 \EFI\BOOT\BOOTx64.EFI。固件實際查找的是 \EFI\BOOT\BOOT{計算機類型簡稱}.EFI,其中,“x64”是 x86-64 PC 的“計算機類型簡稱”。文件名還有可能是 BOOTIA32.EFI (x86-32)、BOOTIA64.EFI (Itanium)、BOOTARM.EFI(AArch32,即32位ARM)和 BOOTAA64.EFI(AArch64,即64位ARM)。然後,固件將執行找到的第一個有效文件(當然,文件需要符合UEFI規範中定義的可執行格式)。

這種機制的設計目的不在於啓動日常使用的操作系統。它的設計目的更像是爲了啓動可熱插拔、與設備無關的介質(如 Live 映像和操作系統介質)。這也是這種機制的常見用途。如果查看 Linux 或其他操作系統的 UEFI 兼容 Live 或安裝介質,你會發現其中包含 GPT,以及位於(或靠近)設備起始位置的 FAT 分區,該分區的 GPT 分區類型標識爲 EFI 系統分區。在那個分區中,會有一個 \EFI\BOOT 目錄,目錄中至少包含上述特殊命名的文件之一。當以原生 UEFI 模式啓動 Fedora Live 或安裝介質時,就會採用這種機制。BOOTx64.EFI(或其他)文件將處理剩餘啓動過程,從而啓動介質上包含的真正操作系統。

完全原生 UEFI 啓動項

Boot0002 和 Boot0003 是存儲設備上所安裝操作系統的“典型”項。這些項顯示了 UEFI 啓動機制的全部優勢,不僅僅是“從此磁盤啓動”,而是“啓動此特定磁盤上此特定位置中的這一特定啓動裝載程序”。

Boot0002 是由原生 UEFI Fedora 安裝生成的啓動項。Boot0003 是由原生 UEFI OpenSUSE安裝生成的啓動項。按照字面意思,這些啓動項表示“從此分區加載這一文件”。分區指的是 HD(1,800,61800,6d98f360-cb3e-4727-8fed-5ce0c040365d) 這個東西:表示某一特定分區(使用 EFI_DEVICE_PATH_PROTOCOL,我不打算對此進行詳細介紹。如果你通過固件界面和 efibootmgr 與啓動管理器進行交互,你也不需要知道其中的細節)。文件指的是 (\EFI\opensuse\grubx64.efi) 這個東西:它僅表示“加載所述分區上此位置中的文件”。這裏所指的分區基本上始終指的就是充當 EFI 系統分區的那個分區,因此:可以放心地讓固件訪問 EFI 系統分區。

UEFI 規範提供這一機制,以便操作系統可啓動:操作系統將啓動裝載程序(作用爲加載操作系統內核等)安裝到 EFI 系統分區中,並使用某一名稱(顯然,這一名稱通常來源於操作系統名稱)以及啓動裝載程序(EFI 可執行格式,用於加載操作系統)的位置向 UEFI 啓動管理器配置中添加啓動項。

Linux發行版使用 efibootmgr 工具處理 UEFI 啓動管理器。進行原生 UEFI 安裝時,有關啓動裝載方面,Linux 發行版實際進行的操作相當簡單:它會創建一個 EFI 系統分區(如果不存在此分區),使用相應配置將 EFI 啓動裝載程序(通常爲 grub2-efi,但是也有例外)安裝到 EFI 系統分區中的正確路徑下,然後調用 efibootmgr 添加相應的 UEFI 啓動管理器項(指向其啓動裝載程序)。如果已存在 EFI 系統分區,大部分發行版會使用現有分區(儘管完全可以創建新的 EFI 系統分區並使用這個新分區):我們已經提到過,UEFI 是一種寬鬆規範,只要在邏輯上遵循其設計,那麼有多少個 EFI 系統分區都沒問題。

配置啓動過程(固件 UI)

上文描述了 UEFI 規範定義的基本機制,用於管理 UEFI 啓動過程。固件用戶界面可能不會明確遵循這一機制,瞭解這一點非常重要。不幸的是,UEFI 規範有意未限制啓動過程的呈現方式或用戶配置啓動過程的方式,這表示——由於我們也從事固件工程——每個固件會有不同的實現方法,並且其中某些固件的實現方法較瘋狂。

許多固件的啓動配置界面較直觀。優秀的固件設計至少會顯示啓動順序以及其中的各個啓動項,允許用戶添加/刪除項、更改啓動順序或在某次特定啓動中忽略原有啓動順序(僅針對那次啓動生效,或直接讓固件啓動特定菜單項,甚至可以選擇讓固件以 BIOS 兼容模式或 UEFI“回退 (Fallback)”模式“啓動這塊磁盤”,我的固件就可以這麼操作)。此類界面通常可以僅按名稱顯示完整的原生 UEFI 啓動項(例如我們上文提到的 Fedora 和 OpenSUSE 示例);你需要檢查 efibootmgr –v 的輸出,以詳細瞭解在調用這些項時,它們具體會嘗試並執行哪些操作。

某些固件會嘗試對配置進行抽象和簡化,最終結果良莠不齊。例如,如果可以選擇“啓用或禁用”BIOS 兼容模式,固件很有可能會爲已連接驅動器的 UEFI 啓動管理器配置添加或刪除 BIOS 兼容項。如果可以選擇“啓用或禁用”原生 UEFI 啓動,那麼在用戶“禁用”原生 UEFI 啓動時,固件很有可能更改 UEFI 啓動管理器配置,從 BootOrder 中刪除所有原生UEFI啓動項。

請謹記,固件界面中的所有配置選項所執行的操作就是在後臺配置 UEFI 啓動管理器的行爲。如果你能理解以上所有內容,那麼當你更改固件界面中的選項時,你會更容易理解其背後的本質。

在 BIOS 中,系統不會始終嘗試優先從可移動驅動器(CD、USB)進行啓動,然後再從驅動器啓動。根據實際情況,結果可能有所不同。有些 BIOS 固件會優先嚐試從 CD 啓動,然後再嘗試從硬盤啓動(而不是 USB)。試圖安裝新的操作系統時,用戶已習慣於時常檢查 BIOS 配置,以確保啓動順序“正確無誤”。

UEFI 也是如此,但是由於 UEFI 啓動管理器機制的靈活性/複雜性,這一過程看起來可能顯得陌生而可怕。

在系統嘗試啓動固定啓動項之前,如果想要確保系統使用“回退(Fallback)”機制優先從可移動設備啓動(例如,在安裝 Fedora 時),需要將可移動設備作爲固件的默認啓動項,或需要相應設置固件。根據具體固件界面,可能發現每個連接的可移動設備都有對應的“菜單項”,你只需要調整啓動順序,把你想要的可移動設備放在首位即可,有時候你也會發現可以直接請求“對此特定磁盤進行 UEFI 恢復啓動”,另外你還可能發現固件會嘗試將配置進行抽象。我們不知道具體的固件界面是什麼樣,因此難以編寫說明。但是既然你已瞭解背後的工作原理,那麼就可能更容易理解固件用戶界面配置的含義。

配置啓動過程(通過操作系統)

如上所述,與 BIOS 機制不同,你可以從操作系統層面配置 UEFI 啓動過程。如果你的固件比較令人噁心,你可能需要執行此操作才能達成目的。

你可以使用之前提過的 efibootmgr 工具來添加、刪除和修改 UEFI 啓動管理器配置中的項,這一工具也具有其他豐富功能。你可以更改啓動順序。你可以更改下次啓動時的首要啓動項,而不需要使用 BootOrder 列表(如果你或其他某些工具已經進行過配置,efibootmgr –v 的輸出將包括 BootNext 項,說明下一次啓動將加載的菜單項)。Windows 下也有類似的工具。因此如果你難以從固件界面配置 UEFI 啓動,但是你可以啓動某種原生 UEFI 操作系統,那麼你可以考慮從操作系統(而不是固件 UI)進行啓動配置。

結論:

  • UEFI固件包含某些非常類似於啓動菜單的內容。
  • 可以使用 efibootmgr –v 從任何原生 UEFI 啓動的 Linux 操作系統中查詢 UEFI 啓動配置,也可以使用 efibootmgr 更改配置(有關詳細信息,請參閱 man 頁面)。
  • “啓動菜單”可以包含表示“以 BIOS 兼容模式啓動此磁盤”,“通過回退路徑 (Fallback path) 以原生 UEFI 模式啓動此磁盤”(將使用上文所述的“尋找 BOOT(某字符串).EFI”方式),或“啓動此特定位置(幾乎始終爲 EFI 系統分區)中的特定 EFI 格式的可執行文件”等含義的項。
  • UEFI 規範嘗試一種優秀、簡潔的設計,讓所有操作系統都將其自身的啓動裝載程序安裝到 EFI 系統分區中,然後在“啓動菜單”中添加指向這些啓動裝載程序的項,同時不得干涉其他目標的啓動過程。
  • 你的固件 UI 可以自由實現此機制,雖然具體的實現結果良莠不齊。

在 UEFI 計算機上安裝操作系統

我們快速瀏覽下上文中與在 UEFI 計算機上安裝操作系統相關的具體結果。

原生 UEFI 啓動和 BIOS 兼容啓動

用戶有時會忽略以下事項:

  • 如果以“原生 UEFI”模式啓動安裝介質,安裝介質將以原生 UEFI 模式安裝操作系統:它將嘗試向 EFI 系統分區寫入 EFI 格式的啓動裝載程序,並嘗試向 UEFI 啓動管理器的“啓動菜單”中添加啓動項,用於啓動該啓動裝載程序。
  • 如果以“BIOS 兼容”模式啓動安裝介質,安裝介質將以 BIOS 兼容模式安裝操作系統:它將嘗試向磁盤上的 MBR 空間寫入 MBR 類型的啓動裝載程序。

這適用於(現在暫時忽略其中的無關警告)我接觸過的所有操作系統。因此你可能確實想了解,如何在固件層選擇以原生 UEFI 模式啓動可移動設備,以及如何在固件層選擇以 BIOS 兼容模式啓動可移動設備,確保在安裝時可以隨意選擇需要使用的模式。

如果以 BIOS 兼容模式啓動安裝介質,那麼你絕對無法成功進行操作系統的原生 UEFI 安裝,因爲安裝程序無法配置 UEFI 啓動管理器(除非以原生 UEFI 模式啓動安裝介質)。

理論上,在以原生 UEFI 模式啓動之後,操作系統的安裝程序可通過 BIOS 模式安裝該操作系統,即,將啓動裝載程序寫入磁盤 MBR,但是大部分安裝程序無法執行此操作,這種做法比較可取。

確定啓動模式

有時候,在啓動操作系統安裝程序之後,你不確定啓動模式爲原生 UEFI 模式還是 BIOS 兼容模式。別擔心。有幾種簡單方法可以確定啓動模式。最簡單的方法之一是嘗試讀取 UEFI 啓動管理器。如果你啓動了 Linux 安裝程序或環境,並且可以運行 shell(例如,在 Fedora 安裝程序中是 Ctrl-Alt-F2),請運行 efibootmgr –v。如果你啓動的是原生 UEFI 模式,那麼就可以看到上文所示的 UEFI啓動管理器配置。如果你啓動的是 BIOS 兼容模式,那麼會看到類似以下內容:

Fatal: Couldn't open either sysfs or procfs directories for accessing EFI variables.
Try 'modprobe efivars' as root.

如果啓動了其他操作系統,你可以嘗試運行該操作系統的內置實用程序,讀取 UEFI 啓動管理器,並查看是否顯示了明確輸出或類似錯誤。或者你可以檢查系統日誌並搜索“efi”和/或“uefi”,從中可能發現蛛絲馬跡。

啓用原生 UEFI 啓動

若要啓用原生 UEFI 模式的啓動,那麼操作系統安裝介質必須明確符合我們剛剛說明的所有規範:具有 GUID 分區表,和 EFI 系統分區,啓動裝載程序位於正確的“回退”路徑 (Fallback path) 中—\EFI\BOOT\BOOTx64.EFI(其他平臺可能會有其他名稱)。如果無法以原生 UEFI 模式啓動安裝介質,並且無法查出原因,那麼請檢查安裝介質是否滿足上述條件。顯然,當使用 livecd-iso-to-disk 工具將 Fedora 映像寫入 USB 存儲器時,你必須傳遞 --efi 參數,才能將存儲器配置爲可用 UEFI 模式啓動。

強制使用 BIOS 兼容啓動

如果你的固件難以通過 BIOS 兼容模式從可移動介質啓動,但是你又確實想通過這種方式啓動,那麼可以使用一些小把戲:完全禁用該介質的原生 UEFI 啓動模式。可以通過清除所有 EFI 系統分區來輕鬆執行此操作(或者,如果使用 livecd-iso-to-disk 從 Fedora 映像創建 USB存儲器,那麼只需去掉 --efi 參數,存儲器就會變爲不可通過 UEFI 模式啓動)。如果執行完此操作以後,你的固件仍然無法以 BIOS 兼容模式啓動介質,那麼就去吐槽你的固件供應商吧(如果還沒吐槽過)。

磁盤格式(MBR vs. GPT)

其他注意事項如下:

  • 如果想執行“BIOS 兼容”類型的安裝,那麼需要安裝到 MBR 格式的磁盤。
  • 如果想執行原生 UEFI 安裝,那麼需要安裝到 GPT 格式的磁盤。

當然,爲了給用戶找不自在,許多固件可以通過 BIOS 模式從 GPT 格式的磁盤啓動。事實上,從技術層面而言,也要求 UEFI 固件能從 MBR 格式的磁盤以 UEFI 模式啓動(雖然無法保證)。但是你應當儘可能避免這種情況。這些注意事項非常重要,因爲許多用戶都曾深受其害。例如,以原生 UEFI 模式啓動操作系統安裝程序,然後試圖直接安裝到 MBR 格式的磁盤是非常不明智的。很有可能失敗。多數現代操作系統安裝程序將把磁盤自動重新格式化爲正確格式(如果你允許安裝程序徹底清除磁盤數據),但是,如果你嘗試讓安裝程序“對此 MBR 格式的磁盤執行原生 UEFI 安裝,並且不要重新格式化這塊磁盤,因爲上面有重要數據”,那麼就很有可能失敗,儘管技術層面而言,UEFI 規範提到了這種配置。具體而言,至少 Windows 和 Fedora 會明確禁止這種配置。

檢查磁盤格式

你可以使用 parted 實用程序檢查給定磁盤的格式:

[adamw@adam Downloads]$ sudo parted /dev/sda
GNU Parted 3.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p                                                                
Model: ATA C300-CTFDDAC128M (scsi)
Disk /dev/sda: 128GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End    Size   Type     File system  Flags
 1      1049kB  525MB  524MB  primary  ext4         boot
 2      525MB   128GB  128GB  primary               lvm

(parted)

 

注意到 Partition table: msdos 那一行了嗎?這是一塊 MBR/MS-DOS 格式的磁盤。如果是 GPT 格式的磁盤,會顯示 gpt。你可以從 parted 中通過執行 mklabel gpt 或 mklabel msdos 將磁盤重新格式化爲其他類型分區表。這會破壞磁盤內容。

對於多數操作系統的安裝程序而言,如果你採用的磁盤配置會清空目標磁盤的所有內容,那麼根據執行的安裝類型,安裝程序就會自動使用最合適的配置重新格式化磁盤。但是如果你想使用現有磁盤而不格式化,那麼你需要檢查該磁盤的格式並三思而後行。

執行手動分區時處理 EFI 系統分區

我只能針對 Fedora 給出權威建議,但是其中的主要內容可能也適用於其他發行版/操作系統。

執行原生 UEFI 安裝,並且採用 GPT 格式的磁盤時,或者允許 Fedora 重新格式化磁盤(通過刪除所有現有分區)時,如果允許 Fedora 自動處理分區,那麼 Fedora 就會自動處理 EFI 系統分區。

但是,如果使用自定義分區,Fedora 會要求指定 EFI 系統分區,以供安裝程序使用。如果不執行此步驟,安裝程序會報錯(錯誤消息的含義不明)並拒絕啓動安裝。

因此,如果執行原生 UEFI 安裝並使用自定義分區,需要確保類型爲“EFI 系統分區”的分區已掛載到 /boot/efi(這是 Fedora 查找 EFI 系統分區的路徑)。如果系統上存在現有 EFI 系統分區,那麼僅需將其掛載點設置爲 /boot/efi 即可。如果還沒有 EFI 系統分區,那麼請創建一個分區,將其類型設置爲 EFI 系統分區,大小至少爲 200MB(建議 500MB),然後將其掛載點設置爲 /boot/efi。

具體示例

總結:如果購買了 Windows 8 或更高版本的操作系統,那麼你的 Windows 基本上肯定是通過原生 UEFI 安裝到 GPT 格式磁盤的。這表示如果你想安裝其他操作系統,並與 Windows 共存,那麼需要通過原生 UEFI 方式安裝操作系統。如果你不喜歡 UEFI,並且想要用回老掉牙的 BIOS,那麼恐怕就得清空整個原生 UEFI 的 Windows,而且需要重新將磁盤格式化爲 MBR。

缺陷

上文解釋了 UEFI 的啓動原理(至少解釋得差不多了)。我這種描述方法應該還可以吧?

但是,UEFI 並不完美,也有許多問題。

細心的讀者可能已經留意,我曾經提到過,UEFI 規範提供了一種機制。這種說法很嚴謹,也很重要。由於 UEFI 規範是一種“廣泛共識”,因此其主要缺點之一(就特定方面而言)是並未提供具體實現。

如果仔細閱讀 UEFI 規範,就會發現 UEFI 規範的基本方式是定義 UEFI 兼容固件必須支持的一系列功能。但是 UEFI 規範並沒有嚴格規定這些功能的具體實現方法。

因此,UEFI 規範只要求系統固件必須遵循其中描述的所有內容,以便滿足 UEFI 兼容固件的要求。但是,規範本身未規定操作系統“應該”或“必須”怎麼做,並且 UEFI 規範也沒有規定固件不得支持(或者不期望支持)的功能。換言之,在制定 UEFI 固件時,需要支持 GPT 格式的磁盤和 FAT 格式的 EFI 系統分區,並且必須以標準格式讀取 UEFI 啓動管理器項等等——但是也可以隨意添加其他未規定的功能。

從 UEFI 規範中不難發現其中的隱喻——UEFI 規範仔細設置了一種良好機制,用於在固件層處理操作系統(或其他啓動項)選擇。但是 UEFI 規範並不要求一定要這麼做,其他廣受讚譽的規範也沒有類似規定。

因此,在實際使用時,我們可能遇到各種複雜情況。例如,Apple Mac 的 HFS+ 分區中隨附了某些啓動裝載程序。UEFI 規範提到,UEFI 兼容固件必須支持特定 GPT 分區類型的 UEFI FAT 分區(標識爲“EFI 系統分區”),但是 UEFI 規範並沒有提到固件不能識別其他文件系統類型並從中加載啓動裝載程序。(此類分區是否應視爲“EFI 系統分區”,這很難回答,在此不做探討。)

要是所有廠商都能按照 UEFI 規範嚴格使用 EFI 系統分區,那就不會有這麼多問題了。但是 Apple 畢竟是 Apple,它的產品設計領先於其他廠商,率先設計出了可以從 HFS+ 分區讀取和加載代碼的固件,導致現在其他廠商不得不緊隨 Apple 的腳步,除非他們不打算支持 Mac。在啓動過程設計中,Apple 進行的工作遠超出 UEFI 規範的範圍,因此,如果你想讓其他操作系統以美觀的圖標或其他形式顯示在 Mac 的圖形啓動菜單上,你所要做的操作將超出 UEFI 規範的建議範圍。

還有各種類似的極端狀況,使人煩不勝煩,但是我們先不管了。這篇文章夠長的了。

另外,就像之前提到過的,UEFI 規範並沒有對機制的具體呈現方式進行約束。因此,如果一些軟件公司設計的操作系統符合 UEFI 規範,並且可以安裝 EFI 啓動裝載程序,並明確命名 EFI 啓動管理器項(例如,Fedora 和 Windows),那麼如果要向用戶提供某種相對辨識度較高的漂亮界面,讓用戶可以從中選擇啓動 Windows 或 Fedora,就得看固件本身設計得怎麼樣。固件設計得越糟糕,操作系統工程師就越不會遵守 UEFI 規範,他們越可能在固件層上另起爐竈。

說句公道話,我們可以在操作系統層實現更多功能。我們可以用更整潔直觀的方式實現 efibootmgr 的所有功能——例如,我們可以採用“無視下一次啓動時的啓動順序,直接啓動此項”,同時將“重新啓動到 Windows”作爲選項之一。如果開發人員能夠用更直觀的方式展現 efibootmgr 的所有功能,那將會非常不錯。Windows 8 系統在一定程度上採用了這種方式——例如,用戶可以從 Windows 8 設置菜單中將系統重新啓動到固件 UI。但是這還不夠。

這些實在令人慾哭無淚,因爲 UEFI 本來可以更好地進行統一。對於多重啓動,BIOS 不提供任何類型的規範或標準,因此完全需要在固件層上處理多重啓動。我們(這一產業)已經提出了某種處理多重啓動的規範,但是我們從未將其付諸實施,因此最終不了了之。而每種操作系統都採用自己的多重啓動方法,大量開發人員也自己寫了啓動裝載程序,試圖包攬所有操作系統。而所有操作系統和獨立的啓動裝載程序難以互相兼容。我想說的是,在 UEFI 誕生之前,多重啓動的實現方式一團混亂。

如果 UEFI——或者基於 UEFI 的某種規範——要求所有廠商遵循 UEFI 提出的規範,並要求固件提供直觀的用戶界面,那將會終結現階段的混亂情況。但是現實不如人意,因此 UEFI 的情況完全可能比 BIOS 更糟糕。如果大量固件沒有爲 UEFI 啓動管理器機制提供良好的 UI,那麼操作系統供應商可能放棄 UEFI 啓動管理器機制(或選擇性地進行支持),轉而在 UEFI 中重現 BIOS 多重啓動的混亂情況——如此一來,我們就得收拾所有爛攤子,外加 UEFI 啓動管理器層的其他影響。在整個 UEFI 啓動管理器機制上,用戶可能裝有多個啓動裝載程序,互相爭搶裝載多個操作系統的控制權,而 UEFI 啓動管理器機制只會機械地處理各種變量,而無法解決這種混亂情況。

這不是某人靈光閃現的荒唐想法,而是可能實際發生的真實情形。

另外,在這方面產生的 UEFI 缺陷是由一時疏忽引起的——這些缺陷不受委員會控制,也不是某人故意爲之的結果。如果你的系統固件很坑爹,無法讓你輕鬆訪問 UEFI 啓動管理器,那麼你的發泄對象不應該是 UEFI 論壇或微軟,當然也不是 Fedora 或者我。你應該歸咎於系統/主板製造商和他們僱用的傻逼固件開發人員。凡是大腦健全的人,都能看出來,UEFI 規範已經明確說明,爲 UEFI 啓動管理器提供某種直觀的用戶界面是非常有益的,所有反人類的固件都是一堆垃圾代碼。的確,UEFI 論壇已經意識到固件工程師難以脫離現有約束重新學習新規範,但是,固件工程師最終還是應該與時俱進。

簡單來說,“所有固件都是垃圾代碼”。這句話通常非常準確。

安全啓動 (Secure Boot)

我們最後要介紹的,就是安全啓動 (Secure Boot)。

安全啓動 (Secure Boot) 並不神奇,也不復雜。纔怪。安全啓動 (Secure Boot) 複雜得要命,但是其理論並不複雜。安全啓動 (Secure Boot) 本身也並不邪惡。事實就是如此,你也應當認同這一事實,除非你認爲GPG也有惡意。

在 UEFI 規範(2.4A 版本)的第 28 章對安全啓動 (Secure Boot) 進行了定義。這種機制事實上非常明智。但是其原理卻非常簡單。UEFI 規範規定固件可以包含一系列簽名,並拒絕運行未簽名或簽名與固件中包含的簽名不一致的 EFI 可執行文件。

就這麼簡單?當然不是了,這只是一種簡單概括。安全問題很複雜,因此纔會產生通過安全啓動 (Secure Boot) 來實現真正安全啓動鏈的各種方法。mjg59 可以進行詳細介紹,或者你可以完整閱讀第 28 章。但是其中只涉及了基本概念。

使用公開密鑰加密來驗證某個文件完整性的方法很難判斷其好壞。幾乎所有 Linux 發行版都依賴這種加密方法——我們爲軟件包簽名,在嘗試安裝未使用我們的密鑰之一簽名的軟件包時,軟件包管理器將發出警告。這不是我們的錯,我也不認爲會有人因爲以這種方式使用公開密鑰加密進行簽名而歸咎於操作系統本身。從字面上看,安全啓動 (Secure Boot) 與這種廣泛認可的機制完全相同,只不過安全啓動 (Secure Boot) 適用於啓動鏈。由於一撮媒體人找錯了槽點,並揪着不放,導致大衆受到了廣泛誤導,認爲安全啓動 (Secure Boot) 是洪水猛獸。

UEFI 規範中定義的安全啓動 (Secure Boot) 並沒有對固件所信任的密鑰形式及其來源作出規定,我也不打算介紹所有細節,因爲過於枯燥乏味,而且本文已經挺長了。但是總的來說,UEFI 規範只對執行啓動鏈的加密驗證進行了定義。UEFI 規範甚至沒有涉及用於執行這一過程的策略可能產生的問題。這本來並沒有錯,因爲這樣可以保證其靈活性,並且 UEFI 規範允許在多個層面配置涉及的所有機制。UEFI 規範中未提及微軟,也沒有和微軟互相勾結。如果你不信,那麼你可以閱讀 UEFI 規範。我已經提供了所有說明。字面上來說,對於那些反對在固件規範中將啓動裝載程序加密驗證機制作爲可選功能的人,我不予置評。

實際使用安全啓動 (Secure Boot)

有關安全啓動 (Secure Boot) 的所有不滿並不針對安全啓動 (Secure Boot) 機制本身——雖然發出這些不滿的人可能不這麼認爲——而是針對安全啓動 (Secure Boot) 在實際操作中的特定實現方式。

我們唯一在意的是,對於預裝 Windows 8 或更高版本 Windows 的 PC 而言,安全啓動 (Secure Boot) 是默認開啓的。

微軟將這些稱爲“Windows 硬件認證要求”。這些要求並不是什麼絕密內容,所有人都可以在互聯網上閱讀。

如果想從微軟那裏以低廉的價格獲得預裝 Windows 的批量許可,並在機箱上貼有“微軟認證”標籤,那麼你必須符合這些認證要求。微軟的約束力有限:他們不是美國或其他國家/地區的法律制定者,無論其他人怎麼想。即使你銷售的 PC 不符合這些要求,比爾?蓋茨也不會拿你怎麼樣,前提是你不需要預裝廉價的 Windows 副本和那張“微軟認證”標籤。對於不符合微軟許可計劃的在售 PC,事實上並不要求如何配置安全啓動 (Secure Boot),甚至根本不需要提供安全啓動 (Secure Boot) 功能。具有 UEFI 2.2 或更高版本兼容固件的 PC 必須提供安全啓動 (Secure Boot) 功能,但是並沒有規定具體的實現方法(包括關閉安全啓動 (Secure Boot) 的方法)。

如果你對安全啓動 (Secure Boot) 意見很大,那麼就別找藉口了,馬上去讀讀微軟認證要求吧(http://msdn.microsoft.com/en-us/library /windows/hardware/dn423132.aspx)。你可以搜索“Secure Boot”來閱讀相關內容。從“System.Fundamentals.Firmware.UEFISecureBoot”一節開始。

你最好讀一遍,但是我對其內容進行了總結。

符合微軟認證要求的計算機必須滿足以下條件:

  • 默認啓用安全啓動 (Secure Boot)(服務器除外)
  • 在其信任密鑰列表中包含微軟的密鑰
  • 啓用安全啓動 (Secure Boot) 時,必須禁用 BIOS 兼容模式(如果沒記錯的話,UEFI 規範也有此要求)
  • 支持簽名黑名單

符合微軟認證要求的 x86 計算機還必須滿足以下附加條件:

  • 允許自然人禁用安全啓動 (Secure Boot)
  • 允許自然人啓用自定義模式,以及修改固件的信任密鑰列表

符合微軟認證要求的 ARM 計算機還必須滿足以下附加條件:

  • 不允許自然人禁用安全啓動 (Secure Boot)
  • 不允許自然人啓用自定義模式,以及修改固件的信任密鑰列表

是的,你沒看錯。對於 x86 計算機,微軟認證要求明確規定了自然人用戶應當能夠完全控制安全啓動 (Secure Boot)(啓用或禁用),或完全控制安全啓動 (Secure Boot) 的信任密鑰列表。另一個重點是,儘管認證要求規定,信任密鑰列表必須包括微軟的密鑰,但是其中沒有規定不允許包括其他密鑰。微軟認證要求也明確允許系統包含其他任意數量的信任密鑰。

這些要求並不完全出於微軟的好意,之所以作出這些規定,是因爲如果不這麼做的話,微軟將面臨大量訴訟2。真正瞭解 UEFI 和安全啓動 (Secure Boot) 的用戶可能不會曲解微軟認證要求,這些要求非常清晰明確。這些要求旨在確保認證系統的所有者能完全控制安全啓動 (Secure Boot),事實上這些要求也確實成功確保了這一條件。

如果你有包含 Windows 認證的 x86 系統,但是不允許你禁用安全啓動 (Secure Boot),那麼這就直接違反了認證要求,你應該馬上投訴。如果市面上存在大量這類系統,那麼我們肯定會有麻煩,可能要給那些巨頭廠商提起訴訟了。但是目前爲止,事實並非如此。在我見過的所有 x86 Windows 認證系統中,其固件都有“禁用安全啓動 (Secure Boot)”選項。

對於 ARM 計算機,認證要求顯然更變態:其中的規定和 x86 完全相反,不允許禁用安全啓動 (Secure Boot),也不允許系統所有者更改信任密鑰。非常糟糕且不合理。這使得微軟認證 ARM 系統成爲了一個封閉的環境。值得注意的是,其他主要 ARM 平臺甚至更糟糕。Apple 在所有 iDevice 上鎖定了啓動裝載程序,而且大部分 Android 設備的啓動裝載程序也是鎖定的。

如果你計劃購買微軟認證 ARM 設備,請注意這一問題,你將無法控制設備上的啓動項。如果你對此反感,那就不要購買這樣的設備,也不要購買 iDevice 或啓動裝載程序處於鎖定狀態的 Android 設備(你可以購買啓動裝載程序未鎖定或無法鎖定的 Android 設備,但是需要事先進行調查研究)。

目前,就 x86 設備本身而言,微軟的認證要求實際上明確保障了用戶自由啓動系統的權利。這是件好事。

建議

以下內容是我在管理系統啓動方面的一般建議,不保證其準確性、可靠性或安全性。

  • 如果可以的話,每臺計算機只安裝一個操作系統。如果你需要一個以上操作系統,那就多買幾臺計算機,或使用虛擬機。這麼做的話,事情就簡單多了,而且無論你的固件是 BIOS 或 UEFI,或在 UEFI 系統上使用 BIOS 兼容啓動,都沒什麼關係了。你在使用計算機時也會輕鬆許多。
  • 如果你確實需要在每臺計算機上安裝多個操作系統,那麼請在每塊磁盤上至少安裝一個操作系統。如果你比較熟悉 BIOS 啓動,而且也不需要安全啓動 (Secure Boot) 功能,在這種情況下,對於 UEFI 系統,請優先使用 BIOS 兼容啓動。這樣一來,可能不會有那麼多麻煩,也不會造成數據丟失。如果每塊磁盤只安裝一個操作系統,那麼你也可以混合使用原生 UEFI 和 BIOS 兼容模式。
  • 如果你堅持要在每塊磁盤上安裝多個操作系統,那麼請先理解本文所寫內容。這麼做無異於自作孽,不可活,出了問題可別責怪操作系統供應商。另外,在這種情況下,也不要混用原生 UEFI 和 BIOS 兼容模式,否則就是雪上加霜。
  • 如果你在使用 UEFI 原生啓動,並且不打算自己編譯內核/內核模塊或在 Linux 上使用 NVIDIA/ATI 私有驅動程序,那麼最好啓用安全啓動 (Secure Boot)。這不會有什麼副作用,反而可以帶來額外的安全性,用以應對某些卑鄙的攻擊類型(儘管目前很少被利用)。
  • 如果打算編譯內核/內核模塊或使用 NVIDIA/ATI 私有驅動程序,那就最好禁用安全啓動 (Secure Boot)。或者你可以啓用安全啓動 (Secure Boot),然後閱讀有關配置信任鏈和對內核/內核模塊簽名的說明。但是這一過程至少需要好幾天。
  • 不要在 MBR 格式的磁盤上進行原生 UEFI 安裝,也不要在 GPT 格式的磁盤上進行 BIOS 兼容安裝(如果沒記錯的話,除非你的磁盤大小大於 2.2TB,因爲 MBR 格式無法識別那麼大的磁盤。如果想在那麼大的磁盤上進行 BIOS 兼容安裝,那麼你可能會卡在 BIOS+GPT 的組合上。雖然這種組合可以正常運行,但是有點不靠譜,而且會牽涉到臭名昭著的“BIOS Boot 分區”)。
  • 相信 mjg59 及其他權威人士,包括我。

1. 這一整節都是簡化過的內容——當啓動已安裝的操作系統時,無論啓動裝載程序是否安裝在“ESP”上,對固件都沒有影響;固件只會讀取啓動管理器項,然後嘗試訪問特定分區並執行特定可執行文件,具體請參閱 pjones 的說明。但是一般會使用 ESP 來進行啓動過程,因爲 UEFI 規範中有相應規定,而且這個分區也很方便,固件可以讀取其文件系統。理論上來說,在固件執行可移動介質/回退路徑 (Fallback path) 啓動時,ESP 將不起作用。

2. 注意,這只是我的個人推斷。在整個規範的制定過程中,我都沒有參與,也沒人告訴我這些內容。但是根據已知事實,明顯可以得出這一推斷。


原文鏈接:http://blog.163.com/wood_elf@126/blog/static/651597912014512113851286/

展開全文
name="api.blog.163.com" width="0" height="0" id="api.blog.163.com" src="http://api.blog.163.com/crossdomain.html" style="display: none;">
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章