Created page with "Category:Boot loaders zh-CN:UEFI Bootloaders 该页包含了关于UEFI 启动管理器启动Linux内核的信息。在阅读该页之前,建议先阅读UEFI..."
New page
[[Category:Boot loaders]]
[[zh-CN:UEFI Bootloaders]]
该页包含了关于[[UEFI]] 启动管理器启动Linux内核的信息。在阅读该页之前,建议先阅读[[UEFI]]以及[[GPT]]页面。 [[Boot Loader|启动管理器]] (稳定性由好到差排序) 如下:
# Linux Kernel EFISTUB
# GRUB(2)
# Fedora's GRUB-Legacy fork
# ELILO
# EFILINUX
== Linux Kernel EFISTUB ==
Linux Kernel >= 3.3 contains a stub which is capable of acting as the kernel's UEFI bootloader (which in a way means the kernel is its own bootloader), thus removing the need for a separate bootloader to launch the kernel (a boot manager might be required though, explained in detail later). This support is called {{ic|EFI BOOT STUB}} by upstream or {{ic|EFISTUB}} in short. EFISTUB should enabled by setting {{ic|1=CONFIG_EFI_STUB=y}} in Kernel config. The upstream documentation about EFISTUB booting is at https://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/x86/efi-stub.txt;hb=HEAD . More (unofficial) info is at http://www.rodsbooks.com/efi-bootloaders/efistub.html .
Since the kernel is responsible for booting only itself, a single EFISTUB enabled kernel is not capable of launching other kernels. And each EFISTUB Kernel+Initramfs pair requires a separate boot menu entry. Thus when multiple kernels and/or initramfs files are involved, a UEFI Boot Manager is recommended to manage them.
=== Setting up EFISTUB ===
# Create an FAT32 UEFI System Partition - [[Unified_Extensible_Firmware_Interface#Create_an_UEFI_System_Partition_in_Linux]]
# Mount the UEFI System Partition at {{ic|/boot/efi}}.
# Create {{ic|/boot/efi/EFI/arch/}} directory.
# Copy {{ic|/boot/vmlinuz-linux}} to {{ic|/boot/efi/EFI/arch/vmlinuz-linux.efi}} . The {{ic|.efi}} file extension is very important as some UEFI firmwares refuse to launch a file without the {{ic|.efi}} file extension.
# Copy {{ic|/boot/initramfs-linux.img}} to {{ic|/boot/efi/EFI/arch/initramfs-linux.img}}.
# Create {{ic|/boot/efi/EFI/arch/linux.conf}} with the kernel parameters to be passed to the kernel (example file shown below). This file should consist of only one line and simply contains all the kernel parameters to be used by the EFISTUB loader to the kernel.
{{hc|/boot/efi/EFI/arch/linux.conf|
root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-linux.img
}}
{{Note|1=This config file is not supported by any currently shipping kernel version and is expected to be supported only in kernels >=3.6 .}}
{{Note|The kernel and initramfs files at {{ic|/boot/efi/EFI/arch/}} should be updated everytime those files in {{ic|/boot}} are updated.}}
{{Warning|In Linux Kernel EFISTUB booting, {{ic|1=initrd=}} path should use UEFI-style backslashes (\) and should be relative to the UEFI System Partition's root, not relative to the current directory in the UEFI Shell. An improper {{ic|1=initrd=}} option leads to a system hang without any error message from the firmware or the kernel.}}
==== Sync EFISTUB Kernel in UEFISYS partition using Systemd ====
[[Systemd]] init system supports defining tasks that should be performed when certain files/paths are changed. This feature of systemd is used to copy updated EFISTUB kernel and initramfs files when they are update in {{ic|/boot}}, like during package updates or during manual run of mkinitcpio etc.
For this create the files as defined below:
{{hc|/etc/systemd/system/efistub_copy.path|
[Unit]
Description=Copy EFISTUB Kernel and Initramfs to UEFISYS Partition
[Path]
PathChanged=/boot/initramfs-linux-fallback.img
Unit=efistub_copy.service
[Install]
WantedBy=multi-user.target
}}
{{hc|/etc/systemd/system/efistub_copy.service|
[Unit]
Description=Copy EFISTUB Kernel and Initramfs to UEFISYS Partition
[Service]
Type=oneshot
ExecStart=/bin/cp -f /boot/vmlinuz-linux /boot/efi/EFI/arch/vmlinuz-linux.efi
ExecStart=/bin/cp -f /boot/initramfs-linux.img /boot/efi/EFI/arch/initramfs-linux.img
ExecStart=/bin/cp -f /boot/initramfs-linux-fallback.img /boot/efi/EFI/arch/initramfs-linux-fallback.img
}}
After creating the files run:
# systemctl enable efistub_copy.path
# systemctl start efistub_copy.path
==== Sync EFISTUB Kernel in UEFISYS partition using Incron ====
Incron can also be used to automatically sync the EFISTUB kernel after updates.
First, [[pacman|install]] the {{Pkg|incron}} package from the [[Official Repositories]].
Next you will need to set up a script to do the actual copying. You can call this script whatever you want, but make sure you use absolute paths in the commands.
{{hc|File: /root/copykernel.sh|
/bin/cp -f /boot/vmlinuz-linux /boot/efi/EFI/arch/vmlinuz-linux.efi
/bin/cp -f /boot/initramfs-linux.img /boot/efi/EFI/arch/initramfs-linux.img
/bin/cp -f /boot/initramfs-linux-fallback.img /boot/efi/EFI/arch/initramfs-linux-fallback.img
}}
Specify which file to watch for changes in {{ic|/etc/incron.d/kernel.conf}}. The first parameter is the file to watch: {{ic|/boot/initramfs-linux-fallback.img}}. The second parameter {{ic|IN_CLOSE_WRITE}} is the action to watch for. The third parameter {{ic|/root/copykernel.sh}} is the script to execute.
{{hc|File: /etc/incron.d/kernel.conf|
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /root/copykernel.sh
}}
Now just add incrond to the daemon list in {{ic|/etc/rc.conf}} and it will automatically start up and copy the new files to the proper place every time the kernel is updated.
==== Sync EFISTUB Kernel in UEFISYS partition using Mkinitcpio hook ====
This uses a hook that spawns a background process, which waits for the generation process to finish, then copies the finished kernel and initrd.
This approach doesn't need a system level daemon to function.
{{hc|File: /usr/lib/initcpio/install/uefi|
#!/bin/bash
function get_kernel() {
next="0"
for a in ${BASH_ARGV[*]} ; do
if [[ $next == "1" ]] ; then
eval "$1='$a'"
return
fi
if [[ $a == "-c" ]] ; then
next="1"
fi
done
}
build() {
kernel_name=''
get_kernel kernel_name
bash /root/watch.sh $GENIMG $kernel_name &
}
help() {
cat
}}
{{hc|File: /root/watch.sh|
#!/bin/bash
EFI_DIR="/boot/efi/EFI/arch"
INITRD="$1"
IMAGE="$2"
IMAGE_BASENAME=$(basename $2)
EFI_IMAGE="$EFI_DIR/$IMAGE_BASENAME.efi"
function do_copy(){
cp $INITRD $EFI_DIR
cp $IMAGE $EFI_IMAGE
echo "Synced $INITRD to $EFI_DIR"
}
while [ : ]; do
if [[ ! -d "/proc/$PPID" ]]; then
do_copy
exit 1
fi
sleep 1
done
}}
Then simply add {{ic|uefi}} to the list of hooks in {{ic|/etc/mkinitcpio.conf}}
=== Booting EFISTUB ===
There are various ways of booting EFISTUB kernels. Those described here are:
# Using rEFInd UEFI Boot Manager
# Using UEFI Shell
# Using efibootmgr entry
==== Using rEFInd ====
rEFInd is a fork of rEFIt Boot Manager (used in Intel Macs) by Rod Smith (author is GPT-fdisk). rEFInd fixes many issues in rEFIt with respect to non-Mac UEFI booting and also has support for booting EFISTUB kernels and contains some features specific to them. More info about rEFInd support for EFISTUB is at http://www.rodsbooks.com/refind/linux.html .
There are two ways of installing rEFInd. One is using the {{Pkg|refind-efi-x86_64}} from [extra] repo or {{AUR|refind-efi-x86_64-git}} AUR package (only for x86_64 UEFI) (recommended). The other is to use the precompiled binaries provided by upstream at http://sourceforge.net/projects/refind/ . If you downloaded the precompiled binaries provided by upstream, then setup rEFInd as follows ({{ic|/boot/efi}} is UEFISYS partition mountpoint):
# Extract the refind-bin-*.zip file.
# Copy {{ic|refind}} directory to {{ic|/boot/efi/EFI/arch/refind}}
# Rename {{ic|/boot/efi/EFI/arch/refind/refind.conf-sample}} to {{ic|/boot/efi/EFI/arch/refind/refind.conf}} and edit it according to your needs. It is possible define boot entries within {{ic|refind.conf}} itself. Follow the example menuentries defined in {{ic|/boot/efi/EFI/arch/refind/refind.conf}} to create your own.
# Rename {{ic|/boot/efi/EFI/arch/refind/refind_x64.efi}} to {{ic|/boot/efi/EFI/arch/refind/refindx64.efi}}. (Or refind_ia32.efi to refindia32.efi in case of 32-bit UEFI).
The above steps are automatically done by the AUR package. After setting up, create {{ic|/boot/efi/EFI/arch/refind_linux.conf}} with the kernel parameters to be used to EFISTUB kernel by rEFInd. An example file is shown below.
{{hc|/boot/efi/EFI/arch/refind_linux.conf|
"Boot with defaults" "root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap"
"Boot to Terminal" "root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap 3"
}}
These options are displayed as a submenu by rEFInd. The sub-menu can be accessed by using "+" or "insert" keys.
In non-Mac systems create an entry for rEFInd using efibootmgr.
# efibootmgr -c -l \\EFI\\arch\\refind\\refindx64.efi -L rEFInd -p X
"X" is the partition number containing the bootloader.
In case of Apple Macs, try {{AUR|mactel-boot}} for an experimental "bless" utility for Linux. If that does not work, use "bless" form within OSX to set rEFInd as default bootloader. Assuming UEFISYS partition is mounted at {{ic|/mnt/efi}} within OSX, do
$ sudo bless --setBoot --folder /mnt/efi/EFI/refind --file /mnt/efi/EFI/refind/refindx64.efi
==== Using UEFI Shell ====
It is possible to launch EFISTUB kernel form UEFI Shell as if its a normal UEFI application. In this case the kernel parameters are passed as normal parameters to the launched EFISTUB kernel file.
> fs0:
> cd \EFI\arch
> vmlinuz-linux.efi root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-linux.img
==== Using efibootmgr entry ====
It is possible to directly embed the kernel parameters within the boot entry created by efibootmgr. Do (as root)
# echo "root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap initrd=\\EFI\\arch\\initramfs-linux.img" | iconv -f ascii -t ucs2 | efibootmgr --create --gpt --disk /dev/sda --part 1 --label "Archlinux (EFISTUB)" --loader "\\EFI\\arch\\vmlinuz-linux.efi" --append-binary-args -
{{Note|The trailing hyphen after {{ic|--append-binary-args}} is required to instruct efibootmgr to read the parameters from STDIN (standard input). The code should be {{ic|--append-binary-args -}} .}}
More info about efibootmgr at [[UEFI#efibootmgr]]. Forum post https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 .
== GRUB(2) ==
GRUB(2) contains its own filesystem drivers and does not rely on the firmware to access the files. It can directly read files from {{ic|/boot}} and does not require the kernel and initramfs files to be in the UEFISYS partition. Detailed information at [[GRUB#UEFI_systems_2]]. For bzr development version try AUR package - {{AUR|grub-efi-x86_64-bzr}}.
== GRUB Legacy Fedora ==
[[GRUB Legacy]] upstream sources (and the package Archlinux ships) do not support UEFI. However Fedora/Redhat's fork contains UEFI patches provided by Intel. The patched sources are at https://github.com/vathpela/grub-fedora . GRUB-Legacy-Fedora contains its own filesystem drivers (including ext4) and does not rely on the firmware to access the files. Thus it can directly read files form /boot and does not require the kernel and initramfs files to be in the UEFISYS partition. AUR package - {{AUR|grub-legacy-fedora-efi-x86_64-git}} (only for x86_64 UEFI).
{{Note|Fedora developers have mentioned that after the release of Fedora 17, grub-legacy-fedora development will stop and Fedora will be switching to GRUB(2) as the default UEFI bootloader from F18 onwards. Fedora already uses GRUB(2) as its default BIOS bootloader since F16. Users are recommended to switch to EFISTUB or GRUB(2) instead.}}
== ELILO ==
ELILO is the UEFI version of LILO Boot Loader. It was originally created for Intel Itanium systems which supported only EFI (precursor to UEFI). It is the oldest UEFI bootloader for Linux. It is still in development but happens at a very slow pace. Upstream provided compiled binaries are available at http://sourceforge.net/projects/elilo/ . Elilo config file {{ic|elilo.conf}} is similar to [[LILO]]'s config file. AUR package - {{AUR|elilo-x86_64}} (only for x86_64 UEFI).
== EFILINUX ==
EFILINUX is a reference implementation of a UEFI Linux bootloader and precursor to Kenrel EFISTUB support. It is considered to be a alpha quality software (as on 16-MAY-2012). Upstream sources are at https://github.com/mfleming/efilinux . and the usage instructions are at http://thread.gmane.org/gmane.linux.kernel/1172645 and http://article.gmane.org/gmane.linux.kernel/1175060 . AUR packages - {{AUR|efilinux-x86_64}} and {{AUR|efilinux-x86_64-git}} (only for x86_64 UEFI).
==See also==
* [http://www.rodsbooks.com/efi-bootloaders/ Rod Smith - Managing EFI Boot Loaders for Linux]
* [http://www.rodsbooks.com/refind/ Rod Smith - rEFInd, a fork or rEFIt]
* [https://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob_plain;f=Documentation/x86/efi-stub.txt;hb=HEAD Linux Kernel Documentation on EFISTUB]
* [http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=291f36325f9f252bd76ef5f603995f37e453fc60;hp=55839d515495e766605d7aaabd9c2758370a8d27 Linux Kernel EFISTUB Git Commit]
* [http://www.rodsbooks.com/efi-bootloaders/efistub.html Rod Smith's page on EFISTUB]
* [http://www.rodsbooks.com/refind/linux.html rEFInd Documentation for booting EFISTUB Kernels]