Difference between revisions of "UEFI Bootloaders"

From ArchWiki
Jump to: navigation, search
m (Linux Kernel EFISTUB)
m (Using UEFI Shell: Fixed typo.)
(48 intermediate revisions by 15 users not shown)
Line 4: Line 4:
  
 
# Linux Kernel EFISTUB
 
# Linux Kernel EFISTUB
# GRUB(2)
+
# GRUB 2.x
# Fedora's GRUB-Legacy fork
+
# Gummiboot
 
# ELILO
 
# ELILO
 
# EFILINUX
 
# EFILINUX
 +
# SYSLINUX (GIT Alpha Version)
  
 
== Linux Kernel EFISTUB ==
 
== Linux Kernel EFISTUB ==
Line 20: Line 21:
 
# Mount the UEFI System Partition at {{ic|/boot/efi}}.
 
# Mount the UEFI System Partition at {{ic|/boot/efi}}.
 
# Create {{ic|/boot/efi/EFI/arch/}} directory.
 
# Create {{ic|/boot/efi/EFI/arch/}} directory.
# Copy {{ic|/boot/vmlinuz-linux}} to {{ic|/boot/efi/EFI/arch/vmlinuz-arch.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/vmlinuz-linux}} to {{ic|/boot/efi/EFI/arch/vmlinuz-arch.efi}} . The {{ic|.efi}} file extension is very important as some UEFI firmwares refuse to launch a file without the {{ic|.efi}} file extension. '''Important:''' Remember that the file is called vmlinu'''z''', but not vmlinu'''x'''.
 
# Copy {{ic|/boot/initramfs-linux.img}} to {{ic|/boot/efi/EFI/arch/initramfs-arch.img}}.
 
# Copy {{ic|/boot/initramfs-linux.img}} to {{ic|/boot/efi/EFI/arch/initramfs-arch.img}}.
 
# Copy {{ic|/boot/initramfs-linux-fallback.img}} to {{ic|/boot/efi/EFI/arch/initramfs-arch-fallback.img}}.
 
# Copy {{ic|/boot/initramfs-linux-fallback.img}} to {{ic|/boot/efi/EFI/arch/initramfs-arch-fallback.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.
 
  
 +
{{Note|There exists a [http://article.gmane.org/gmane.linux.kernel/1269122/ patch] for the kernel that allows passing kernel parameters via a file named {{ic|linux.conf}} placed in the same directory as the kernel when booting via EFISTUB; example
 
{{hc|/boot/efi/EFI/arch/linux.conf|<nowiki>
 
{{hc|/boot/efi/EFI/arch/linux.conf|<nowiki>
root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-arch.img</nowiki>}}  
+
root=UUID=xxxx ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-arch.img</nowiki>}}
 +
As of at least commit [https://github.com/torvalds/linux/commit/29594404d7fe73cd80eaa4ee8c43dcc53970c60e 29594404d7fe73cd80eaa4ee8c43dcc53970c60e], the {{ic|linux.conf}} patch has not been merged; you will need to apply it yourself if you wish to use this feature.}}
  
{{Note|1=This config file is not supported by any currently shipping kernel version and is expected to be supported only in kernels >=3.7 .}}
+
Finally, jump to [[#Booting_EFISTUB]] choose a way to get your machine to make use of the new EFISTUB you've just created.
  
 
{{Note|The kernel and initramfs files at {{ic|/boot/efi/EFI/arch/}} should be updated everytime those files in {{ic|/boot}} are updated.}}
 
{{Note|The kernel and initramfs files at {{ic|/boot/efi/EFI/arch/}} should be updated everytime those files in {{ic|/boot}} are updated.}}
Line 36: Line 38:
 
==== Sync EFISTUB Kernel in UEFISYS partition using Systemd ====
 
==== 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.
+
[[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 updated in {{ic|/boot}}, like during package updates or during manual run of mkinitcpio etc.
  
 
For this create the files as defined below:
 
For this create the files as defined below:
  
{{hc|/etc/systemd/system/efistub_copy.path|<nowiki>
+
{{hc|/etc/systemd/system/efistub-update.path|<nowiki>
 
[Unit]
 
[Unit]
Description=Copy EFISTUB Kernel and Initramfs to UEFISYS Partition
+
Description=Copy EFISTUB Kernel to UEFISYS Partition
  
 
[Path]
 
[Path]
 +
PathChanged=/boot/vmlinuz-linux
 +
PathChanged=/boot/initramfs-linux.img
 
PathChanged=/boot/initramfs-linux-fallback.img
 
PathChanged=/boot/initramfs-linux-fallback.img
Unit=efistub_copy.service
 
  
 
[Install]
 
[Install]
 
WantedBy=multi-user.target</nowiki>}}
 
WantedBy=multi-user.target</nowiki>}}
  
{{hc|/etc/systemd/system/efistub_copy.service|<nowiki>
+
{{hc|/etc/systemd/system/efistub-update.service|<nowiki>
 
[Unit]
 
[Unit]
Description=Copy EFISTUB Kernel and Initramfs to UEFISYS Partition
+
Description=Copy EFISTUB Kernel to UEFISYS Partition
  
 
[Service]
 
[Service]
Line 64: Line 67:
 
After creating the files run:
 
After creating the files run:
  
  # systemctl enable efistub_copy.path
+
  # systemctl enable efistub-update.path
  # systemctl start efistub_copy.path
+
  # systemctl start efistub-update.path
  
 
==== Sync EFISTUB Kernel in UEFISYS partition using Incron ====
 
==== Sync EFISTUB Kernel in UEFISYS partition using Incron ====
Line 75: Line 78:
 
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.
 
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/efistub_copy.sh|<nowiki>
+
{{hc|File: /usr/local/bin/efistub-update.sh|<nowiki>
 +
#!/bin/sh
 
/bin/cp -f /boot/vmlinuz-linux /boot/efi/EFI/arch/vmlinuz-arch.efi
 
/bin/cp -f /boot/vmlinuz-linux /boot/efi/EFI/arch/vmlinuz-arch.efi
 
/bin/cp -f /boot/initramfs-linux.img /boot/efi/EFI/arch/initramfs-arch.img
 
/bin/cp -f /boot/initramfs-linux.img /boot/efi/EFI/arch/initramfs-arch.img
Line 81: Line 85:
 
</nowiki>}}
 
</nowiki>}}
  
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/efistub_copy.sh}} is the script to execute.
+
Specify which file to watch for changes in {{ic|/etc/incron.d/efistub-update.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|/usr/local/bin/efistub-update.sh}} is the script to execute.
  
{{hc|File: /etc/incron.d/kernel.conf|<nowiki>
+
{{hc|File: /etc/incron.d/efistub-update.conf|<nowiki>
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /root/efistub_copy.sh
+
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update.sh
 
</nowiki>}}
 
</nowiki>}}
  
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.
+
Now just add {{ic|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 ====
 
==== Sync EFISTUB Kernel in UEFISYS partition using Mkinitcpio hook ====
Line 95: Line 99:
 
This approach doesn't need a system level daemon to function.
 
This approach doesn't need a system level daemon to function.
  
{{hc|File: /usr/lib/initcpio/install/efistub_copy|<nowiki>
+
{{hc|File: /usr/lib/initcpio/install/efistub-update|<nowiki>
 +
#!/usr/bin/env bash
  
#!/bin/bash
+
build() {
 
+
     local kernel= image=
function get_kernel() {
+
     while getopts ':c:S:' OPT; do
 
+
        case $OPT in
     next="0"
+
        'c') kernel=$OPTARG;;
     for a in ${BASH_ARGV[*]} ; do
+
        'S') image=$OPTARG;;
      if [[ $next == "1" ]] ; then
+
        esac
          eval "$1='$a'"
+
          return
+
      fi
+
 
+
      if [[ $a == "-c" ]] ; then
+
          next="1"
+
      fi
+
 
     done
 
     done
  
 +
    /root/watch.sh $image $kernel &
 
}
 
}
 
build() {
 
 
    kernel_name=''
 
    get_kernel kernel_name
 
    bash /root/watch.sh $GENIMG  $kernel_name &
 
}
 
 
  
 
help() {
 
help() {
Line 130: Line 121:
  
 
# vim: set ft=sh ts=4 sw=4 et:
 
# vim: set ft=sh ts=4 sw=4 et:
 
 
 
</nowiki>}}
 
</nowiki>}}
 
  
  
 
{{hc|File: /root/watch.sh|<nowiki>
 
{{hc|File: /root/watch.sh|<nowiki>
 
 
#!/bin/bash
 
#!/bin/bash
  
 
EFI_DIR="/boot/efi/EFI/arch"
 
EFI_DIR="/boot/efi/EFI/arch"
  
 +
INITRD=$1
 +
KERNEL=$2
  
INITRD="$1"
+
EFI_IMAGE="$EFI_DIR/${KERNEL##*/}.efi"
IMAGE="$2"
+
EFI_INITRD="$EFI_DIR/${INITRD##*/}"
EFI_IMAGE="$EFI_DIR/$(basename $2 | sed 's@linux@arch@g')"
+
EFI_INITRD="$EFI_DIR/$(basename $1 | sed 's@linux@arch@g')"
+
  
function do_copy(){
+
while [[ -d "/proc/$PPID" ]]; do
        cp $INITRD $EFI_INITRD
+
        cp $IMAGE $EFI_IMAGE
+
        echo "Synced $INITRD to $EFI_DIR"
+
}
+
 
+
while [ : ]; do
+
 
+
    if [[ ! -d "/proc/$PPID" ]]; then
+
        do_copy
+
        exit 1
+
    fi
+
 
     sleep 1
 
     sleep 1
 
 
done
 
done
  
 +
cp $INITRD $EFI_INITRD
 +
cp $KERNEL $EFI_IMAGE
 +
echo "Synced $INITRD to $EFI_DIR"
 
</nowiki>}}
 
</nowiki>}}
  
  
Then simply add {{ic|efistub_copy}} to the list of hooks in {{ic|/etc/mkinitcpio.conf}}
+
Then simply add {{ic|efistub-update}} to the list of hooks in {{ic|/etc/mkinitcpio.conf}}
  
 
=== Booting EFISTUB ===
 
=== Booting EFISTUB ===
Line 173: Line 151:
 
There are various ways of booting EFISTUB kernels. Those described here are:
 
There are various ways of booting EFISTUB kernels. Those described here are:
  
# Using rEFInd UEFI Boot Manager
+
# Using rEFInd UEFI Boot Manager <-- Nice boot GUI.
 
# Using Gummiboot Boot Manager
 
# Using Gummiboot Boot Manager
 
# Using UEFI Shell
 
# Using UEFI Shell
# Using efibootmgr entry
+
# Using efibootmgr entry <-- will load Arch Linux directly. No GUI.
  
 
==== Using rEFInd ====
 
==== 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 .
+
rEFInd is a fork of rEFIt Boot Manager (used in Intel Macs) by Rod Smith (author of 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:
+
Install the {{Pkg|refind-efi}} package from [extra]
  
* 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).
+
# pacman -S refind-efi
  
* Using 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):
+
Then run the below commands ($esp is the mountpoint of UEFISYS partition)
  
# Extract the refind-bin-*.zip file.
+
# mkdir -p $esp/EFI/refind
# 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.
+
  
{{Note|The above steps are automatically done in {{Pkg|refind-efi-x86_64}} and {{AUR|refind-efi-x86_64-git}}.}}
+
For 64-bit UEFI
 +
# cp /usr/lib/refind/refindx64.efi $esp/EFI/refind/refindx64.efi
  
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.
+
For 32-bit UEFI
 +
# cp /usr/lib/refind/refindia32.efi $esp/EFI/refind/refindia32.efi
  
{{hc|/boot/efi/EFI/arch/refind_linux.conf|<nowiki>
+
Common commands:
"Boot with defaults" "root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap"
+
# cp /usr/lib/refind/config/refind.conf $esp/EFI/refind/refind.conf
"Boot to Terminal"  "root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap 3"</nowiki>}}
+
# cp -r /usr/share/refind/icons $esp/EFI/refind/icons
 +
 
 +
Edit {{ic|$esp/EFI/refind/refind.conf}} according to your requirements. The file is well documented/commented. After that create {{ic|$esp/EFI/arch/refind_linux.conf}} as shown below (example):
 +
 
 +
{{hc|$esp/EFI/arch/refind_linux.conf|<nowiki>
 +
"Boot with defaults" "root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 ro rootfstype=ext4 add_efi_memmap systemd.unit=graphical.target"
 +
"Boot to Terminal"  "root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 ro rootfstype=ext4 add_efi_memmap systemd.unit=multi-user.target"</nowiki>}}
 +
Please notice the difference between the standard UUID and the PARTUUID shown by {{ic|ls -l /dev/disk/by-partuuid/}}.
 +
{{Note|{{ic|refind_linux.conf}} should be in the same directory as the kernel and initramfs files, not the directory {{ic|refindx64.efi}} resides.}}
  
 
These options are displayed as a submenu by rEFInd. The sub-menu can be accessed by using "+" or "insert" keys.
 
These options are displayed as a submenu by rEFInd. The sub-menu can be accessed by using "+" or "insert" keys.
Line 204: Line 190:
 
In non-Mac systems create an entry for rEFInd using [[UEFI#efibootmgr|efibootmgr]].  
 
In non-Mac systems create an entry for rEFInd using [[UEFI#efibootmgr|efibootmgr]].  
  
  # efibootmgr -c -g -d /dev/sdX -p Y -w -L "Arch Linux (rEFInd)" -l '\\EFI\\arch\\refind\\refindx64.efi'
+
# modprobe efivars
 +
  # efibootmgr -c -g -d /dev/sdX -p Y -w -L "rEFInd" -l '\EFI\refind\refindx64.efi'
  
"X" is the partition number containing the bootloader.
+
where {{ic|/dev/sdX}} is the drive and {{ic|Y}} is the partition number of UEFISYS in {{ic|/dev/sdXY}}.
  
 
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
 
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
Line 214: Line 201:
 
==== Using gummiboot ====
 
==== Using gummiboot ====
  
Gummiboot is a UEFI Boot Manager which provides a nice menu for EFISTUB Kernels. It is a new program and relatively untested compared to rEFInd . It is available in AUR as {{AUR|gummiboot}}. See http://freedesktop.org/wiki/Software/gummiboot for more info.
+
[[Gummiboot]] is a UEFI Boot Manager which provides a nice menu for EFISTUB Kernels. It is a new program and relatively untested compared to rEFInd . It is available in [extra] as {{Pkg|gummiboot-efi}}. See http://freedesktop.org/wiki/Software/gummiboot for more info.
  
 
==== Using UEFI Shell ====
 
==== 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.
+
It is possible to launch EFISTUB kernel form UEFI Shell as if it is a normal UEFI application. In this case the kernel parameters are passed as normal parameters to the launched EFISTUB kernel file.
  
 
  > fs0:
 
  > fs0:
 
  > cd \EFI\arch
 
  > cd \EFI\arch
  > vmlinuz-arch.efi root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-arch.img
+
  > vmlinuz-arch.efi root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-arch.img
  
 
==== Using efibootmgr entry ====
 
==== Using efibootmgr entry ====
  
It is possible to directly embed the kernel parameters within the boot entry created by efibootmgr. Do (as root)
+
{{Note|1=This menthod may not work due to [https://git.kernel.org/?p=linux/kernel/git/mfleming/efi.git;a=commitdiff;h=b003aaf799c991295b8b73e8f940d20bda2c1bbb;hp=ddffeb8c4d0331609ef2581d84de4d763607bd37 limitations in how the kernel handles uefi runtime variables]. For example in Lenovo Thinkpads the initrd path is truncated (verified using {{ic|efibootmgr -v}} command) and therefore the kernel fails to boot.}}
  
  # echo "root=/dev/sdaX ro rootfstype=ext4 add_efi_memmap initrd=\\EFI\\arch\\initramfs-arch.img" | iconv -f ascii -t ucs2 | efibootmgr -c -g -d /dev/sda -p 1 -L "Archlinux (EFISTUB)" -l "\\EFI\\arch\\vmlinuz-arch.efi" -@ -
+
{{Note|Some UEFI firmwares may not support embedding command line parameters to uefi applications in the boot entries.}}
 +
 
 +
It is possible to directly embed the kernel parameters within the boot entry created by efibootmgr. This means that in your BIOS/UEFI you will be able to select Arch Linux directly in the default boot order, and on startup it will boot into Arch directly without any kind of boot selection GUI.
 +
 
 +
Do (as root):
 +
 
 +
Install efibootmgr if you haven't already.
 +
  # pacman -S --needed efibootmgr
 +
 
 +
Determine the UUID or PARTUUID of your boot device (ie. the partition for {{ic|/}}, not the EFI boot partition)
 +
# blkid
 +
 
 +
Load the EFI module.
 +
# modprobe efivars
 +
 
 +
Finally, add the efistub.
 +
WARNING: Make sure you replace the following before running this command:
 +
* ''3518bb68-d01e-45c9-b973-0b5d918aae96'' -- with the UUID of your {{ic|/}} partition. (This is not PARTUUID!)
 +
* ''ext4'' -- if you use a different file system.
 +
* ''/dev/sda'' -- the drive that contains the EFI boot partition.
 +
* ''-p 1'' -- the partition number of the EFI boot partition.
 +
# echo 'root=UUID=3518bb68-d01e-45c9-b973-0b5d918aae96 ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-arch.img' | iconv -f ascii -t ucs2 | efibootmgr -c -g -d /dev/sda -p 1 -L "Arch Linux" -l '\EFI\arch\vmlinuz-arch.efi' -@ -
 +
 
 +
or you can just run the following line (remember to replace /dev/sda1):
 +
 
 +
  # echo "root=UUID=$(blkid /dev/sda1 -o value -s UUID) ro rootfstype=ext4 add_efi_memmap initrd=\\EFI\\arch\\initramfs-arch.img" | iconv -f ascii -t ucs2 | efibootmgr -c -g -d /dev/sda -p 1 -L "Arch Linux" -l '\EFI\arch\vmlinuz-arch.efi' -@ -
  
 
{{Note|The trailing hyphen after {{ic|--append-binary-args}} or {{ic|-@}} is required to instruct efibootmgr to read the parameters from STDIN (standard input). The code should be {{ic|--append-binary-args -}} or {{ic|-@ -}} .}}
 
{{Note|The trailing hyphen after {{ic|--append-binary-args}} or {{ic|-@}} is required to instruct efibootmgr to read the parameters from STDIN (standard input). The code should be {{ic|--append-binary-args -}} or {{ic|-@ -}} .}}
Line 234: Line 246:
 
More info about efibootmgr at [[UEFI#efibootmgr]]. Forum post https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 .
 
More info about efibootmgr at [[UEFI#efibootmgr]]. Forum post https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 .
  
== GRUB(2) ==
+
{{Note|Some firmwares may have trouble with the "initrd path" when piping in ucs-2 as shown above. In this case, one may put vmlinuz-linux.efi and the initramfs in the root of the ESP and adjust the efibootmgr entry accordingly.}}
  
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 2.x ==
  
== GRUB Legacy Fedora ==
+
GRUB 2.x 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]] 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).
+
== SYSLINUX ==
  
{{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.}}
+
{{Note|Syslinux UEFI support is currently part of version 6.00-preXX or in firmware branch of upstream git repo. It is considered alpha quality by upstream. The below information is provided mainly to enable bug-testing. Please report all issues upstream.}}
 +
 
 +
{{Note|Syslinux UEFI can boot only those kernels that support '''EFI Handover Protocol'''. Thus LTS kernels are not supported.}}
 +
 
 +
Install {{AUR|syslinux-efi-git}} AUR package and copy {{ic|/usr/lib/syslinux/efi64/*}} to {{ic|$esp/EFI/syslinux/}} ({{ic|$esp}} is the mountpoint of UEFISYS partition) ({{ic|efi64}} is for x86_64 UEFI firmwares, replace with {{ic|efi32}} for i386 UEFI firmwares), and then create a boot entry using efibootmgr in the firmware boot manager.
  
 
== ELILO ==
 
== 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).
+
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-efi-x86_64}} (only for x86_64 UEFI).
  
 
== EFILINUX ==
 
== 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).
+
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 - {{Pkg|efilinux-efi}} and {{AUR|efilinux-efi-x86_64-git}} (only for x86_64 UEFI).
 +
 
 +
== Package Naming Guidelines ==
 +
 
 +
UEFI bootloader package(s) should be suffixed with {{ic|-efi-x86_64}} or {{ic|-efi-i386}} to denote package built for 64-bit and 32-bit UEFI respectively. If a single package contains both 64-bit and 32-bit UEFI applications, then {{ic|-efi}} suffix should be used in the '''pkgname'''.
  
==See also==
+
== See also ==
  
 
* [http://www.rodsbooks.com/efi-bootloaders/ Rod Smith - Managing EFI Boot Loaders for Linux]
 
* [http://www.rodsbooks.com/efi-bootloaders/ Rod Smith - Managing EFI Boot Loaders for Linux]

Revision as of 14:17, 19 December 2012

This page contains info about various UEFI Bootloaders capable of booting Linux kernel. It is recommended to read the UEFI and GPT pages before reading this page. The following bootloaders (listed in decreasing order of stability) are explained here:

  1. Linux Kernel EFISTUB
  2. GRUB 2.x
  3. Gummiboot
  4. ELILO
  5. EFILINUX
  6. SYSLINUX (GIT Alpha Version)

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 EFI BOOT STUB by upstream or EFISTUB in short. EFISTUB should enabled by setting 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

  1. Create an FAT32 UEFI System Partition - Unified_Extensible_Firmware_Interface#Create_an_UEFI_System_Partition_in_Linux
  2. Mount the UEFI System Partition at /boot/efi.
  3. Create /boot/efi/EFI/arch/ directory.
  4. Copy /boot/vmlinuz-linux to /boot/efi/EFI/arch/vmlinuz-arch.efi . The .efi file extension is very important as some UEFI firmwares refuse to launch a file without the .efi file extension. Important: Remember that the file is called vmlinuz, but not vmlinux.
  5. Copy /boot/initramfs-linux.img to /boot/efi/EFI/arch/initramfs-arch.img.
  6. Copy /boot/initramfs-linux-fallback.img to /boot/efi/EFI/arch/initramfs-arch-fallback.img.
Note: There exists a patch for the kernel that allows passing kernel parameters via a file named linux.conf placed in the same directory as the kernel when booting via EFISTUB; example
/boot/efi/EFI/arch/linux.conf
root=UUID=xxxx ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-arch.img
As of at least commit 29594404d7fe73cd80eaa4ee8c43dcc53970c60e, the linux.conf patch has not been merged; you will need to apply it yourself if you wish to use this feature.

Finally, jump to #Booting_EFISTUB choose a way to get your machine to make use of the new EFISTUB you've just created.

Note: The kernel and initramfs files at /boot/efi/EFI/arch/ should be updated everytime those files in /boot are updated.
Warning: In Linux Kernel EFISTUB booting, 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 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 updated in /boot, like during package updates or during manual run of mkinitcpio etc.

For this create the files as defined below:

/etc/systemd/system/efistub-update.path
[Unit]
Description=Copy EFISTUB Kernel to UEFISYS Partition

[Path]
PathChanged=/boot/vmlinuz-linux
PathChanged=/boot/initramfs-linux.img
PathChanged=/boot/initramfs-linux-fallback.img

[Install]
WantedBy=multi-user.target
/etc/systemd/system/efistub-update.service
[Unit]
Description=Copy EFISTUB Kernel to UEFISYS Partition

[Service]
Type=oneshot
ExecStart=/bin/cp -f /boot/vmlinuz-linux /boot/efi/EFI/arch/vmlinuz-arch.efi
ExecStart=/bin/cp -f /boot/initramfs-linux.img /boot/efi/EFI/arch/initramfs-arch.img
ExecStart=/bin/cp -f /boot/initramfs-linux-fallback.img /boot/efi/EFI/arch/initramfs-arch-fallback.img

After creating the files run:

# systemctl enable efistub-update.path
# systemctl start efistub-update.path

Sync EFISTUB Kernel in UEFISYS partition using Incron

Incron can also be used to automatically sync the EFISTUB kernel after updates.

First, install the 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.

File: /usr/local/bin/efistub-update.sh
#!/bin/sh
/bin/cp -f /boot/vmlinuz-linux /boot/efi/EFI/arch/vmlinuz-arch.efi
/bin/cp -f /boot/initramfs-linux.img /boot/efi/EFI/arch/initramfs-arch.img
/bin/cp -f /boot/initramfs-linux-fallback.img /boot/efi/EFI/arch/initramfs-arch-fallback.img

Specify which file to watch for changes in /etc/incron.d/efistub-update.conf. The first parameter is the file to watch: /boot/initramfs-linux-fallback.img. The second parameter IN_CLOSE_WRITE is the action to watch for. The third parameter /usr/local/bin/efistub-update.sh is the script to execute.

File: /etc/incron.d/efistub-update.conf
/boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update.sh

Now just add incrond to the daemon list in /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.

File: /usr/lib/initcpio/install/efistub-update
#!/usr/bin/env bash

build() {
    local kernel= image=
    while getopts ':c:S:' OPT; do
        case $OPT in
        'c') kernel=$OPTARG;;
        'S') image=$OPTARG;;
        esac
    done

    /root/watch.sh $image $kernel &
}

help() {
    cat <<HELPEOF
This hook simply waits for mkinitcpio to finish and copies the finished ramdisk and kernel to UEFI
HELPEOF
}

# vim: set ft=sh ts=4 sw=4 et:


File: /root/watch.sh
#!/bin/bash

EFI_DIR="/boot/efi/EFI/arch"

INITRD=$1
KERNEL=$2

EFI_IMAGE="$EFI_DIR/${KERNEL##*/}.efi"
EFI_INITRD="$EFI_DIR/${INITRD##*/}"

while [[ -d "/proc/$PPID" ]]; do
    sleep 1
done

cp $INITRD $EFI_INITRD
cp $KERNEL $EFI_IMAGE
echo "Synced $INITRD to $EFI_DIR"


Then simply add efistub-update to the list of hooks in /etc/mkinitcpio.conf

Booting EFISTUB

There are various ways of booting EFISTUB kernels. Those described here are:

  1. Using rEFInd UEFI Boot Manager <-- Nice boot GUI.
  2. Using Gummiboot Boot Manager
  3. Using UEFI Shell
  4. Using efibootmgr entry <-- will load Arch Linux directly. No GUI.

Using rEFInd

rEFInd is a fork of rEFIt Boot Manager (used in Intel Macs) by Rod Smith (author of 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 .

Install the refind-efi package from [extra]

# pacman -S refind-efi

Then run the below commands ($esp is the mountpoint of UEFISYS partition)

# mkdir -p $esp/EFI/refind

For 64-bit UEFI

# cp /usr/lib/refind/refindx64.efi $esp/EFI/refind/refindx64.efi

For 32-bit UEFI

# cp /usr/lib/refind/refindia32.efi $esp/EFI/refind/refindia32.efi

Common commands:

# cp /usr/lib/refind/config/refind.conf $esp/EFI/refind/refind.conf
# cp -r /usr/share/refind/icons $esp/EFI/refind/icons

Edit $esp/EFI/refind/refind.conf according to your requirements. The file is well documented/commented. After that create $esp/EFI/arch/refind_linux.conf as shown below (example):

$esp/EFI/arch/refind_linux.conf
"Boot with defaults" "root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 ro rootfstype=ext4 add_efi_memmap systemd.unit=graphical.target"
"Boot to Terminal"   "root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 ro rootfstype=ext4 add_efi_memmap systemd.unit=multi-user.target"

Please notice the difference between the standard UUID and the PARTUUID shown by ls -l /dev/disk/by-partuuid/.

Note: refind_linux.conf should be in the same directory as the kernel and initramfs files, not the directory refindx64.efi resides.

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.

# modprobe efivars
# efibootmgr -c -g -d /dev/sdX -p Y -w -L "rEFInd" -l '\EFI\refind\refindx64.efi'

where /dev/sdX is the drive and Y is the partition number of UEFISYS in /dev/sdXY.

In case of Apple Macs, try mactel-bootAUR 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 /mnt/efi within OSX, do

$ sudo bless --setBoot --folder /mnt/efi/EFI/refind --file /mnt/efi/EFI/refind/refindx64.efi

Using gummiboot

Gummiboot is a UEFI Boot Manager which provides a nice menu for EFISTUB Kernels. It is a new program and relatively untested compared to rEFInd . It is available in [extra] as gummiboot-efi. See http://freedesktop.org/wiki/Software/gummiboot for more info.

Using UEFI Shell

It is possible to launch EFISTUB kernel form UEFI Shell as if it is 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-arch.efi root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-arch.img

Using efibootmgr entry

Note: This menthod may not work due to limitations in how the kernel handles uefi runtime variables. For example in Lenovo Thinkpads the initrd path is truncated (verified using efibootmgr -v command) and therefore the kernel fails to boot.
Note: Some UEFI firmwares may not support embedding command line parameters to uefi applications in the boot entries.

It is possible to directly embed the kernel parameters within the boot entry created by efibootmgr. This means that in your BIOS/UEFI you will be able to select Arch Linux directly in the default boot order, and on startup it will boot into Arch directly without any kind of boot selection GUI.

Do (as root):

Install efibootmgr if you haven't already.

 # pacman -S --needed efibootmgr

Determine the UUID or PARTUUID of your boot device (ie. the partition for /, not the EFI boot partition)

# blkid

Load the EFI module.

# modprobe efivars

Finally, add the efistub. WARNING: Make sure you replace the following before running this command:

  • 3518bb68-d01e-45c9-b973-0b5d918aae96 -- with the UUID of your / partition. (This is not PARTUUID!)
  • ext4 -- if you use a different file system.
  • /dev/sda -- the drive that contains the EFI boot partition.
  • -p 1 -- the partition number of the EFI boot partition.
# echo 'root=UUID=3518bb68-d01e-45c9-b973-0b5d918aae96 ro rootfstype=ext4 add_efi_memmap initrd=\EFI\arch\initramfs-arch.img' | iconv -f ascii -t ucs2 | efibootmgr -c -g -d /dev/sda -p 1 -L "Arch Linux" -l '\EFI\arch\vmlinuz-arch.efi' -@ -

or you can just run the following line (remember to replace /dev/sda1):

# echo "root=UUID=$(blkid /dev/sda1 -o value -s UUID) ro rootfstype=ext4 add_efi_memmap initrd=\\EFI\\arch\\initramfs-arch.img" | iconv -f ascii -t ucs2 | efibootmgr -c -g -d /dev/sda -p 1 -L "Arch Linux" -l '\EFI\arch\vmlinuz-arch.efi' -@ -
Note: The trailing hyphen after --append-binary-args or -@ is required to instruct efibootmgr to read the parameters from STDIN (standard input). The code should be --append-binary-args - or -@ - .

More info about efibootmgr at UEFI#efibootmgr. Forum post https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 .

Note: Some firmwares may have trouble with the "initrd path" when piping in ucs-2 as shown above. In this case, one may put vmlinuz-linux.efi and the initramfs in the root of the ESP and adjust the efibootmgr entry accordingly.

GRUB 2.x

GRUB 2.x contains its own filesystem drivers and does not rely on the firmware to access the files. It can directly read files from /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 - grub-efi-x86_64-bzrAUR.

SYSLINUX

Note: Syslinux UEFI support is currently part of version 6.00-preXX or in firmware branch of upstream git repo. It is considered alpha quality by upstream. The below information is provided mainly to enable bug-testing. Please report all issues upstream.
Note: Syslinux UEFI can boot only those kernels that support EFI Handover Protocol. Thus LTS kernels are not supported.

Install syslinux-efi-gitAUR AUR package and copy /usr/lib/syslinux/efi64/* to $esp/EFI/syslinux/ ($esp is the mountpoint of UEFISYS partition) (efi64 is for x86_64 UEFI firmwares, replace with efi32 for i386 UEFI firmwares), and then create a boot entry using efibootmgr in the firmware boot manager.

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 elilo.conf is similar to LILO's config file. AUR package - elilo-efi-x86_64AUR (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 - efilinux-efi and efilinux-efi-x86_64-gitAUR (only for x86_64 UEFI).

Package Naming Guidelines

UEFI bootloader package(s) should be suffixed with -efi-x86_64 or -efi-i386 to denote package built for 64-bit and 32-bit UEFI respectively. If a single package contains both 64-bit and 32-bit UEFI applications, then -efi suffix should be used in the pkgname.

See also