1

tl;dr - How to boot an Ubuntu Server installation from an USB key?

I am trying to boot an Ubuntu Server 18.04 LTS installation on a server that doesn't allow booting from a NVMe drive. Since the drive is visible post boot (after booting to a Live CD for example) my thought was to make it work by chain-loading the OS from a USB disk/key that I keep plugged in at all times.

I have scoured through the web for a guide on how to do this but everything I have found is on a very conceptual level. I am looking for someone to provide links to documentation or step-by-step guidance.

Hardware specifications (if necessary):

Dell Poweredge R230 Startech x4 PCI Express to M.2 PCIe SSD Adapter Card Samsung 970 EVO NVMe (M.2) 250 GB Kingston DataTraveler SE9 16GB

-1

I have a USB drive I use to boot from my laptop, which has intermittent issues with the internal hard drive. Sometimes it will not be detected in the BIOS, but it is always detected once already booted.

If you have systemd-boot installed on your internal drive, follow the first guide. If not, skip down to the second method. Installing systemd-boot on your internal drive is the recommended method

Guide 1: Systemd-boot on Internal Drive

  1. Boot into a live CD on the computer. Insert the USB drive you'll be using to boot from the NVMe drive.

  2. Create a FAT32 partition on the USB drive. Make sure it has the boot and esp flags enabled. The easiest way to do this is with gparted.

  3. Mount the FAT32 partition. For the rest of the steps, I will assume it is mounted at /mnt/usbboot

  4. Add your USB boot partition to the fstab so that it is automatically mounted. The easiest way to do this is to chroot (use arch-chroot, it's easier) into your internal drive and then run sudo genfstab -U / > /etc/fstab.

  5. Create this file on the internal drive: `/etc/systemd/system/boot-sync.service'

    Note: you will need rsync installed for this systemd unit.

  6. Paste the following into the file you just created:

[Unit]

Description="Sync boot files from internal drive to usb drive"

RequiresMountsFor=/mnt/usbboot

[Service]

Type=oneshot

ExecStart=/bin/bash -c "rsync -rlgopuv /boot/*.img /mnt/usbboot/"

ExecStart=/bin/rsync -rlgopuv /boot/vmlinuz-linux /mnt/usbboot/

ExecStart=/bin/rsync -rlgopuv /boot/EFI /mnt/usbboot/

ExecStart=/bin/rsync -rlgopuv /boot/loader /mnt/usbboot/

[Install] WantedBy=multi-user.target

  1. Chroot into your internal drive and run this command: sudo systemctl enable --now boot-sync.service

  2. Reboot and select the USB drive you just created as the default boot device.


Guide 2: Systemd-boot on the USB Drive - Not Recommended

  1. Boot into a live CD on the computer. Insert the USB drive you'll be using to boot from the NVMe drive.

  2. Create a FAT32 partition on the USB drive. Make sure it has the boot and esp flags enabled. The easiest way to do this is with gparted.

  3. Mount the FAT32 partition. For the rest of the steps, I will assume it is mounted at /mnt/usbboot

  4. Chroot into your internal drive and run this command sudo bootctl --path=/mnt/usbboot install

  5. Run this command (also inside the chroot on your internal drive) sudo bootctl update (NOTE: This may not be necessary, but it won't hurt)

  6. Create an entry for your NVMe drive at /mnt/usb/loader/entries/ubuntu_server.conf

It should look something like this:

title Ubuntu Server 18.04
linux /vmlinuz-linux
initrd /initramfs-linux.img
options root=PARTUUID=XXXX rw

Replace XXXX with the PARTUUID for the root partition of your NVMe drive. This can be found by running blkid and looking for your root partition.

  1. Create /mnt/usb/loader/loader.conf

It should look something like this:

default ubuntu_server

timeout 4

editor 0

NOTE: Complete EITHER step 8A OR step 8B. If you choose to copy the files manually, they will need to be recopied every time you update the kernel


8A (Not Recommended). Manually copy /boot/initramfs-linux.img and /boot/vmlinuz-linux from your internal drive boot partition over to the USB drive. These files will need to be updated every time you update your kernel or rebuild your initramfs.


8B. If you wish to use the script instead of manually copying, first add your USB boot partition to the fstab so that it is automatically mounted. The easiest way to do this is to chroot (use arch-chroot, it's easier) into your internal drive and then run sudo genfstab -U / > /etc/fstab.


Note: you will need rsync installed for this systemd unit

  1. Create this file on the internal drive: `/etc/systemd/system/boot-sync.service'

  2. Paste the following into the file you just created:

[Unit]

Description="Sync boot files from internal drive to usb drive"

RequiresMountsFor=/mnt/usbboot

[Service]

Type=oneshot

ExecStart=/bin/bash -c "rsync -rlgopuv /boot/*.img /mnt/usbboot/"

ExecStart=/bin/rsync -rlgopuv /boot/vmlinuz-linux /mnt/usbboot/

[Install] WantedBy=multi-user.target

  1. Chroot into your internal drive and run this command: sudo systemctl enable --now boot-sync.service

  2. Reboot and select the USB drive you just created as the default boot device.

  • What do the bootctl commands do? Man implies it's something related to systemd and EFI, are they required? – Xen2050 Oct 28 '18 at 15:19
  • From wiki.archlinux.org/index.php/… - "[bootctl install] will copy the systemd-boot boot loader to the EFI partition: on a x64 architecture system the two identical binaries esp/EFI/systemd/systemd-bootx64.efi and esp/EFI/BOOT/BOOTX64.EFI will be transferred to the ESP. It will then set systemd-boot as the default EFI application (default boot entry) loaded by the EFI Boot Manager." Basically it copies over the required EFI stubs and files which will be run by the UEFI implementation on your motherboard. It is required for this method. – Layne Bernardo Oct 28 '18 at 15:24
  • First of all, thank you for a quick response and for taking your time to help out! I can't seem to get this to work though. I don't get any particular error messages, except I needed to point out the path in step 5 (sudo bootctl update --path=/mnt/sdb1). When I boot I get the following error message: "Error loading \vmlinuz-linux: Not Found Failed to execute Ubuntu Server 18.04 (\vmlinuz-linux): Not Found" – megahertz Oct 29 '18 at 15:35
  • Oh that's right, I forgot about that part. I have a hackish fix, you can fix the issue by copying initramfs-linux.img and vmlinuz-linux from your internal drive boot partition to the USB drive. You will need to copy these files every time you update the linux kernel. I have a systemd unit that will do that on boot and will update the answer. – Layne Bernardo Oct 29 '18 at 16:43
  • The tutorial has been updated - including a much easier method I had forgot about which can be used if you already have systemd-boot installed on the internal drive. I apologize for that, I set my USB boot drive up over a year ago and haven't messed with it since. Note that I have changed the mount location from /mnt/usb to /mnt/usbboot because it's less confusing with the systemd unit. Cheers! – Layne Bernardo Oct 29 '18 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.