debian – How to Move the Bootloader from a Hard Drive to a USB Stick

boot-loaderdebiangrubluks

I've decided to move my Debian bootloader and /boot from the hard drive to a USB stick.
I'm using LUKS to en/decrypt my hard drive and the bootloader is the only unencrypted partition.

How can I easily do this? I want to remove it from
the hard drive, resize any of the partitions (/, /var, /tmp) to get the free space after I deleted /boot and put a new bootloader on the USB stick.
The Bootloader in use is GRUB it is on /dev/sda1.

Best Answer

Screw grub. It's probably some complexity it introduces that leads you to believe this is a difficult problem to solve. If your computer is less than 5 years old or so, then you're probably booting from a UEFI firmware, in which case your Debian-built linux kernel is already a bootloader.

  1. Partition the disk:

    printf %c\\n o y n 1 '' '' ef00 w y |
    gdisk /dev/usb-stick/or-whatever-path    
    
    • That's a scripted shortcut for the options you'd want to feed the program interactively. It will create a GUID partition table and a partition of type EFI-system that spans the whole disk.

    • The gdisk program is easy to use though - and so you might do better to go at it interactively instead. The target disk should not be mounted when it is run, and you'll probably need root rights to write the changes. As a general rule you can do pretty much whatever you want in that program without any effect until you write - so be sure when you do.

  2. Format the stick fat32:

    mkfs.vfat -nLABEL /dev/usb-stick/or-whatever-path
    
    • LABEL is whatever you want it to be. You should LABEL all disks, in my opinion.
  3. Install a boot-menu-manager if wanted. I like rEFInd:

    dpkg -i refind_0.8.7-1_amd64.deb
    
    • That probably won't install to the USB automatically, so afterward you may want to do...

      /path/to/refinds/install/dir/install.sh  --usedefault /dev/usbstick
      
    • If you use rEFInd, you'll want to do something like this after:

      mount /dev/usbstick /mnt
      mkdir -p /mnt/EFI/debian /esp
      cp -ar /boot/* /mnt/EFI/debian
      cat <<\TWONEWLINES >>/etc/fstab
          LABEL=LABEL      /esp  vfat  defaults      0 2
          /esp/EFI/debian  /boot none  bind,defaults 0 0
      TWONEWLINES
      cat <<\ONESIMPLECONFIG >/mnt/EFI/debian/refind_linux.conf
          "Debian Menu Entry" root=LABEL=rootlabel other_kernel_params
      ONESIMPLECONFIG
      
    • But you might skip rEFInd and just use the firmware's boot menu:

       efibootmgr -c -d /dev/rootdevice       \
                  -p 1 -L "Debian"            \
                  -l '\EFI\debian\kernelfile' \
                  -u root=/dev/sda3 kparams   \
                  initrd=EFI/debian/initramfs_image_file
      

And that's pretty much it. Pretty much forever - no more fuss. The firmware loads the kernel from the EFI-system partition you format on your USB stick. The kernel loads its initial root in the initramfs file. If you're already successfully booting LUKS then you must have already arranged for it to access its key somehow - your key is probably already in the initramfs image. If not, well, you'll want to put it in there - or on the USB.

The boot partition is a mount on a UEFI-system - there is absolutely no need for all of the old-timey nastiness surrounding embedding boot-loaders and MBRs and the rest. You just mount the boot from firmware, load a kernel executable, and go on your merry way.

The fstab stuff just --bind mounts a directory on your USB-stick over /boot - so all kernel updates will happen just as always. If you like yourself, you'll uninstall grub entirely, though. Its arcane update process - a bunch of scripts that read and/or generate other scripts in a wicked chain - is more than a little ridiculous and the kind of nightmare you can easily do without.

If you'll take my advice you'll use rEFInd, though. It has pretty menus, and you never have to worry about it - the effects of the install.sh script above can easily be reproduced (and is above, in large part) with a single cp command. It's just a static directory called /EFI/BOOT on the EFI-system partition containing a little EFI-executable file that tells the firmware where to find the kernel. The kernel is the actual bootloader - as it should be.

With the setup above you can boot as many EFI-executables as you'd like - just put their /boot (or whatever their boot partition is) contents on the USB-stick in /EFI somewhere and rEFInd will probably find them automatically and present them as an option to you from the firmware menu - to include Microsoft systems. Forevermore.

Related Question