动态

详情 返回 返回

【Linux】《how linux work》第五章 Linux內核的啓動過程 - 动态 详情

Chapter 5. How the Linux Kernel Boots(第5章 Linux內核的啓動過程)

You now know the physical and logical structure of a Linux system, what the kernel is, and how to work with processes. This chapter will teach you how the kernel starts— or boots. In other words, you’ll learn how the kernel moves into memory up to the point where the first user process starts.

你現在已經瞭解了Linux系統的物理和邏輯結構,知道了內核是什麼,以及如何處理進程。

本章將教你內核是如何啓動的。換句話説,你將學習內核如何將自己加載到內存中,直到第一個用户進程開始運行的過程。

A simplified view of the boot process looks like this:

啓動過程的簡化視圖如下:

  1. The machine’s BIOS or boot firmware loads and runs a boot loader.
  2. The boot loader finds the kernel image on disk, loads it into memory, and starts it.
  3. The kernel initializes the devices and its drivers.
  4. The kernel mounts the root filesystem.
  5. The kernel starts a program called init with a process ID of 1. This point is the user space start.
  6. init sets the rest of the system processes in motion.
  7. At some point, init starts a process allowing you to log in, usually at the end or near the end of the boot.This chapter covers the first four stages, focusing on the kernel and boot loaders. Chapter 6 continues with the user space start.
  8. 計算機的BIOS或引導固件加載並運行引導加載程序。
  9. 引導加載程序在磁盤上找到內核鏡像,將其加載到內存中並啓動它。
  10. 內核初始化設備和驅動程序。
  11. 內核掛載根文件系統。
  12. 內核啓動一個名為init的程序,它的進程ID為1。這一點是用户空間的起點。
  13. init啓動其餘的系統進程。
  14. 在某個時候,init啓動一個進程,允許你登錄,通常在啓動結束或接近結束時。本章重點介紹前四個階段,關注內核和引導加載程序。第6章將繼續講述用户空間的啓動。

Your ability to identify each stage of the boot process will prove invaluable in fixing boot problems and understanding the system as a whole. However, the default behavior in many Linux distributions often makes it difficult, if not impossible, to identify the first few boot stages as they proceed, so you’ll probably be able to get a good look only after they’ve completed and you log in.

你能夠識別啓動過程的每個階段對於解決啓動問題和理解整個系統將非常有價值。

然而,許多Linux發行版的默認行為往往使得很難,甚至不可能在啓動過程中識別前幾個階段的進行情況,所以你可能只能在它們完成並且你登錄後才能仔細觀察。

5.1 Startup Messages(啓動信息)

Traditional Unix systems produce many diagnostic messages upon boot that tell you about the boot process. The messages come first from the kernel and then from processes and initialization procedures that init starts. However, these messages aren’t pretty or consistent, and in some cases they aren’t even very informative. Most current Linux distributions do their best to hide them with splash screens, filler, and boot options. In addition, hardware improvements have caused the kernel to start much faster than before; the messages flash by so quickly, it can be difficult to see what is happening.

傳統的Unix系統在啓動時會產生許多診斷消息,告訴你有關啓動過程的信息。

這些消息首先來自內核,然後是由init啓動的進程和初始化過程。

然而,這些消息並不美觀或一致,有些情況下甚至不是很有信息量。

大多數當前的Linux發行版都會盡力隱藏這些消息,使用閃屏、填充物和啓動選項。

此外,硬件的改進使得內核啓動速度比以前快得多;消息閃過得非常快,很難看清楚正在發生什麼。

There are two ways to view the kernel’s boot and runtime diagnostic messages. You can:

有兩種方法可以查看內核的啓動和運行時診斷消息。你可以:

o Look at the kernel system log file. You’ll often find this in /var/log/ kern.log, but depending on how your system is configured, it might also be lumped together with a lot of other system logs in /var/log/messages or elsewhere

o 查看內核系統日誌文件。通常你會在/var/log/kern.log中找到它,但根據系統的配置方式,它也可能與許多其他系統日誌一起存放在/var/log/messages或其他位置。

o Use the dmesg command, but be sure to pipe the output to less because there will be much more than a screen’s worth. The dmesg command uses the kernel ring buffer, which is of limited size, but most newer kernels have a large enough buffer to hold boot messages for a long time.

o 使用dmesg命令,但一定要將輸出導入到less中,因為輸出的內容可能遠遠超過一個屏幕的容量。

dmesg命令使用內核環形緩衝區,它的大小是有限的,但大多數較新的內核都有足夠大的緩衝區來保存啓動消息很長一段時間。

Here’s a sample of what you can expect to see from the dmesg command:

以下是你可以通過dmesg命令看到的示例:

$ dmesg[ 0.000000] Initializing cgroup subsys cpu  
[ 0.000000] Linux version 3.2.0-67-generic-pae (buildd@toyol) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #101-Ubuntu SMP Tue Jul 15 18:04:54 UTC 2014  
(Ubuntu 3.2.0-67.101-generic-pae 3.2.60)  
[ 0.000000] KERNEL supported cpus:  
--snip--  
[ 2.986148] sr0: scsi3-mmc drive: 24x/8x writer dvd-ram cd/rw xa/form2 cdda tray  
[ 2.986153] cdrom: Uniform CD-ROM driver Revision: 3.20  
[ 2.986316] sr 1:0:0:0: Attached scsi CD-ROM sr0  
[ 2.986416] sr 1:0:0:0: Attached scsi generic sg1 type 5  
[ 3.007862] sda: sda1 sda2 < sda5 >  
[ 3.008658] sd 0:0:0:0: [sda] Attached SCSI disk  
--snip--  

After the kernel has started, the user-space startup procedure often generates messages. These messages will likely be more difficult to view and review because on most systems you won’t find them in a single log file. Startup scripts usually print the messages to the console and they’re erased after the boot process finishes. However, this usually isn’t a problem because each script typically writes its own log. Some versions of init, such as Upstart and systemd, can capture diagnostic messages from startup and runtime that would normally go to the console.

內核啓動後,用户空間啓動過程通常會產生信息。

這些信息可能更難查看和審查,因為在大多數系統中,你不會在一個日誌文件中找到它們。

啓動腳本通常會將信息打印到控制枱,並在啓動過程結束後刪除。

不過,這通常不是問題,因為每個腳本通常都會寫入自己的日誌。

某些版本的 init(如 Upstart 和 systemd)可以從啓動和運行時捕獲診斷信息,這些信息通常會傳到控制枱。

5.2 Kernel Initialization and Boot Options(內核初始化和啓動選項)

Upon startup, the Linux kernel initializes in this general order:

在啓動時,Linux內核按照以下一般順序進行初始化:

  1. CPU inspection
  2. Memory inspection
  3. Device bus discovery
  4. Device discovery
  5. Auxiliary kernel subsystem setup (networking, and so on)
  6. Root filesystem mount
  7. User space start
  8. CPU檢查
  9. 內存檢查
  10. 設備總線發現
  11. 設備發現
  12. 輔助內核子系統設置(網絡等)
  13. 掛載根文件系統
  14. 用户空間啓動

The first steps aren’t too remarkable, but when the kernel gets to devices, a question of dependencies arises. For example, the disk device drivers may depend on bus support and SCSI subsystem support

前幾個步驟並不太引人注目,但當內核到達設備時,就會出現依賴性的問題。

例如,磁盤設備驅動程序可能依賴於總線支持和SCSI子系統支持。

Later in the initialization process, the kernel must mount a root file-system before starting init. In general, you won’t have to worry about any of this, except that some necessary components may be loadable kernel modules rather than part of the main kernel. On some machines, you may need to load these kernel modules before the true root filesystem is mounted. We’ll cover this problem and its initial RAM filesystem workaround solutions in 6.8 The Initial RAM Filesystem.

在初始化過程的後期,內核必須在啓動init之前掛載根文件系統。一般情況下,您不必擔心這些問題,只是一些必要的組件可能是可加載的內核模塊,而不是主內核的一部分。在某些機器上,您可能需要在真正的根文件系統掛載之前加載這些內核模塊。我們將在6.8節“初始RAM文件系統”中介紹這個問題及其解決方法。

As of this writing, the kernel does not emit specific messages when it’s about to start its first user process. However, the following memory management messages are a good indication that the user-space handoff is about to happen because this is where the kernel protects its own memory from user-space processes:

截至本文撰寫時,內核在即將啓動其第一個用户進程時不會發出特定的消息。

但是,以下內存管理消息是一個很好的指示,表明即將發生用户空間的切換,因為這是內核保護自己內存免受用户空間進程影響的地方:

Freeing unused kernel memory: 740k freedWrite protecting the kernel text: 5820kWrite protecting the kernel read-only data: 2376kNX-protecting the kernel data: 4420k```  
  
You may also see a message about the root filesystem being mounted at this point.  
  
此時,您可能還會看到一條關於根文件系統已掛載的信息。  
  
> NOTE   
>   
> Feel free to skip ahead to Chapter 6 to learn the specifics of user space start and the init program that the kernel runs as its first process. The remainder of this chapter details how the kernel starts.  
         
> 注意 >   
> 請隨意跳到第 6 章,瞭解用户空間啓動和內核作為第一個進程運行的 init 程序的具體細節。
> 
> 本章其餘部分將詳細介紹內核的啓動方式。  
# 5.3 Kernel Parameters(內核參數)  
  
When running the Linux kernel, the boot loader passes in a set of text-based kernel parameters that tell the kernel how it should start. The parameters specify many different types of behavior, such as the amount of diagnostic output the kernel should produce and device driver–specific options.  
  
在運行Linux內核時,引導加載程序會傳遞一組基於文本的內核參數,告訴內核它應該如何啓動。

這些參數指定了許多不同類型的行為,例如內核應該產生多少診斷輸出以及設備驅動程序特定的選項。  
  
You can view the kernel parameters from your system’s boot by looking at the /proc/cmdline file:  
  
您可以通過查看/proc/cmdline文件來查看系統啓動時的內核參數。  
  

$ cat /proc/cmdlineBOOT_IMAGE=/boot/vmlinuz-3.2.0-67-generic-pae root=UUID=70ccd6e7-6ae6-
44f6-
812c-51aab8036d29 ro quiet splash vt.handoff=7`

The parameters are either simple one-word flags, such as ro and quiet, or key=value pairs, such as vt.handoff=7. Many of the parameters are unimportant, such as the splash flag for displaying a splash screen, but one that is critical is the root parameter. This is the location of the root filesystem; without it, the kernel cannot find init and therefore cannot perform the user space start.

這些參數要麼是簡單的單詞標誌,比如ro和quiet,要麼是鍵值對,比如vt.handoff=7。

其中許多參數都不重要,比如用於顯示啓動畫面的splash標誌,但一個關鍵的參數是root參數。

這是根文件系統的位置;如果沒有它,內核就找不到init,因此無法執行用户空間啓動。

The root filesystem can be specified as a device file, such as in this example:

根文件系統可以指定為設備文件,例如在這個例子中:

root=/dev/sda1  

However, on most modern desktop systems, a UUID is more common (see 4.2.4 Filesystem UUID):

不過,在大多數現代桌面系統中,UUID 更為常見(參見 4.2.4 文件系統 UUID):

root=UUID=70ccd6e7-6ae6-44f6-812c-51aab80  

The ro parameter is normal; it instructs the kernel to mount the root filesystem in read-only mode upon user space start. (Read-only mode ensures that fsck can check the root filesystem safely; after the check, the bootup process remounts the root filesystem in read-write mode.)

ro參數是正常的;它指示內核在用户空間啓動時以只讀模式掛載根文件系統。

(只讀模式確保fsck可以安全地檢查根文件系統;檢查完成後,啓動過程會將根文件系統重新掛載為讀寫模式。)

Upon encountering a parameter that it does not understand, the Linux kernel saves the parameter. The kernel later passes the parameter to init when performing the user space start. For example, if you add -s to the kernel parameters, the kernel passes the -s to the init program to indicate that it should start in single-user mode.

當遇到無法理解的參數時,Linux內核會保存該參數。內核在執行用户空間啓動時會將該參數傳遞給init。例如,如果您添加了-s到內核參數中,內核會將-s傳遞給init程序,表示應該以單用户模式啓動。

Now let’s look at the mechanics of how boot loaders start the kernel.

現在讓我們來看看引導加載程序如何啓動內核的機制。

5.4 Boot Loaders (引導加載器 )

At the start of the boot process, before the kernel and init start, a boot loader starts the kernel. The task of a boot loader sounds simple: It loads the kernel into memory, and then starts the kernel with a set of kernel parameters. But consider the questions that the boot loader must answer:

在啓動過程的開始階段,在內核和init啓動之前,引導加載程序會啓動內核。

引導加載程序的任務聽起來很簡單:它將內核加載到內存中,然後使用一組內核參數啓動內核。

但是請考慮引導加載程序必須回答的問題:

o Where is the kernel?
o What kernel parameters should be passed to the kernel when it starts?

  • 內核在哪裏?
  • 內核啓動時應傳遞哪些內核參數?

The answers are (typically) that the kernel and its parameters are usually somewhere on the root filesystem. It sounds like the kernel parameters should be easy to find, except that the kernel is not yet running, so it can’t traverse a filesystem to find the necessary files. Worse, the kernel device drivers normally used to access the disk are also unavailable. Think of this as a kind of “chicken or egg” problem

答案(通常)是內核及其參數通常位於根文件系統的某個位置。

內核參數似乎應該很容易找到,但是由於內核尚未運行,因此無法遍歷文件系統以找到必要的文件。更糟糕的是,通常用於訪問磁盤的內核設備驅動程序也不可用。

可以將其視為一種“先有雞還是先有蛋”的問題。

Let’s start with the driver concern. On PCs, boot loaders use the Basic Input/Output System (BIOS) or Unified Extensible Firmware Interface (UEFI) to access disks. Nearly all disk hardware has firmware that allows the BIOS to access attached storage hardware with Linear Block Addressing (LBA). Although it exhibits poor performance, this mode of access does allow universal access to disks. Boot loaders are often the only programs to use the BIOS for disk access; the kernel uses its own high-performance drivers.

讓我們從驅動程序的問題開始。

在個人電腦上,引導加載程序使用基本輸入/輸出系統(BIOS)或統一可擴展固件接口(UEFI)來訪問磁盤。

幾乎所有磁盤硬件都有固件,允許BIOS使用線性塊尋址(LBA)來訪問連接的存儲硬件。

儘管性能較差,但這種訪問模式確實允許對磁盤進行通用訪問。

引導加載程序通常是唯一使用BIOS進行磁盤訪問的程序;內核使用自己的高性能驅動程序。

The filesystem question is trickier. Most modern boot loaders can read partition tables and have built-in support for read-only access to filesystems. Thus, they can find and read files. This capability makes it far easier to dynamically configure and enhance the boot loader. Linux boot loaders have not always had this capability; without it, configuring the boot loader was more difficult.

文件系統的問題更加棘手。大多數現代引導加載程序可以讀取分區表,並具有對文件系統的只讀訪問的內置支持。

因此,它們可以找到並讀取文件。這種能力使得動態配置和增強引導加載程序變得更加容易。Linux引導加載程序並不總是具備這種能力;在沒有這種能力的情況下,配置引導加載程序更加困難。

5.4.1 Boot Loader Tasks (引導加載器任務 )

A Linux boot loader’s core functionality includes the ability to do the following:

o Select among multiple kernels.
o Switch between sets of kernel parameters.
o Allow the user to manually override and edit kernel image names and parameters (for example, to enter single-user mode).
o Provide support for booting other operating systems.

Boot loaders have become considerably more advanced since the inception of the Linux kernel, with features such as history and menu systems, but the basic need has always been flexibility in kernel image and parameter selection. One interesting phenomenon is that certain needs have diminished. For example, because you can now perform an emergency or recovery boot partially or entirely from a USB storage device, you probably won’t have to worry about manually entering kernel parameters or going into single-user mode. But modern boot loaders offer more power than ever, which can be particularly handy if you’re building custom kernels or just want to tweak parameters.

Linux引導加載程序的核心功能包括以下幾點:

o 在多個內核之間進行選擇。
o 在不同的內核參數集之間切換。
o 允許用户手動覆蓋和編輯內核映像的名稱和參數(例如,進入單用户模式)。
o 提供引導其他操作系統的支持。

自Linux內核誕生以來,引導加載程序已經變得更加先進,具備了諸如歷史記錄和菜單系統等功能,但基本需求始終是靈活選擇內核映像和參數。有一個有趣的現象是,某些需求已經減少。例如,由於現在可以部分或完全從USB存儲設備進行緊急或恢復引導,您可能不再需要擔心手動輸入內核參數或進入單用户模式。但現代引導加載程序提供了比以往更強大的功能,這對於構建自定義內核或只是想調整參數的用户來説尤為方便。

5.4.2 Boot Loader Overview (引導加載器概述 )

Here are the main boot loaders that you may encounter, in order of popularity:

以下是您可能會遇到的主要引導加載程序,按受歡迎程度排序:

o GRUB. A near-universal standard on Linux systems
o LILO. One of the first Linux boot loaders. ELILO is a UEFI version
o SYSLINUX. Can be configured to run from many different kinds of filesystems
o LOADLIN. Boots a kernel from MS-DOS
o efilinux. A UEFI boot loader intended to serve as a model and reference for other UEFI boot loaders
o coreboot (formerly LinuxBIOS). A high-performance replacement for the PC BIOS that can include a kernel o Linux Kernel EFISTUB. A kernel plugin for loading the kernel directly from the EFI/UEFI System Partition (ESP) found on recent systems

o GRUB。在Linux系統上幾乎是標準配置
o LILO。最早的Linux引導加載程序之一。ELILO是UEFI版本
o SYSLINUX。可以配置為從許多不同類型的文件系統中運行
o LOADLIN。從MS-DOS引導內核
o efilinux。一種UEFI引導加載程序,旨在為其他UEFI引導加載程序提供模型和參考
o coreboot(以前稱為LinuxBIOS)。用於替代PC BIOS的高性能版本,可以包含內核
o Linux Kernel EFISTUB。用於從最新系統上的EFI/UEFI系統分區(ESP)直接加載內核的內核插件

This book deals exclusively with GRUB. The rationale behind using other boot loaders is either that they are simpler to configure than GRUB or that they are faster.

本書僅涉及GRUB。使用其他引導加載程序的理由要麼是它們比GRUB更簡單配置,要麼是它們更快。

To enter a kernel name and parameters, you first need to know how to get to a boot prompt. Unfortunately, this can sometimes be difficult to figure out because Linux distributions customize boot loader behavior and appearance to their hearts’ content.

要輸入內核名稱和參數,您首先需要知道如何進入引導提示符。不幸的是,有時候這可能很難弄清楚,因為Linux發行版會根據自己的喜好自定義引導加載程序的行為和外觀。

The next sections tell you how to get to a boot prompt in order to enter a kernel name and parameters. Once you’re comfortable with that, you’ll see how to configure and install a boot loader.

接下來的幾節將告訴您如何進入引導提示符以輸入內核名稱和參數。一旦您熟悉了這一點,您將看到如何配置和安裝引導加載程序。

5.5 GRUB Introduction(GRUB 簡介 )

GRUB stands for Grand Unified Boot Loader. We’ll cover GRUB 2; there is also an older version now called GRUB Legacy that is slowing falling out of use.

GRUB 是 Grand Unified Boot Loader 的縮寫。我們將介紹 GRUB 2;還有一箇舊版本,現在稱為 GRUB Legacy,正在逐漸被淘汰。

One of GRUB’s most important capabilities is filesystem navigation that allows for much easier kernel image and configuration selection. One of the best ways to see this in action and to learn about GRUB in general is to look at its menu. The interface is easy to navigate, but there’s a good chance that you’ve never seen it. Linux distributions often do their best to hide the boot loader from you.

GRUB 最重要的功能之一是文件系統導航,可以更方便地選擇內核映像和配置。查看 GRUB 菜單是瞭解 GRUB 功能的最佳方式之一。界面很容易瀏覽,但你很可能從未見過它。Linux 發行版通常會盡力向你隱藏引導加載器。

To access the GRUB menu, press and hold SHIFT when your BIOS or firmware startup screen first appears. Otherwise, the boot loader configuration may not pause before loading the kernel. Figure 5-1 shows the GRUB menu. Press ESC to temporarily disable the automatic boot timeout after the GRUB menu appears

要訪問 GRUB 菜單,請在 BIOS 或固件啓動屏幕首次出現時按住 SHIFT。否則,引導加載器配置可能不會在加載內核前暫停。圖 5-1 顯示了 GRUB 菜單。出現 GRUB 菜單後,按 ESC 鍵可暫時禁用自動啓動超時功能

image.png

Figure 5-1. GRUB menu

圖5-1. GRUB 菜單

Try the following to explore the boot loader:

嘗試以下步驟來探索引導加載程序:

  1. Reboot or power on your Linux system.
  2. Hold down SHIFT during the BIOS/Firmware self-test and/or splash screen to get the GRUB menu.
  3. Press e to view the boot loader configuration commands for the default boot option. You should see something like Figure 5-2.
  4. 重新啓動或開機您的 Linux 系統。
  5. 在 BIOS/固件自檢和/或啓動畫面期間按住 SHIFT 鍵,以獲取 GRUB 菜單。
  6. 按下 e 鍵查看默認引導選項的引導加載程序配置命令。您應該會看到類似於圖5-2的內容。

image.png

Figure 5-2. GRUB configuration editor

圖5-2. GRUB配置編輯器

This screen tells us that for this configuration, the root is set with a UUID, the kernel image is /boot/vmlinuz3.2.0-31-generic-pae, and the kernel parameters include ro, quiet, and splash. The initial RAM filesystem is /boot/initrd.img-3.2.0-31-generic-pae. But if you’ve never seen this sort of configuration before, you may find it somewhat confusing. Why are there multiple references to root, and why are they different? Why is insmod here? Isn’t that a Linux kernel feature normally run by udevd?

這個界面告訴我們,對於這個配置,根目錄使用了一個UUID,內核映像文件是/boot/vmlinuz-3.2.0-31-generic-pae,內核參數包括ro、quiet和splash。初始RAM文件系統是/boot/initrd.img-3.2.0-31-generic-pae。但是如果你以前從未見過這種配置,可能會感到有些困惑。為什麼有多個對根目錄的引用,而且它們為什麼不同?為什麼這裏有insmod命令?那不是udev守護進程通常運行的Linux內核特性嗎?

The double-takes are warranted, because GRUB doesn’t really use the Linux kernel—it starts it. The configuration you see consists wholly of GRUB internal commands. GRUB really is an entirely separate world. The confusion stems from the fact that GRUB borrows terminology from many sources. GRUB has its own “kernel” and its own insmod command to dynamically load GRUB modules, completely independent of the Linux kernel. Many GRUB commands are similar to Unix shell commands; there’s even an ls command to list files.

這種困惑是正常的,因為GRUB並不真正使用Linux內核,而是啓動它。你看到的配置完全由GRUB內部命令組成。GRUB實際上是一個完全獨立的世界。困惑的原因在於GRUB借用了許多來源的術語。GRUB有自己的“內核”和自己的insmod命令,用於動態加載GRUB模塊,完全獨立於Linux內核。許多GRUB命令類似於Unix shell命令;甚至有一個ls命令用於列出文件。

But the most confusion comes from the use of the word root. To clear it up, there is one simple rule to follow when you’re looking for your system’s root filesystem: Only the root kernel parameter will be the root filesystem when you boot your system.

但是最令人困惑的是對於root這個詞的使用。為了澄清這一點,在尋找系統的根文件系統時,只有root內核參數在系統啓動時才是根文件系統。

In the GRUB configuration, that kernel parameter is somewhere after the image name of the linux command. Every other reference to root in the configuration is to the GRUB root, which exists only inside of GRUB. The GRUB “root” is the filesystem where GRUB searches for kernel and RAM filesystem image files. In Figure 5-2, the GRUB root is first set to a GRUB-specific device (hd0,msdos1). Then in the following command, GRUB searches for a particular UUID on a partition. If it finds that UUID, it sets the GRUB root to that partition.

在GRUB配置中,該內核參數位於linux命令的映像名稱之後。配置中對root的其他引用都是指GRUB的root,它僅存在於GRUB內部。GRUB的“root”是GRUB用於搜索內核和RAM文件系統映像文件的文件系統。在圖5-2中,GRUB的root首先設置為一個GRUB特定的設備(hd0,msdos1)。然後在隨後的命令中,GRUB在一個分區上搜索特定的UUID。如果找到該UUID,它將把GRUB的root設置為該分區。

To wrap things up, the linux command’s first argument (/boot/vmlinuz-...) is the location of the Linux kernel image file. GRUB loads this file from the GRUB root. The initrd command is similar, specifying the file for the initial RAM filesystem

總結一下,linux命令的第一個參數(/boot/vmlinuz-...)是Linux內核映像文件的位置。GRUB從GRUB的root加載此文件。initrd命令類似,指定初始RAM文件系統的文件。

You can edit this configuration inside GRUB; doing so is usually the easiest way to temporarily fix an erroneous boot. To permanently fix a boot problem, you’ll need to change the configuration (see 5.5.2 GRUB Configuration), but for now, let’s go one step deeper and examine some GRUB internals with the commandline interface.

你可以在GRUB中編輯這個配置;這通常是暫時修復錯誤引導的最簡單的方法。要永久修復引導問題,你需要更改配置(參見5.5.2 GRUB配置),但現在,讓我們更深入地使用命令行界面來查看一些GRUB內部信息。

5.5.1 Exploring Devices and Partitions with the GRUB Command Line (使用 GRUB 命令行探索設備和分區 )

As you can see in Figure 5-2, GRUB has its own device-addressing scheme. For example, the first hard disk found is hd0, followed by hd1, and so on. But device assignments are subject to change. Fortunately, GRUB can search all partitions for a UUID in order to find the one where the kernel resides, as you just saw with the search command.

正如您在圖5-2中所看到的,GRUB有自己的設備尋址方案。

例如,找到的第一個硬盤是hd0,接着是hd1,依此類推。但是設備分配可能會發生變化。

幸運的是,GRUB可以搜索所有分區的UUID,以找到內核所在的分區,就像您剛才用search命令看到的那樣。

Listing Devices (列表設備)

To get a feel for how GRUB refers to the devices on your system, access the GRUB command line by pressing C at the boot menu or configuration editor. You should get the GRUB prompt:

為了瞭解GRUB如何引用您系統上的設備,請通過在啓動菜單或配置編輯器中按下C鍵來訪問GRUB命令行。您應該會看到GRUB提示符:

grub>  

You can enter any command here that you see in a configuration, but to get started, try a diagnostic command instead: ls. With no arguments, the output is a list of devices known to GRUB:

您可以在這裏輸入任何您在配置中看到的命令,但是為了開始,請嘗試使用診斷命令代替:ls。

如果沒有參數,輸出將是一個已知於GRUB的設備列表:

grub> ls (hd0) (hd0,msdos1) (hd0,msdos5)  

In this case, there is one main disk device denoted by (hd0) and the partitions (hd0,msdos1) and (hd0,msdos5). The msdos prefix on the partitions tells you that the disk contains an MBR partition table; it would begin with gpt for GPT. (You will find even deeper combinations with a third identifier, where a BSD disklabel map resides inside a partition, but you won’t normally have to worry about this unless you’re running multiple operating systems on one machine.)

在本例中,有一個以 (hd0) 表示的主磁盤設備,以及 (hd0,msdos1) 和 (hd0,msdos5) 分區。分區上的 msdos 前綴表示磁盤包含 MBR 分區表;GPT 則以 gpt 開頭。(你會發現帶有第三個標識符的更深層次的組合,即 BSD 磁盤標籤映射位於分區內部,但除非你在一台機器上運行多個操作系統,否則通常不必擔心這個問題)。

To get more detailed information, use ls -l. This command can be particularly useful because it displays any UUIDs of the partitions on the disk. For example:

要獲取更詳細的信息,請使用 ls -l。該命令特別有用,因為它會顯示磁盤上分區的 UUID。例如

grub> ls -l  
Device hd0: Not a known filesystem - Total size 426743808 sectors Partition hd0,msdos1: Filesystem type ext2 – Last modification time  
 2015-09-18 20:45:00 Friday, UUID 4898e145-b064-45bd-b7b4-7326b00273b7 -Partition start at 2048 - Total size 424644608 sectors Partition hd0,msdos5: Not a known filesystem - Partition start at 424648704 - Total size 2093056 sectors```  
  
This particular disk has a Linux ext2/3/4 filesystem on the first MBR partition and a Linux swap signature on partition 5, which is a fairly common configuration. (You can’t tell that (hd0,msdos5) is a swap partition from this output, though.)  
  
該磁盤的第一個 MBR 分區上有 Linux ext2/3/4 文件系統,第 5 分區上有 Linux swap 簽名,這是一種相當常見的配置。(不過,從輸出結果中看不出 (hd0,msdos5) 是交換分區)。  
  
### File Navigation  
  
Now let’s look at GRUB’s filesystem navigation capabilities. Determine the GRUB root with the echo command (recall that this is where GRUB expects to find the kernel):  
  
現在讓我們看看 GRUB 的文件系統導航功能。使用 echo 命令確定 GRUB 根目錄(請記住,這是 GRUB 希望找到內核的位置):  
  
  

grub> echo $root
hd0,msdos1

  
To use GRUB’s ls command to list the files and directories in that root, you can append a forward slash to the end of the partition:  
  
要使用 GRUB 的 ls 命令列出根目錄下的文件和目錄,可以在分區末尾添加一個斜線:  
  

grub> ls (hd0,msdos1)/

  
But it’s a pain to remember and type the actual root partition, so use the root variable to save yourself some time:  
  
但記住並鍵入實際的 root 分區很麻煩,所以使用 root 變量可以節省時間:  
  

grub> ls ($root)/

  
The output is a short list of file and directory names on that partition’s filesystem, such as etc/, bin/, and dev/. You should realize that this is now a completely different function of the GRUB ls: Before, you were listing devices, partition tables, and perhaps some filesystem header information. Now you’re actually looking at the contents of filesystems.  
  
You can take a deeper look into the files and directories on a partition in a similar manner. For example, to inspect the /boot directory, start with the following:  
  
輸出結果:  
  
輸出的是該分區文件系統上的文件和目錄名稱的簡短列表,例如etc/,bin/和dev/。  
  
您應該意識到,這是GRUB ls的完全不同的功能:之前,您是在列出設備、分區表,以及可能的一些文件系統頭信息。現在,您實際上正在查看文件系統的內容。  
  
您可以以類似的方式更深入地查看分區上的文件和目錄。例如,要檢查/boot目錄,請從以下內容開始:  
  

grub> ls ($root)/boot

  
> NOTE Use the up and down arrow keys to flip through GRUB command history and the left and right arrows to edit the current command line. The standard readline keys (CTRL-N, CTRL-P, and so on) also work.  
>   
> 注意:使用上下箭頭鍵來翻閲GRUB命令歷史記錄,使用左右箭頭鍵來編輯當前命令行。標準的readline鍵(CTRL-N、CTRL-P等)也可以使用。  
  
You can also view all currently set GRUB variables with the set command:  
  
您還可以使用set命令查看當前設置的所有GRUB變量。  
  

grub> set
?=0
color_highlight=black/white
color_normal=white/black
--snip--
prefix=(hd0,msdos1)/boot/grub
root=hd0,msdos1

  
One of the most important of these variables is $prefix, the filesystem and directory where GRUB expects to find its configuration and auxiliary support. We’ll explore this in the next section.  
  
其中最重要的變量之一是$prefix,它是GRUB期望找到其配置和輔助支持的文件系統和目錄。我們將在下一節中探討這個問題。  
  
Once you’ve finished with the GRUB command-line interface, enter the boot command to boot your current configuration or just press ESC to return to the GRUB menu. In any case, boot your system; we’re going to explore the GRUB configuration, and that’s best done when you have your full system available.  
  
  
一旦你完成了GRUB命令行界面的操作,輸入boot命令來啓動當前的配置,或者按ESC鍵返回到GRUB菜單。無論哪種情況,都要啓動你的系統;我們將要探索GRUB配置,而在你擁有完整的系統時進行這個操作是最好的。  
## 5.5.2 GRUB Configuration (GRUB 配置  )
  
The GRUB configuration directory contains the central configuration file (grub.cfg) and numerous loadable modules with a .mod suffix. (As GRUB versions progress, these modules will move into subdirectories such as i386-pc.) The directory is usually /boot/grub or /boot/grub2. We won’t modify grub.cfg directly; instead, we’ll use the grub-mkconfig command (or grub2-mkconfig on Fedora).  
  
  
GRUB 配置目錄包含中央配置文件 (grub.cfg) 和許多後綴為 .mod 的可加載模塊。  
  
(隨着 GRUB 版本的更新,這些模塊將移至 i386-pc 等子目錄)。  
  
該目錄通常為 /boot/grub 或 /boot/grub2。我們不會直接修改 grub.cfg,而是使用 grub-mkconfig 命令(或 Fedora 上的 grub2-mkconfig)。  
### Reviewing Grub.cfg (查看 Grub.cfg  )
  
First, take a quick look at grub.cfg to see how GRUB initializes its menu and kernel options. You’ll see that the grub.cfg file consists of GRUB commands, which usually begin with a number of initialization steps followed by a series of menu entries for different kernel and boot configurations. The initialization isn’t complicated; it’s a bunch of function definitions and video setup commands like this:  
  
首先,快速查看grub.cfg文件,瞭解GRUB如何初始化其菜單和內核選項。  
  
您會發現grub.cfg文件由一系列GRUB命令組成,通常以一系列初始化步驟開始,然後是一系列不同內核和引導配置的菜單條目。  
  
初始化過程並不複雜;它包括一些函數定義和視頻設置命令,例如:  
  

if loadfont /usr/share/grub/unicode.pf2 ; then
set gfxmode=auto load_video insmod gfxterm --snip--

  
Later in this file you should see the available boot configurations, each beginning with the menuentry command. You should be able to read and understand this example based on what you learned in the preceding section:  
  
在本文件的稍後部分,您將看到可用的啓動配置,每個配置都以 menuentry 命令開頭。根據上一節所學內容,您應該能夠閲讀並理解本示例:  
  

menuentry 'Ubuntu, with Linux 3.2.0-34-generic-pae' --class ubuntu --class gnu-linux --class gnu--class os { recordfail
gfxmode $linux_gfx_mode insmod gzio insmod part_msdos insmod ext2 set root='(hd0,msdos1)' search --no-floppy --fs-uuid --set=root 70ccd6e7-6ae6-44f6-812c51aab8036d29 linux /boot/vmlinuz-3.2.0-34-generic-pae root=UUID=70ccd6e7-6ae6-44f6-812c-51aab8036d29
ro quiet splash $vt_handoff initrd /boot/initrd.img-3.2.0-34-generic-pae}

  
Watch for submenu commands. If your grub.cfg file contains numerous menuentry commands, most of them are probably wrapped up inside a submenu command for older versions of the kernel so that they don’t crowd the GRUB menu.  
  
請注意子菜單命令。如果您的grub.cfg文件包含大量的menuentry命令,其中大部分可能被包裹在一個子菜單命令中,用於舊版本的內核,以避免擁擠GRUB菜單。  
  
### Generating a New Configuration File ( 生成新配置文件 )
  
If you want to make changes to your GRUB configuration, you won’t edit your grub.cfg file directly because it’s automatically generated and the system occasionally overwrites it. You’ll add your new configuration elsewhere, then run grub-mkconfig to generate the new configuration.  
  
如果您想對GRUB配置進行更改,不要直接編輯grub.cfg文件,因為它是自動生成的,系統有時會覆蓋它。您可以在其他地方添加新的配置,然後運行grub-mkconfig來生成新的配置。  
  
To see how the configuration generation works, look at the very beginning of grub.cfg. There should be comment lines such as this:  
  
  
要了解配置生成的工作原理,請查看grub.cfg的開頭部分。應該有類似以下的註釋行:  
  

BEGIN /etc/grub.d/00_header

  
Upon further inspection, you’ll find that every file in /etc/grub.d is a shell script that produces a piece of the grub.cfg file. The grub-mkconfig command itself is a shell script that runs everything in /etc/grub.d.  
  
經過進一步檢查,您會發現`/etc/grub.d`目錄中的每個文件都是一個Shell腳本,用於生成`grub.cfg`文件的一部分。`grub-mkconfig`命令本身也是一個Shell腳本,運行`/etc/grub.d`目錄中的所有內容。  
  
Try it yourself as root. (Don’t worry about overwriting your current configuration. This command by itself simply prints the configuration to the standard output.)  
  
作為root用户,您可以嘗試一下。(不用擔心覆蓋當前配置。這個命令只會將配置信息打印到標準輸出。)  
  

grub-mkconfig

  
The long answer is a little more complicated. The /etc/grub.d configuration directory gives you two options: 40_custom and 41_custom. The first, 40_custom, is a script that you can edit yourself, but it’s probably the least stable; a package upgrade is likely to destroy any changes you make. The 41_custom script is simpler; it’s just a series of commands that load custom.cfg when GRUB starts. (Keep in mind that if you choose this second option, your changes won’t appear when you generate your configuration file.)  
  
The two options for custom configuration files aren’t particularly extensive. You’ll see additions in your particular distribution’s /etc/grub.d directory. For example, Ubuntu adds memory tester boot options (memtest86+) to the configuration.  
  
To write and install a newly generated GRUB configuration file, you can write the configuration to your GRUB directory with the -o option to grub-mkconfig, like this:  
  
長答案稍微複雜一些。/etc/grub.d配置目錄提供了兩個選項:40_custom和41_custom。第一個選項40_custom是一個你可以自己編輯的腳本,但它可能是最不穩定的;升級軟件包可能會破壞你所做的任何更改。41_custom腳本更簡單;它只是一系列在GRUB啓動時加載custom.cfg的命令。(請記住,如果選擇第二個選項,生成配置文件時你的更改將不會顯示。)  
  
自定義配置文件的兩個選項並不是特別廣泛。你會在你特定的發行版的/etc/grub.d目錄中看到添加的內容。例如,Ubuntu在配置中添加了內存測試程序的啓動選項(memtest86+)。  
  
要編寫和安裝新生成的GRUB配置文件,你可以使用grub-mkconfig命令的-o選項將配置寫入你的GRUB目錄,像這樣:  
  

grub-mkconfig -o /boot/grub/grub.cfg

  
Or if you’re an Ubuntu user, just run install-grub. In any case, back up your old configuration, make sure that you’re installing to the correct directory, and so on.  
  
Now we’re going to get into some of the more technical details of GRUB and boot loaders. If you’re tired of hearing about boot loaders and the kernel, feel free to skip to Chapter 6.  
  
如果你是一個Ubuntu用户,只需運行install-grub命令。無論如何,請備份您的舊配置,確保您安裝到了正確的目錄等等。  
  
現在我們將進入一些關於GRUB和引導加載程序的更多技術細節。如果你厭倦了聽關於引導加載程序和內核的內容,可以跳到第6章。  
## 5.5.3 GRUB Installation (GRUB 安裝  )
  
Installing GRUB is more involved than configuring it. Fortunately, you won’t normally have to worry about installation because your distribution should handle it for you. However, if you’re trying to duplicate or restore a bootable disk, or preparing your own boot sequence, you might need to install it on your own  


安裝GRUB比配置它更復雜。幸運的是,通常情況下,您不必擔心安裝問題,因為您的發行版應該會為您處理。然而,如果您想要複製或恢復可引導的磁盤,或者準備自己的引導順序,您可能需要自己安裝它。  
  
Before proceeding, read 5.8.3 How GRUB Works to get an idea of how PCs boot and determine whether you’re using MBR or EFI boot. Next, build the GRUB software set and determine where your GRUB directory will be; the default is /boot/grub. You may not need to build GRUB if your distribution does it for you, but if you do, see Chapter 16 for how to build software from source code. Make sure that you build the correct target: It’s different for MBR or UEFI boot (and there are even differences between 32-bit and 64-bit EFI).  
  
  
在繼續之前,請閲讀5.8.3 GRUB的工作原理,瞭解個人電腦的引導方式,並確定您是使用MBR還是EFI引導。

接下來,構建GRUB軟件集,並確定您的GRUB目錄位置;默認位置是/boot/grub。如果您的發行版已經為您構建了GRUB,您可能不需要自己構建,但如果需要,請參考第16章中的如何從源代碼構建軟件的方法。

確保構建正確的目標:MBR引導和UEFI引導是不同的(甚至32位和64位EFI之間也有區別)。  
  
#### Installing GRUB on Your System ( 在系統上安裝 GRUB)
  
Installing the boot loader requires that you or an installer determine the following:  
  
安裝引導加載程序需要您或安裝程序確定以下內容:  
  
o The target GRUB directory as seen by your currently running system. That’s usually /boot/grub, but it might be different if you’re installing GRUB on another disk for use on another system.  
o The current device of the GRUB target disk.  
o For UEFI booting, the current mount point of the UEFI boot partition  
  
o 目標 GRUB 目錄,由您當前正在運行的系統所看到。通常是 /boot/grub,但如果您要在另一個磁盤上安裝 GRUB 以供另一個系統使用,則可能會有所不同。  
o GRUB 目標磁盤的當前設備。  
o 對於 UEFI 引導,UEFI 引導分區的當前掛載點。  
  
Remember that GRUB is a modular system, but in order to load modules, it must read the filesystem that contains the GRUB directory. Your task is to construct a version of GRUB capable of reading that filesystem so that it can load the rest of its configuration (grub.cfg) and any required modules. On Linux, this usually means building a version of GRUB with its ext2.mod module preloaded. Once you have this version, all you need to do is place it on the bootable part of the disk and place the rest of the required files into /boot/grub.  
  
請記住,GRUB 是一個模塊化的系統,但為了加載模塊,它必須讀取包含 GRUB 目錄的文件系統。

您的任務是構建一個能夠讀取該文件系統的 GRUB 版本,以便它可以加載其餘的配置文件(grub.cfg)和任何所需的模塊。

在 Linux 上,這通常意味着構建一個預加載了 ext2.mod 模塊的 GRUB 版本。

一旦您擁有了這個版本,您只需要將它放置在可引導的磁盤上,並將其餘所需文件放置在 /boot/grub 目錄中。  
  
Fortunately, GRUB comes with a utility called grub-install (not to be confused with Ubuntu’s install-grub), which performs most of the work of installing the GRUB files and configuration for you. For example, if your current disk is at /dev/sda and you want to install GRUB on that disk with your current /boot/grub directory, use this command to install GRUB on the MBR:  
  
幸運的是,GRUB 自帶一個名為 grub-install 的實用程序(不要與 Ubuntu 的 install-grub 混淆),它可以為您執行大部分安裝 GRUB 文件和配置的工作。

例如,如果您當前的磁盤位於 /dev/sda,並且您想要將 GRUB 安裝在該磁盤上,使用當前的 /boot/grub 目錄,可以使用以下命令在 MBR 上安裝 GRUB:  
  

grub-install /dev/sda

  
> WARNING   
> Incorrectly installing GRUB may break the bootup sequence on your system, so don’t take this command lightly. If you’re concerned, read up on how to back up your MBR with dd, back up any other currently installed GRUB directory, and make sure that you have an emergency bootup plan.  
>   
> 警告 > 錯誤安裝 GRUB 可能會破壞系統的啓動順序,因此不要輕易執行此命令。
> 
> 如果擔心,請閲讀如何使用 dd 備份 MBR,備份當前安裝的任何其他 GRUB 目錄,並確保有一個緊急啓動計劃。  
  
### Installing GRUB on an External Storage Device (在外部存儲設備上安裝 GRUB  )
  
To install GRUB on a storage device outside the current system, you must manually specify the GRUB directory on that device as your current system now sees it. For example, say that you have a target device of /dev/sdc and that device’s root/boot filesystem (for example, /dev/sdc1) is mounted on /mnt of your current system. This implies that when you install GRUB, your current system will see the GRUB files in /mnt/boot/grub. When running grub-install, tell it where those files should go as follows:  
  
要在當前系統外的存儲設備上安裝GRUB,您必須手動指定該設備上的GRUB目錄,以便您的當前系統能夠看到它。  
  
例如,假設您的目標設備是/dev/sdc,並且該設備的根/引導文件系統(例如,/dev/sdc1)被掛載在當前系統的/mnt目錄下。  
  
這意味着當您安裝GRUB時,您的當前系統將在/mnt/boot/grub中看到GRUB文件。  
  
在運行grub-install時,告訴它這些文件應該放在哪裏,如下所示:  
  

grub-install --boot-directory=/mnt/boot /dev/sdc

  
### Installing GRUB with UEFI (使用 UEFI 安裝 GRUB  )
  
UEFI installation is supposed to be easier, because you all you need to do is copy the boot loader into place. But you also need to “announce” the boot loader to the firmware with the efibootmgr command. The grub-install command runs this if it’s available, so in theory all you need to do to install on an UEFI partition is the following:  
  
UEFI安裝應該更加簡單,因為你只需要將引導加載程序複製到正確的位置即可。  
  
但是你還需要使用efibootmgr命令將引導加載程序“通知”給固件。  
  
如果可用,grub-install命令會自動運行此操作,所以理論上,你只需要執行以下步驟即可在UEFI分區上進行安裝:  
  

grub-install --efi-directory=efi_dir –-bootloader-id=name

  
  
Here, efi_dir is where the UEFI directory appears on your current system (usually /boot/efi/efi, because the UEFI partition is often mounted at /boot/efi) and name is an identifier for the boot loader, as described in 5.8.2 UEFI Boot  
  
在這裏,efi_dir是UEFI目錄在您當前系統上的位置(通常是/boot/efi/efi,因為UEFI分區通常被掛載在/boot/efi上),name是引導加載程序的標識符,如5.8.2 UEFI引導中所述。  
  
Unfortunately, many problems can crop up when installing a UEFI boot loader. For example, if you’re installing to a disk that will eventually end up in another system, you have to figure out how to announce that boot loader to the new system’s firmware. And there are differences in the install procedure for removable media.  
  
不幸的是,在安裝UEFI引導加載程序時可能會出現許多問題。  
  
例如,如果您要安裝到最終會進入另一個系統的磁盤上,您必須找出如何向新系統的固件通告該引導加載程序。  
  
而且,可移動介質的安裝過程也有所不同。  
  
But one of the biggest problems is UEFI secure boot.  
  
但是,其中最大的問題之一就是UEFI安全啓動。  
# 5.6 UEFI Secure Boot Problems (UEFI 安全啓動問題  )
  
One of the newest problems affecting Linux installations is the secure boot feature found on recent PCs. When active, this mechanism in UEFI requires boot loaders to be digitally signed by a trusted authority in order to run. Microsoft has required vendors shipping Windows 8 to use secure boot. The result is that if you try to install an unsigned boot loader (which is most current Linux distributions), it will not load.  
  
最新影響Linux安裝的問題之一是最近PC上出現的安全啓動功能。當激活時,UEFI中的這種機制要求引導加載程序必須由可信任的機構進行數字簽名才能運行。微軟要求出貨的Windows 8設備使用安全啓動。結果就是,如果你嘗試安裝未經簽名的引導加載程序(大多數當前的Linux發行版都是如此),它將無法加載。  
  
The easiest way around this for anyone with no interest in Windows is to disable secure boot in the EFI settings. However, this won’t work cleanly for dual-boot systems and may not be an option for all users. Therefore, Linux distributions are offering signed boot loaders. Some solutions are just front-ends to GRUB, some offer a fully signed loading sequence (from the boot loader to the kernel), and others are entirely new boot loaders (some based on efilinux).  
  
對於那些對Windows沒有興趣的用户來説,最簡單的方法是在EFI設置中禁用安全啓動。

然而,這對於雙啓動系統來説可能不太方便,並且可能並非所有用户的選擇。

因此,Linux發行版提供了經過簽名的引導加載程序。有些解決方案只是GRUB的前端,有些提供了完全經過簽名的加載順序(從引導加載程序到內核),還有一些是全新的引導加載程序(一些基於efilinux)。  
  
# 5.7 Chainloading Other Operating Systems(鏈載其他操作系統  )
  
UEFI makes it relatively easy to support loading other operating systems because you can install multiple boot loaders in the EFI partition. However, the older MBR style doesn’t support it, and even if you do have UEFI, you may still have an individual partition with an MBR-style boot loader that you want to use. You can get GRUB to load and run a different boot loader on a specific partition on your disk by chainloading  
  
UEFI使得支持加載其他操作系統相對容易,因為你可以在EFI分區中安裝多個引導加載程序。

然而,舊的MBR樣式不支持此功能,即使你有UEFI,你可能仍然有一個使用MBR樣式引導加載程序的單獨分區,你想要使用它。

通過鏈式加載,你可以讓GRUB在磁盤上的特定分區上加載和運行不同的引導加載程序。  
  
To chainload, create a new menu entry in your GRUB configuration (using one of the methods in Reviewing Grub.cfg). Here’s an example for a Windows installation on the third partition of a disk:  
  
要進行鏈式加載,可以在GRUB配置中創建一個新的菜單項(使用“Reviewing Grub.cfg”中的方法之一)。以下是一個示例,用於在磁盤的第三個分區上安裝Windows:  
  

menuentry "Windows" { insmod chain insmod ntfs set root=(hd0,3) chainloader +1}

  
The +1 option to chainloader tells it to load whatever is at the first sector of a partition. You can also get it to directly load a file by using a line like this to load the io.sys MS-DOS loader:  
  
chainloader 的 +1 選項會告訴它加載分區第一個扇區的任何內容。你也可以用這樣一行來加載 io.sys MS-DOS 加載器,讓它直接加載文件:  
  

menuentry "DOS" { insmod chain insmod fat set root=(hd0,3) chainloader /io.sys}

# 5.8 Boot Loader Details (引導加載器詳細信息  )
  
Now we’ll look quickly at some boot loader internals. Feel free to skip to the next chapter if this material doesn’t interest you.  
  
現在我們將簡要介紹一些引導加載程序的內部機制。

如果這部分內容不符合您的興趣,可以跳到下一章節。  
  
To understand how boot loaders like GRUB work, let’s first survey how a PC boots when you turn it on. Due to the repeated inadequacies of traditional PC boot mechanisms, there are several variations, but there are two main schemes: MBR and UEFI  
  
為了理解像GRUB這樣的引導加載程序是如何工作的,讓我們首先了解一下當您打開計算機電源時,計算機是如何啓動的。

由於傳統PC引導機制的重複不足,存在幾種變體,但主要有兩種方案:MBR和UEFI。  
### 5.8.1 MBR Boot (MBR 啓動 )
  
In addition to the partition information described in 4.1 Partitioning Disk Devices, the Master Boot Record (MBR) includes a small area (441 bytes) that the PC BIOS loads and executes after its Power-On Self-Test (POST). Unfortunately, this is too little storage to house almost any boot loader, so additional space is necessary, resulting in what is sometimes called a multi-stage boot loader. In this case the initial piece of code in the MBR does nothing other than load the rest of the boot loader code. The remaining pieces of the boot loader are usually stuffed into the space between the MBR and the first partition on the disk.  
  
  
除了 4.1 磁盤設備分區中描述的分區信息外,主引導記錄 (MBR) 還包括一小塊區域(441 字節),用於 PC BIOS 在開機自檢 (POST) 後加載和執行。

不幸的是,這個存儲空間太小,幾乎無法容納任何引導加載程序,因此需要額外的空間,這就是所謂的多階段引導加載程序。在這種情況下,MBR 中的初始代碼除了加載引導加載器的其他代碼外沒有其他作用。

引導加載器的其餘部分通常被塞入 MBR 和磁盤上第一個分區之間的空間。  
  
Of course, this isn’t terribly secure because anything can overwrite the code there, but most boot loaders do it, including most GRUB installations. In addition, this scheme won’t work with a GPT-partitioned disk using the BIOS to boot because the GPT table information resides in the area after the MBR. (GPT leaves the traditional MBR alone for backward compatibility.)  
  
當然,這並不是非常安全,因為任何東西都可以覆蓋那裏的代碼,但大多數引導加載器都是這樣做的,包括大多數 GRUB 安裝。

此外,該方案不能用於使用 BIOS 啓動的 GPT 分區磁盤,因為 GPT 表信息位於 MBR 之後的區域。(為了向後兼容,GPT 只保留了傳統的 MBR)。  
  
  
The workaround for GPT is to create a small partition called a BIOS boot partition with a special UUID to give the full boot loader code a place to reside. But GPT is normally used with UEFI, not the traditional BIOS, which leads us to the UEFI boot scheme.  
  
GPT 的變通方法是創建一個稱為 BIOS 啓動分區的小分區,該分區具有特殊的 UUID,以便為完整的啓動加載程序代碼提供存放位置。

但 GPT 通常用於 UEFI,而不是傳統的 BIOS,這就引出了 UEFI 啓動方案。  
### 5.8.2 UEFI Boot( UEFI 啓動  )
  
PC manufacturers and software companies realized that the traditional PC BIOS is severely limited, so they decided to develop a replacement called Extensible Firmware Interface (EFI). EFI took a while to catch on for most PCs, but now it’s fairly common. The current standard is Unified EFI (UEFI), which includes features such as a built-in shell and the ability to read partition tables and navigate filesystems. The GPT partitioning scheme is part of the UEFI standard.  
  
個人電腦製造商和軟件公司意識到,傳統的個人電腦 BIOS 有很大的侷限性,因此他們決定開發一種名為 "可擴展固件接口"(EFI)的替代品。

EFI 花了一段時間才被大多數個人電腦所接受,但現在已經相當普遍。

目前的標準是統一 EFI (UEFI),它包括一些功能,如內置 shell 以及讀取分區表和瀏覽文件系統的能力。GPT 分區方案是 UEFI 標準的一部分。  
  
Booting is radically different on UEFI systems and, for the most part, much easier to understand. Rather than executable boot code residing outside of a filesystem, there is always a special filesystem called the EFI System Partition (ESP), which contains a directory named efi. Each boot loader has its own identifier and a corresponding subdirectory, such as efi/microsoft, efi/apple, or efi/grub. A boot loader file has an .efi extension and resides in one of these subdirectories, along with other supporting files.  
  
在 UEFI 系統上,啓動方式截然不同,而且大部分情況下更容易理解。

在 UEFI 系統中,可執行的啓動代碼並不存在於文件系統之外,而是始終存在一個名為 EFI 系統分區(ESP)的特殊文件系統,其中包含一個名為 efi 的目錄。

每個引導加載程序都有自己的標識符和相應的子目錄,如 efi/microsoft、efi/apple 或 efi/grub。

Boot Loader 文件的擴展名為 .efi,與其他支持文件一起存放在這些子目錄中。  
  
> NOTE The ESP differs from the BIOS boot partition described in 5.8.1 MBR Boot and has a different UUID.  
>   
> 注意 ESP 與 5.8.1 MBR 啓動中描述的 BIOS 啓動分區不同,其 UUID 也不同。  
  
There’s a wrinkle, though: You can’t just put old boot loader code into the ESP because that code was written for the BIOS interface. Instead, you must provide a boot loader written for UEFI. For example, when using GRUB, you have to install the UEFI version of GRUB rather than the BIOS version. In addition, you must “announce” new boot loaders to the firmware.  
  
但有一個問題:不能將舊的引導加載程序代碼放入 ESP,因為這些代碼是為 BIOS 界面編寫的。

相反,你必須提供一個為 UEFI 編寫的引導加載器。

例如,在使用 GRUB 時,必須安裝 UEFI 版本的 GRUB 而不是 BIOS 版本。

此外,您必須向固件 "宣佈 "新的啓動加載程序。  
  
And, as mentioned in 5.6 UEFI Secure Boot Problems, we have the “secure boot” issue.  
  
正如 5.6 UEFI 安全啓動問題中提到的,我們還有 "安全啓動 "問題。  
### 5.8.3 How GRUB Works (GRUB 如何工作  )
  
Let’s wrap up our discussion of GRUB by looking at how it does its work:  


最後,我們來看看 GRUB 是如何工作的:

1. The PC BIOS or firmware initializes the hardware and searches its boot-order storage devices for boot   
code.  
2. Upon finding the boot code, the BIOS/firmware loads and executes it. This is where GRUB begins.  
3. The GRUB core loads.  
4. The core initializes. At this point, GRUB can now access disks and filesystems.  
5. GRUB identifies its boot partition and loads a configuration there.  
6. GRUB gives the user a chance to change the configuration.  
7. After a timeout or user action, GRUB executes the configuration (the sequence of commands outlined in   
5.5.2 GRUB Configuration).  
8. In the course of executing the configuration, GRUB may load additional code (modules) in the boot   
partition.  
9. GRUB executes a boot command to load and execute the kernel as specified by the configuration’s   
linux command.  


1. 電腦 BIOS 或固件初始化硬件,並搜索啓動順序存儲設備以獲取啓動代碼。    
2. 找到啓動代碼後,BIOS/固件加載並執行它。這就是 GRUB 的開始。  
3. 加載 GRUB 核心。  
4. 核心初始化。此時,GRUB 可以訪問磁盤和文件系統。  
5. 5. GRUB 識別其引導分區並在此加載配置。  
6. GRUB 允許用户更改配置。  
7. 超時或用户操作後,GRUB 執行配置(5.5.2 GRUB 配置中概述的命令序列)。  
5.5.2 GRUB 配置)。  
8. 在執行配置的過程中,GRUB 可能會在引導分區中加載額外的代碼(模塊)。  
分區中的附加代碼(模塊)。  
9. GRUB 執行啓動命令,加載並執行配置的 linux 命令指定的內核。  
  
  
Steps 3 and 4 of the preceding sequence, where the GRUB core loads, can be complicated due to the repeated inadequacies of traditional PC boot mechanisms. The biggest question is “Where is the GRUB core?” There are three basic possibilities:  


由於傳統 PC 啓動機制屢屢出現缺陷,前述序列中 GRUB 內核加載的第 3 步和第 4 步可能會變得複雜。

最大的問題是 "GRUB 內核在哪裏?有三種基本可能性:  

o Partially stuffed between the MBR and the beginning of the first partition  
o In a regular partition  
o In a special boot partition: a GPT boot partition, EFI System Partition (ESP), or elsewhere  
  
o 部分塞在 MBR 和第一個分區的開頭之間  
o 常規分區中  
o 在特殊引導分區中:GPT 引導分區、ESP 系統分區或其他地方  
  
  
In all cases except where you have an ESP, the PC BIOS loads 512 bytes from the MBR, and that is where GRUB starts. This little piece (derived from boot.img in the GRUB directory) isn’t yet the core, but it contains the start location of the core and loads the core from this point  

除 ESP 外,在所有情況下,電腦 BIOS 都會從 MBR 中加載 512 字節,這就是 GRUB 的起始位置。這一小段(來自 GRUB 目錄中的 boot.img)還不是核心,但它包含了核心的起始位置,並從此處加載核心。  
  

However, if you have an ESP, the GRUB core goes there as a file. The firmware can navigate the ESP and directly execute the GRUB core or any other operating system loader located there.  
  
不過,如果你有一個 ESP,GRUB 內核就會以文件形式存在。

固件可以瀏覽 ESP 並直接執行 GRUB 內核或位於其中的任何其他操作系統加載器。  


Still, on most systems, this is not the complete picture. The boot loader might also need to load an initial RAM filesystem image into memory before loading and executing the kernel. That’s what the initrd configuration parameter in 6.8 The Initial RAM Filesystem specifies. But before you learn about the initial RAM filesystem, you should learn about the user space start—that’s where the next chapter begins.  

  
不過,在大多數系統中,這還不是全部。在加載和執行內核之前,引導加載器可能還需要將初始 RAM 文件系統映像加載到內存中。

這就是 6.8 初始 RAM 文件系統中的 initrd 配置參數所指定的。
user avatar AmbitionGarden 头像 chengxy 头像 shenchendexiaoyanyao 头像 wxweven 头像 daixiaoyulq 头像 shanliangdeyanjing 头像 summo_java 头像
点赞 7 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.