Uefi boot linux without grub

EFISTUB

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.

  • 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

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

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 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.

  • 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.
  • Some firmwares (notably Lenovo and Dell laptops) do not pass command line parameters from the boot entries in NVRAM to the EFI binaries.[1] In that case, the kernel and parameters can be combined into a unified kernel image, then create a boot entry with the resulting .efi file.

efibootmgr

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

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

or create a boot entry with efibootmgr and hibernation on swap partition:

# efibootmgr --create --disk /dev/sdX --part Y --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=block_device_identifier resume=block_device_identifier rw initrd=\initramfs-linux.img'

Where /dev/sdX and Y are the drive and partition number where the ESP is located. Change the root= and resume= parameters to reflect your Linux root and swap partitions.

Читайте также:  Linux device interrupt 17

Note: See kernel parameters for supported device name formats, and persistent block device naming for how to obtain the corresponding value.

If omitted, then 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 --bootorder XXXX,XXXX --unicode

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

  • https://github.com/de-arl/auto-UEFI-entry is a tool to create the commands
  • 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 does not support editing existing entries.
  • The forum post titled The linux kernel with build in bootloader? might also be of interest.

bcfg

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:

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

To view the current boot entries:

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:

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

root=/dev/sda2 rw 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 

kesboot

You can also simplify and automate the work with EFISTUB using a script from the kesboot-git AUR package. It also contains a pacman hook that can add and remove EFI variables during actions with packages.

First, install the package, and then configure the /etc/kesboot.conf file:

CMDLINES=('linux' 'acpi=on' 'linux-zen' 'iommu=off')

Note: If you use a hook (the variables INSTALL_HOOK and REMOVE_HOOK ), then it will overwrite the CMDLINES array every time it runs (preserving the contents of all records).

The package also contains a program for the initial configuration of the EFI boot. After mounting the ESP directory, run

Читайте также:  Linux cpu usage monitor

Using UEFI Shell

If you do not want to create a permanent boot entry it is possible to launch the kernel from UEFI Shell since 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:

Using a startup.nsh script

Some UEFI implementations do not retain EFI variables between cold boots (e.g. VirtualBox before version 6.1) 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.

Troubleshooting

EFISTUB does not work on some Dell systems

Several generation Dell firmwares are wrongly passing the arguments to the bootloader, thus making EFISTUB parse a null command line which normally means unbootable system (see the complete linux-efi thread).

A workaround has been found since Linux 5.10 to correct this behavior (see this commit ). For Linux < 5.10, you can use an efi-packer like arch-efiboot, or a different bootloader.

Changes to boot entries are not applied

Some motherboards, such as Haswell-era Asus boards (as encountered on the french forum), will not notice changes to boot entries unless the system is booted with another pre-existing boot entry before booting the updated EFISTUB entry.

See also

Источник

Boot Linux without GRUB

To boot the Linux Kernel, most distro use a bootloader and one of the most popular is GRUB. But did you know you can directly boot the Kernel without using a bootloader?

DISCLAIMER: This is only for fun and learning, I do not advise anyone to do that on their main system. Be safe, use a VM.

VM setup#

Just a quick recap of what is needed (mostely stolen from powersj’s excelent blog post).

Setup the user-data (for cloud-init) to be able to SSH into the VM:

Читайте также:  Терминал linux для виндовс

Copy the EFI vars to a temp place (they will get modified)

Download an Ubuntu cloud-image and launch the VM with the cloud-init metadata and the EFI firemware.

 To SSH into the VM: ssh [email protected] -p 2222

In practice#

First, check if your Kernel config allows this:

 Then, copy the Kernel and initrd to the EFI partition:
cp -v /boot/initrd.img-* /boot/efi/EFI/ cp -v /boot/vmlinuz-$(uname -r) /boot/efi/EFI/vmlinuz-$(uname -r).efi 

In theory, you can put those files wherever you want on the EFI partition (Ubuntu uses /EFI/ubuntu for example). Just be carefull about the length of the EFI stub path, see this thread.

Now we need to find out some information about the system:

  • On which device (and partition) is located the root filesystem?
  • On which device and which partition is the EFI partition?
$ lsblk -o NAME,MOUNTPOINT,LABEL NAME MOUNTPOINT LABEL fd0 loop0 /snap/core20/1169 loop1 /snap/lxd/21780 loop2 /snap/snapd/13640 sr0 vda ├─vda1 / cloudimg-rootfs ├─vda14 └─vda15 /boot/efi UEFI vdb cidata 

On this system, the root filesystem is in /dev/vda1 and the EFI partition is on the same device /dev/vda on partition number 15.

Now, let’s add a new boot entry in the UEFI boot manager

efibootmgr --create --disk /dev/vda --part 15 --label grub-less --loader "\EFI\vmlinuz-$(uname -r).efi" -u "root=/dev/vda1 initrd=\\EFI\\initrd.img-$(uname -r) ro console=ttyS0" 
  • efibootmgr is a CLI tool to manipulate the UEFI boot manager (no one could have guessed it :D)
  • —create indicates we want to create a new boot entry
  • —disk specifies the disk containing the bootloader (here the Kernel)
  • —part is the partition where the boot loader (here the Kernel) is
  • —label is simply the name we want to give to this new boot entry
  • —loader is the actual bootloader we want to call, here it is the Kernel we previously copied
  • -u is used to pass arguments to the boot loader. Here we pass the location of initrd and the other usual Kernel command line arguments (check /proc/cmdline to find out which cmdline arguments are currently in use)

The current boot entries can then be checked with: efibootmgr (no arg). The new boot entry we just created should already be the first one in the bootorder list.

Reboot!! The system should start directly without going through the GRUB.

At the very beginning of the serial console, we can find:

BdsDxe: loading Boot0008 "grub-less" from HD(15,GPT,CB5D0560-825B-4575-A9E3-F3263C410054,0x2800,0x35000)/\EFI\vmlinuz-5.13.0-20-generic.efi BdsDxe: starting Boot0008 "grub-less" from HD(15,GPT,CB5D0560-825B-4575-A9E3-F3263C410054,0x2800,0x35000)/\EFI\vmlinuz-5.13.0-20-generic.efi EFI stub: Loaded initrd from command line option 

Troubleshooting#

If something goes really wrong and the system doesn’t boot, use this post to mount the EFI partition locally and simply delete the Kernel’s EFI from it. The new entry will just fail to find the EFI stub and fallback to the old boot entry.

To delete a boot entry: efibootmgr -b NUM -B

Refs#

  • https://askubuntu.com/a/511019 The main source for this blog post
  • https://www.kubuntuforums.net/showthread.php?60193-Going-GRUB-less-with-UEFI&p=309923&viewfull=1#post309923 An undocumented issue
  • https://powersj.io/posts/ubuntu-qemu-cli/ to know more about how to use QEMU
  • https://docs.kernel.org/admin-guide/efi-stub.html The official Kernel doc about this Kernel feature
  • https://www.kernel.org/doc/html/v4.14/admin-guide/kernel-parameters.html more about Kernel command line

Источник

Оцените статью
Adblock
detector