Difference between revisions of "EFISTUB"

From ArchWiki
Jump to navigation Jump to search
(remove "Boot loaders" from related articles)
(move uefi shell option to end, clarify the difference from the previous section)
 
(33 intermediate revisions by 10 users not shown)
Line 2: Line 2:
 
[[es:EFISTUB]]
 
[[es:EFISTUB]]
 
[[ja:EFISTUB]]
 
[[ja:EFISTUB]]
 +
[[pt:EFISTUB]]
 
[[ru:EFISTUB]]
 
[[ru:EFISTUB]]
 
{{Related articles start}}
 
{{Related articles start}}
Line 8: Line 9:
 
{{Related articles end}}
 
{{Related articles end}}
  
The Linux kernel supports EFISTUB booting which allows [[EFI]] firmware to load the kernel as an EFI executable. The option is enabled by default on Arch Linux kernels, or if compiling a the kernel one can activate it by setting {{ic|1=CONFIG_EFI_STUB=y}} in the Kernel configuration. See [https://www.kernel.org/doc/Documentation/efi-stub.txt The EFI Boot Stub] for more information.
+
The Linux kernel supports EFISTUB booting which allows [[EFI]] firmware to load the kernel as an EFI executable. The option is enabled by default on Arch Linux kernels, or if compiling the kernel one can activate it by setting {{ic|1=CONFIG_EFI_STUB=y}} in the Kernel configuration. See [https://www.kernel.org/doc/Documentation/efi-stub.txt The EFI Boot Stub] for more information.
  
 
With EFISTUB a kernel can be booted directly by a UEFI motherboard or indirectly using a [[boot loader]]. Using a boot loader is recommended if you have multiple kernel/initramfs pairs and your motherboard's UEFI boot menu is not easy to use.
 
With EFISTUB a kernel can be booted directly by a UEFI motherboard or indirectly using a [[boot loader]]. Using a boot loader is recommended if you have multiple kernel/initramfs pairs and your motherboard's UEFI boot menu is not easy to use.
Line 18: Line 19:
 
{{Tip|
 
{{Tip|
 
* [[pacman]] will directly update the kernel that the EFI firmware will read if you mount the ESP to {{ic|/boot}}.  
 
* [[pacman]] will directly update the kernel that the EFI firmware will read if you mount the ESP to {{ic|/boot}}.  
* You can keep the kernel and initramfs off of the ESP if you use a boot manager which has a file system driver for the partition where they reside, e.g. [[rEFInd]].}}
+
* You can keep the kernel and initramfs off of the ESP if you use a boot manager which has a file system driver for the partition where they reside, e.g. [[rEFInd]].
 +
}}
  
 
== Booting EFISTUB ==
 
== Booting EFISTUB ==
Line 28: Line 30:
 
There are several UEFI boot managers which can provide additional options or simplify the process of UEFI booting - especially if you have multiple kernels/operating systems. See [[Arch boot process#Boot loader]] for more information.
 
There are several UEFI boot managers which can provide additional options or simplify the process of UEFI booting - especially if you have multiple kernels/operating systems. See [[Arch boot process#Boot loader]] for more information.
  
=== Using UEFI Shell ===
+
=== Using UEFI directly ===
  
It is possible to launch an EFISTUB kernel from 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.
+
UEFI is designed to remove the need for an intermediate bootloader such as [[GRUB]]. If your motherboard has a good UEFI implementation, it is possible to embed the kernel parameters within a UEFI boot entry and for the motherboard to boot Arch directly. You can use [[efibootmgr]] or UEFI Shell v2 to modify your motherboard's boot entries.
  
> fs0:
+
{{Note|Outdated UEFI implementations may have compatibility issues with the Linux kernel. If there is a newer version of your UEFI with bug fixes, consider flashing it with the manufacturer's recommended tool.}}
> \vmlinuz-linux root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rw initrd=\initramfs-linux.img
 
 
 
To avoid needing to remember all of your kernel parameters every time, you can save the executable command to a shell script such as {{ic|archlinux.nsh}} on your UEFI System Partition, then run it with:
 
 
 
> fs0:
 
> archlinux
 
 
 
=== Using UEFI directly ===
 
 
 
UEFI is designed to remove the need for an intermediate bootloader such as [[GRUB]]. If your motherboard has a good UEFI implementation, it is possible to embed the kernel parameters within a UEFI boot entry and for the motherboard to boot Arch directly. You can use {{Pkg|efibootmgr}} or UEFI Shell v2 to modify your motherboard's boot entries.
 
  
 
==== efibootmgr ====
 
==== efibootmgr ====
  
The command looks like
+
To create a boot entry with ''efibootmgr'' that will load the kernel:
  
 
  # efibootmgr --disk ''/dev/sdX'' --part ''Y'' --create --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=PARTUUID=''XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'' rw initrd=\initramfs-linux.img' --verbose
 
  # efibootmgr --disk ''/dev/sdX'' --part ''Y'' --create --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=PARTUUID=''XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'' rw initrd=\initramfs-linux.img' --verbose
  
Where {{ic|''/dev/sdX''}} and {{ic|''Y''}} are the drive and partition number where the ESP is located. Change the {{ic|1=root=}} parameter to reflect your Linux root partition. Note that the {{ic|-u}}/{{ic|--unicode}} argument in quotes is just the list of [[kernel parameters]], so you may need to add additional parameters (e.g. for [[Suspend and hibernate#Required kernel parameters|suspend to disk]] or [[microcode]]).
+
Where {{ic|''/dev/sdX''}} and {{ic|''Y''}} are the drive and partition number where the ESP is located. Change the {{ic|1=root=}} parameter to reflect your Linux root partition, see [[kernel parameters#Parameter list|kernel parameters]] for supported device name formats, and [[persistent block device naming]] for how to obtain the corresponding value. If omitted, the the first partition on {{ic|''/dev/sda''}} is used as the ESP.
  
{{Tip|Save the command for creating your boot entry in a shell script somewhere, which makes it easier to modify (when changing kernel parameters, for example).}}
+
Note that the {{ic|-u}}/{{ic|--unicode}} argument in quotes is just the list of [[kernel parameters]], so you may need to add additional parameters (e.g. for [[Suspend and hibernate#Required kernel parameters|suspend to disk]] or [[microcode]]).
  
 
After adding the boot entry, you can verify the entry was added properly with:
 
After adding the boot entry, you can verify the entry was added properly with:
Line 58: Line 50:
 
  # efibootmgr --verbose
 
  # efibootmgr --verbose
  
{{Note|Some kernel and {{ic|efibootmgr}} version combinations might refuse to create new boot entries. This could be due to lack of free space in the NVRAM. You can try deleting any EFI dump files
+
To set the boot order:
 
 
# rm /sys/firmware/efi/efivars/dump-*
 
 
 
Or, as a last resort, boot with the {{ic|efi_no_storage_paranoia}} kernel parameter. You can also try to downgrade your efibootmgr install to version 0.11.0 if you have it available in your cache. This version works with Linux version 4.0.6. See the bug discussion {{Bug|34641}} for more information.
 
}}
 
 
 
To set the boot order, run:
 
  
 
  # efibootmgr --bootorder ''XXXX'',''XXXX'' --verbose
 
  # efibootmgr --bootorder ''XXXX'',''XXXX'' --verbose
  
where ''XXXX'' is the number that appears in the output of {{ic|efibootmgr}} command against each entry.
+
Where ''XXXX'' is the number that appears in the output of ''efibootmgr'' command against each entry.
  
More info about efibootmgr at [[UEFI#efibootmgr]]. Forum post https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 .
+
{{Tip|1=<nowiki></nowiki>
 +
* It is convenient to save the command to create the boot entry in a shell script, which makes it easier to modify, for example when changing kernel parameters. In doing so, consider automating the deletion of old boot entries, as ''efibootmgr'' currently [https://github.com/rhboot/efibootmgr/issues/49 does not support editing existing entries].
 +
* The forum post titled [https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 The linux kernel with build in bootloader?] might also be of interest.
 +
}}
  
 
==== efibootmgr with .efi file ====
 
==== efibootmgr with .efi file ====
 
   
 
   
If using {{AUR|cryptboot}} and {{AUR|sbupdate-git}} to generate your own keys for [[Secure Boot#Using_your_own_keys|Secure Boot]] and sign the initramfs and kernel then create a bootable ''.efi'' image, {{Pkg|efibootmgr}} can be used directly to boot the ''.efi'' file:
+
If using {{AUR|cryptboot}} and {{AUR|sbupdate-git}} to generate your own keys for [[Secure Boot#Using_your_own_keys|Secure Boot]] and sign the initramfs and kernel then create a bootable ''.efi'' image, ''efibootmgr'' can be used directly to boot the ''.efi'' file:
  
 
  # efibootmgr --create --disk /dev/sdX --part ''partition_number'' --label "''label''" --loader "EFI\''folder''\''file''.efi" --verbose
 
  # efibootmgr --create --disk /dev/sdX --part ''partition_number'' --label "''label''" --loader "EFI\''folder''\''file''.efi" --verbose
Line 83: Line 71:
 
==== UEFI Shell ====
 
==== UEFI Shell ====
  
Some UEFI implementations make it difficult to modify the NVRAM successfully using efibootmgr. If efibootmgr cannot successfully create an entry, you can use the [[UEFI#bcfg|bcfg]] command in UEFI Shell v2 (i.e., from the Arch Linux live iso).
+
Some UEFI implementations make it difficult to modify the NVRAM successfully using ''efibootmgr''. If ''efibootmgr'' cannot successfully create an entry, you can use the [[UEFI#bcfg|bcfg]] command in UEFI Shell v2 (i.e., from the [https://www.archlinux.org/download/ Arch Linux live iso]).
  
First, find out the device number where your [[ESP]] resides by using:
+
First, find out the device number where your [[ESP]] resides with:
  
 
  Shell> map
 
  Shell> map
  
In this example, {{ic|1}} is used as the device number. To list the contents of the [[ESP]] do:
+
In this example, {{ic|1}} is used as the device number. To list the contents of the [[ESP]]:
  
 
  Shell> ls fs1:
 
  Shell> ls fs1:
  
To view the current boot entries do:
+
To view the current boot entries:
  
 
  Shell> bcfg boot dump
 
  Shell> bcfg boot dump
Line 101: Line 89:
 
  Shell> bcfg boot add ''N'' fs1:\vmlinuz-linux "Arch Linux"
 
  Shell> bcfg boot add ''N'' fs1:\vmlinuz-linux "Arch Linux"
  
where {{ic|''N''}} is the location where the entry will be added in the boot menu. 0 is the first menu item. Menu items already existing will be shifted in the menu without being discarded.
+
Where {{ic|''N''}} is the location where the entry will be added in the boot menu. 0 is the first menu item. Menu items already existing will be shifted in the menu without being discarded.
  
To add the necessary kernel options, first create a file on your ESP:
+
Add the necessary kernel options by creating a file on your ESP:
  
 
  Shell> edit fs1:\options.txt
 
  Shell> edit fs1:\options.txt
  
In the file add the boot line. For example:
+
In the file, add the boot line. For example:
  
 
  root=/dev/sda2 ro initrd=\initramfs-linux.img
 
  root=/dev/sda2 ro initrd=\initramfs-linux.img
  
{{Note|Add extra spaces in the beginning of the line in the file. There is a byte order mark at the beginning of the line that will squash any character next to it which will cause an error when booting.}}
+
{{Note|Add extra spaces in the beginning of the line in the file. There is a [[Wikipedia:Byte order mark|byte order mark]] at the beginning of the line that will squash any character next to it which will cause an error when booting.}}
  
 
Press {{ic|F2}} to save and then {{ic|F3}} to exit.
 
Press {{ic|F2}} to save and then {{ic|F3}} to exit.
  
To add these options to your previous entry do:
+
Add these options to your previous entry:
  
 
  Shell> bcfg boot -opt ''N'' fs1:\options.txt
 
  Shell> bcfg boot -opt ''N'' fs1:\options.txt
Line 124: Line 112:
  
 
  Shell> bcfg boot rm ''N''
 
  Shell> bcfg boot rm ''N''
 +
 +
==== More tools ====
 +
 +
Some of the tools above, and more, are briefly discussed in [[rEFInd#Tools]].
  
 
==== Using a startup.nsh script ====
 
==== Using a startup.nsh script ====
Line 131: Line 123:
 
The [http://www.uefi.org/sites/default/files/resources/UEFI_Shell_Spec_2_0.pdf UEFI Shell Specification 2.0] establishes that a script called {{ic|startup.nsh}} at the root of the ESP partition will always be interpreted and can contain arbitrary instructions; among those you can set a bootloading line. Make sure you mount the ESP partition on {{ic|/boot}} and create a {{ic|startup.nsh}} script that contains a kernel bootloading line. For example:
 
The [http://www.uefi.org/sites/default/files/resources/UEFI_Shell_Spec_2_0.pdf UEFI Shell Specification 2.0] establishes that a script called {{ic|startup.nsh}} at the root of the ESP partition will always be interpreted and can contain arbitrary instructions; among those you can set a bootloading line. Make sure you mount the ESP partition on {{ic|/boot}} and create a {{ic|startup.nsh}} script that contains a kernel bootloading line. For example:
  
  vmlinuz-linux rw root=/dev/sdX [rootfs=myfs] [rootflags=myrootflags] \
+
  vmlinuz-linux rw root=/dev/sd''X'' [rootfs=''myfs''] [rootflags=''myrootflags''] \
   [kernel.flag=foo] [mymodule.flag=bar] \
+
   [kernel.flag=''foo''] [''mymodule''.flag=''bar''] \
 
   [initrd=\intel-ucode.img] initrd=\initramfs-linux.img
 
   [initrd=\intel-ucode.img] initrd=\initramfs-linux.img
  
 
This method will work with almost all UEFI firmware versions you may encounter in real hardware, you can use it as last resort. '''The script must be a single long line.''' Sections in brackets are optional and given only as a guide. Shell style linebreaks are for visual clarification only. FAT filesystems use the backslash as path separator and in this case, the backslash declares the initramfs is located in the root of the ESP partition. Only Intel microcode is loaded in the booting parameters line; AMD microcode is read from disk later during the boot process; this is done automatically by the kernel.
 
This method will work with almost all UEFI firmware versions you may encounter in real hardware, you can use it as last resort. '''The script must be a single long line.''' Sections in brackets are optional and given only as a guide. Shell style linebreaks are for visual clarification only. FAT filesystems use the backslash as path separator and in this case, the backslash declares the initramfs is located in the root of the ESP partition. Only Intel microcode is loaded in the booting parameters line; AMD microcode is read from disk later during the boot process; this is done automatically by the kernel.
 +
 +
=== Using UEFI Shell ===
 +
 +
If you do not want to create a permanent boot entry it is possible to launch the kernel from UEFI Shell as if it is a normal UEFI application:
 +
 +
> fs0:
 +
> \vmlinuz-linux root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rw initrd=\initramfs-linux.img
 +
 +
In this case, the kernel parameters are passed as normal parameters to the launched EFISTUB kernel file.
 +
 +
To avoid needing to remember all of your kernel parameters every time, you can save the executable command to a shell script such as {{ic|archlinux.nsh}} on your UEFI System Partition, then run it with:
 +
 +
> fs0:
 +
> archlinux
 +
 +
== Troubleshooting ==
 +
 +
=== Cannot create a new boot entry with efibootmgr ===
 +
 +
Some kernel and ''efibootmgr'' version combinations might refuse to create new boot entries. This could be due to lack of free space in the NVRAM. You can try deleting any EFI dump files:
 +
 +
# rm /sys/firmware/efi/efivars/dump-*
 +
 +
Or, as a last resort, boot with the {{ic|efi_no_storage_paranoia}} kernel parameter. You can also try to [[downgrade]] your ''efibootmgr'' install to version 0.11.0. This version works with Linux version 4.0.6. See the bug discussion {{Bug|34641}}, in particular the [https://bugs.archlinux.org/task/34641#comment111365 closing comment], for more information.
 +
 +
=== Newly created boot entries are removed ===
 +
 +
Some motherboards may remove boot entries after a couple of boots. This could be due to lack of free space in the NVRAM. To prevent this from occuring, it may help to reduce the amount of Linux boot entries being added by ''efibootmgr'' by minimizing your entry creation process, as well as reducing the amount of automatic drive boot entries by the [[Wikipedia:Unified Extensible Firmware Interface#CSM booting|Compatibility Support Module (CSM)]] by disabling it from your UEFI settings.
  
 
== See also ==
 
== See also ==

Latest revision as of 20:15, 6 October 2019

The Linux kernel supports EFISTUB booting which allows EFI firmware to load the kernel as an EFI executable. The option is enabled by default on Arch Linux kernels, or if compiling the kernel one can activate it by setting CONFIG_EFI_STUB=y in the Kernel configuration. See The EFI Boot Stub for more information.

With EFISTUB a kernel can be booted directly by a UEFI motherboard or indirectly using a boot loader. Using a boot loader is recommended if you have multiple kernel/initramfs pairs and your motherboard's UEFI boot menu is not easy to use.

Preparing for EFISTUB

First, you must create an EFI system partition and choose how it is mounted. See EFI system partition#Mount the partition for all available ESP mounting options.

Tip:
  • pacman will directly update the kernel that the EFI firmware will read if you mount the ESP to /boot.
  • You can keep the kernel and initramfs off of the ESP if you use a boot manager which has a file system driver for the partition where they reside, e.g. rEFInd.

Booting EFISTUB

Note: Linux Kernel EFISTUB initramfs path should be relative to the EFI System Partition's root and use backslashes (in accordance with EFI standards). For example, if the initramfs is located in esp/EFI/arch/initramfs-linux.img, the corresponding UEFI formatted line should be initrd=\EFI\arch\initramfs-linux.img. In the following examples we will assume that everything is under esp/.

Using a boot manager

There are several UEFI boot managers which can provide additional options or simplify the process of UEFI booting - especially if you have multiple kernels/operating systems. See Arch boot process#Boot loader for more information.

Using UEFI directly

UEFI is designed to remove the need for an intermediate bootloader such as GRUB. If your motherboard has a good UEFI implementation, it is possible to embed the kernel parameters within a UEFI boot entry and for the motherboard to boot Arch directly. You can use efibootmgr or UEFI Shell v2 to modify your motherboard's boot entries.

Note: Outdated UEFI implementations may have compatibility issues with the Linux kernel. If there is a newer version of your UEFI with bug fixes, consider flashing it with the manufacturer's recommended tool.

efibootmgr

To create a boot entry with efibootmgr that will load the kernel:

# efibootmgr --disk /dev/sdX --part Y --create --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw initrd=\initramfs-linux.img' --verbose

Where /dev/sdX and Y are the drive and partition number where the ESP is located. Change the root= parameter to reflect your Linux root partition, see kernel parameters for supported device name formats, and persistent block device naming for how to obtain the corresponding value. If omitted, the the first partition on /dev/sda is used as the ESP.

Note that the -u/--unicode argument in quotes is just the list of kernel parameters, so you may need to add additional parameters (e.g. for suspend to disk or microcode).

After adding the boot entry, you can verify the entry was added properly with:

# efibootmgr --verbose

To set the boot order:

# efibootmgr --bootorder XXXX,XXXX --verbose

Where XXXX is the number that appears in the output of efibootmgr command against each entry.

Tip:

efibootmgr with .efi file

If using cryptbootAUR and sbupdate-gitAUR to generate your own keys for Secure Boot and sign the initramfs and kernel then create a bootable .efi image, efibootmgr can be used directly to boot the .efi file:

# efibootmgr --create --disk /dev/sdX --part partition_number --label "label" --loader "EFI\folder\file.efi" --verbose

See efibootmgr(8) for an explanation of the options.

UEFI Shell

Some UEFI implementations make it difficult to modify the NVRAM successfully using efibootmgr. If efibootmgr cannot successfully create an entry, you can use the bcfg command in UEFI Shell v2 (i.e., from the Arch Linux live iso).

First, find out the device number where your ESP resides with:

Shell> map

In this example, 1 is used as the device number. To list the contents of the ESP:

Shell> ls fs1:

To view the current boot entries:

Shell> bcfg boot dump

To add an entry for your kernel, use:

Shell> bcfg boot add N fs1:\vmlinuz-linux "Arch Linux"

Where N is the location where the entry will be added in the boot menu. 0 is the first menu item. Menu items already existing will be shifted in the menu without being discarded.

Add the necessary kernel options by creating a file on your ESP:

Shell> edit fs1:\options.txt

In the file, add the boot line. For example:

root=/dev/sda2 ro initrd=\initramfs-linux.img
Note: Add extra spaces in the beginning of the line in the file. There is a byte order mark at the beginning of the line that will squash any character next to it which will cause an error when booting.

Press F2 to save and then F3 to exit.

Add these options to your previous entry:

Shell> bcfg boot -opt N fs1:\options.txt

Repeat this process for any additional entries.

To remove a previously added item do:

Shell> bcfg boot rm N

More tools

Some of the tools above, and more, are briefly discussed in rEFInd#Tools.

Using a startup.nsh script

Some UEFI implementations do not retain EFI variables between cold boots (e.g. VirtualBox) and anything set through the UEFI firmware interface is lost on poweroff.

The UEFI Shell Specification 2.0 establishes that a script called startup.nsh at the root of the ESP partition will always be interpreted and can contain arbitrary instructions; among those you can set a bootloading line. Make sure you mount the ESP partition on /boot and create a startup.nsh script that contains a kernel bootloading line. For example:

vmlinuz-linux rw root=/dev/sdX [rootfs=myfs] [rootflags=myrootflags] \
 [kernel.flag=foo] [mymodule.flag=bar] \
 [initrd=\intel-ucode.img] initrd=\initramfs-linux.img

This method will work with almost all UEFI firmware versions you may encounter in real hardware, you can use it as last resort. The script must be a single long line. Sections in brackets are optional and given only as a guide. Shell style linebreaks are for visual clarification only. FAT filesystems use the backslash as path separator and in this case, the backslash declares the initramfs is located in the root of the ESP partition. Only Intel microcode is loaded in the booting parameters line; AMD microcode is read from disk later during the boot process; this is done automatically by the kernel.

Using UEFI Shell

If you do not want to create a permanent boot entry it is possible to launch the kernel from UEFI Shell as if it is a normal UEFI application:

> fs0:
> \vmlinuz-linux root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rw initrd=\initramfs-linux.img

In this case, the kernel parameters are passed as normal parameters to the launched EFISTUB kernel file.

To avoid needing to remember all of your kernel parameters every time, you can save the executable command to a shell script such as archlinux.nsh on your UEFI System Partition, then run it with:

> fs0:
> archlinux

Troubleshooting

Cannot create a new boot entry with efibootmgr

Some kernel and efibootmgr version combinations might refuse to create new boot entries. This could be due to lack of free space in the NVRAM. You can try deleting any EFI dump files:

# rm /sys/firmware/efi/efivars/dump-*

Or, as a last resort, boot with the efi_no_storage_paranoia kernel parameter. You can also try to downgrade your efibootmgr install to version 0.11.0. This version works with Linux version 4.0.6. See the bug discussion FS#34641, in particular the closing comment, for more information.

Newly created boot entries are removed

Some motherboards may remove boot entries after a couple of boots. This could be due to lack of free space in the NVRAM. To prevent this from occuring, it may help to reduce the amount of Linux boot entries being added by efibootmgr by minimizing your entry creation process, as well as reducing the amount of automatic drive boot entries by the Compatibility Support Module (CSM) by disabling it from your UEFI settings.

See also