I regularly have the need to try things out on Linux. Sometimes a virtual machine won't cut it for me typically due to memory, disk and performance limitations. Moreover, a decent, up-to-date, bootable Linux environment is a great backup in case all of my other computers are broken, infected or stolen. That entails having the Linux installation on an external, USB-attached hard disk drive which can boot with relative ease on any UEFI-enabled PC (driver compatibility notwithstanding). Moreover, all the preparatory work has to be performed using a single-boot Windows computer without ending up having a dual boot system. It sounds tough. It is tough, but I'm writing this from my portable Ubuntu Linux installation running off a USB-attached SSD!

What you need

  • An empty external (USB) hard drive. I used a USB 3 drive enclosure with a cheap 256Gb SSD. For those of you worrying about performance, the USB 3.0 port is faster than the maximum transfer rate of any SSD I've seen to this date.
  • Ubuntu Linux bootable USB drive. Very easy to create using Rufus on Windows. I used a cheap, promotional flash drive. Reduce, reuse, recycle FTW.
  • Windows System Repair Disc (a bootable USB drive with Windows recovery tools which you can make yourself) or a Windows installation or rescue CD-ROM / DVD-ROM. I used another promotional flash drive.

Remember to take backups of all your critical files and folders before continuing. You are going to make changes to your computer. If it breaks don't cry, I warned you. Also test both your bootable media. Twice. You will need them both!

Caveats

Having a dual- or multi-boot system isn't as straightforward as it used to be a decade ago. Nowadays, in the interest of security, performance and backwards compatibility, there are many semi-hidden options and features which can get in your way. Given enough experience and patience you can work around them. Below is a selection of problems that got me moderately stumped along the way.

Secure boot caveat

I have only tested these instructions with Secure Boot turned off. Even though Ubuntu does support Secure Boot (it comes with signed bootloaders) I have no idea if my method uses the signed bootloaders or not. I suggest turning off Secure Boot if possible.

FastBoot caveats

Many boards come with some sort of "fast boot" or "boot optimization" options. For example, my Intel NUC has an option called Fast Boot which won't let me choose an alternative boot device at startup. It also has an option to support Intel Rapid Start Technology which does get in the way of booting to multiple OS. I had to disable both.

It's worth noting that Windows 8 and 10 have an Fast Startup or Fast Boot feature. This feature takes some shortcuts when it comes to booting and also makes the NTFS filesystem remain in a dirty state, making it unwriteable from Linux. It's best to understand what it does and disable it if you plan on writing to your Windows drive from Linux.

USB host controller caveat

Some firmwares will present the USB host controller as UHCI (USB 1.1) at boot time. When Linux probes for an xHCI (USB 3) host controller during the boot process they will respond positively. At this time Linux loads the xHCI driver and the USB host controller resets itself.

However, your root filesystem is inside a device attached to this USB controller. Therefore the controller resetting means that Linux can no longer communicate with the USB-attached hard drive. Therefore the Linux boot will hang forever without any further indication as to what went wrong.

Most affected boards (including my Intel NUC) have an option to enable the xHCI host controller interface by default. Enabling the xHCI option in the BIOS fixes the hanging boot issue. If you are only using modern operating systems with USB 3 support (anything newer than and including Windows 8.1 and Ubuntu Linux 15.04) you can safely enable that option.

Installing Linux

Boot your computer from the Ubuntu Linux bootable USB drive. Remember that you may have to enter your computer's boot manager to do that (on my Intel NUC I have to press F10; on most other BIOS I've seen it's F9; consult your BIOS documentation).

Install Ubuntu Linux regularly. When it prompts you about the disk layout choose Something Else and partition your external HDD the way you want. I chose to create a modestly sized root partition (about 40Gb), a swap partition that's as big as the biggest RAM configuration I am going to be using this installation with plus one Gb (my computers max out at 16Gb so I made a 17Gb swap partition) and the rest of the disk went to a massive /home partition.

Caveat: I chose to use btrfs which – as I learned along the way – makes things a bit more complicated down the line. For your sanity's sake I recommend using ext4. This guide assumes the use of btrfs and will point out the caveats with this approach.

Fix Windows 10 boot

Unfortunately the Ubuntu Installer assumes that you want a dual booting configuration alongside Windows. Therefore it adds itself (actually, the bootloader it uses, GRUB2) to your computer's UEFI configuration. This causes two problems. For starters, the external HDD is not portable as you cannot boot with it on another computer.

Secondly, if you remove this external HDD your Windows won't boot. Bummer. We have to fix that.

  • Shut down your computer.
  • Disconnect the Ubuntu HDD
  • Boot from the Windows system repair disc USB drive (or a Windows installation or rescue CD-ROM / DVD-ROM).
  • Select Repair your computer.
  • Select the operating system and click Next.
  • Choose Command Prompt.
  • In the command prompt run
    diskpart
    sel disk 0
    list vol
  • Verify that the EFI partition is using the FAT32 file system. It will have a volume ID, let's say 99. Now we need to assign a drive letter to it. Back in the command prompt type:
    sel vol 99
    assign letter=z:
    exit
  • Now we need to fix the boot record. Again in the command prompt type:
    z:
    cd EFI/Microsoft/Boot
    bootrec /FixBoot
  • Finally, we need to re-create the BCD store which tells the Microsoft boot loader where to find Windows so it can boot it. From our trusted command prompt:
    ren BCD BCD.old
    bcdboot c:\Windows /l en-us /s z: All
  • If this didn't work try
    ren BCD BCD.old
    bootrec /RebuildBcd

At this point exit the command prompt and shut down your computer.

Create an ESP on the Ubuntu HDD

A hard drive is not bootable with UEFI unless it has an ESP (EFI System Partition). An ESP is simply a FAT32 partition with a special flag that tells the EFI BIOS to look inside it for boot information. We have to create one on your hard drive.

  • Plug in your external HDD and the Ubuntu Linux bootable USB stick.
  • Boot with the Ubuntu Linux bootable USB stick using the option to try Ubuntu before installing.
  • Open a Terminal (CTRL-ALT-T)
  • Run sudo fdisk -l to get a list of partitions.
  • Identify from them the drive that has the Linux partitions, in my case /dev/sdb. I'll call it /dev/sdX from now on.
  • Also identify the partition that contains the root filesystem. I will call it /dev/sdXY from now on.
  • Launch GParted from the Terminal:
    sudo gparted /dev/sdX
    Why not just click on GParted on your desktop? Well, I kept receiving errors about the Ubuntu Linux bootable USB stick because it was already in use. Of course it is, I am using it to run the computer off it, duh!
  • Resize the first partition on disk to have another 200 Mb of free space after it.
  • Create a new partition on the free space, changing the file system to fat32.
  • Apply operations. You need to do that now for the next step to be possible.
  • Right click the new partition.
  • Click on Manage Flags.
  • Set the boot and esp flags. This is what makes the partition "special" to the EFI BIOS.
  • One more thing! Note down the the partition that contains the ESP filesystem. I will call it /dev/sdXZ from now on.

Make sure the Ubuntu installation on the external HDD can see the ESP

The new ESP on the external drive must be visible by the Ubuntu installation in the HDD. Otherwise GRUB2, the Linux bootloader, won't be able to update itself, making your system unbootable after the next kernel update at the latest.

  • Launch GParted from the Terminal, as we saw above:
    sudo gparted /dev/sdX
  • Double click the partition with your Linux root (/) filesystem on the external HDD
  • Note down the UUID, e.g. 01234567-89ab-cdef-0123-4567890abcde
  • Double click the new FAT32 partition and note down the UUID, e.g. 0123-ABCD
  • Close GParted
  • Open a Terminal

The process is different depending on the format of your root partition on the external hard disk.

If you DID NOT use btrfs (e.g. you used ext4)

sudo umount /media/ubuntu/01234567-89ab-cdef-0123-4567890abcde 
sudo mount /dev/sdXY /mnt

If you DID use btrfs

If you DID use btrfs, you made your life complicated. We need to mount the btrfs subvolume containing the root partition instead of the entire partition. Otherwise you'll never be able to install GRUB and you'll probably lose an entire day, like me.

btrfs subvolume list /media/ubuntu/01234567-89ab-cdef-0123-4567890abcde

This will give you a line with a numeric ID. Let's say 123. Note it down.

umount /media/ubuntu/01234567-89ab-cdef-0123-4567890abcde
mount /dev/sdXY -o subvolid=123 /mnt

The rest of the instructions are common, no matter if used btrfs, ext4 or something else

  • sudo nano /mnt/etc/fstab
  • There is a line with /boot/efi already in this file. Comment it by placing a # in front of it.
  • Add the following line:
    UUID=0123-ABCD /boot/efi vfat defaults 0 1

Install GRUB2 on the external drive's EFI System Partition

Right now our external drive has an empty ESP. We need to put a bootloader in it to make it actually, well, bootable.

First caveat: all the instructions you find on-line assume you are using a dual boot system with Windows or macOS. When you have an external drive it is critical that you use the --removable option in the last step. This installs the EFI bootloader under the special "fallback path" EFI\Boot\bootx64.efi in the ESP. Normally this not supposed to be used for permanently installed Operating Systems. It's the mechanism used by EFI BIOS to boot arbitrary external media. Technically, that's exactly what our external hard drive is: arbitrary external media!

Second caveat: installing the bootloader is only possible from inside the Linux installation we want to boot. However, we need the bootloader to boot that installation, leading to a Catch-22 issue. The solution is to run the bootloader installation through a chroot jail. The actual caveat that got me stumped for a day comes from the fact that I am using btrfs (because it's so much better for SSDs!). btrfs has subvolumes. If you mount the entire partition instead of a subvolume the grub-install script can't figure out the mapping between paths and devices, therefore failing to install itself on the ESP, returning the cryptic error

/usr/sbin/grub-probe: error: cannot find a device for / (is /dev mounted?).

The error is misleading! /dev is mounted if you follow my instructions below. The actual problem, as I understand it, is that there is a discrepancy between the mounted device and the path to the chroot root. That's why I had you mount only the subvolume containing the root filesystem in the steps above. If you were not paying attention, you are not following the instructions step-by-step, you rebooted before this step or just came here directly looking for a solution to your problem about GRUB not installing look above for instructions on mounting the correct btrfs subvolume.

  • We need to prepare the chroot environment. The ESP must be mounted in the correct place and we have to bind system mount point for some special trees (most notably /dev). Moreover, we will copy the resolv.conf file to let the chroot environment have network access should it need it.
    mount /dev/sdXZ /mnt/boot/efi
    for i in /dev /dev/pts /proc /sys; do sudo mount -B $i /mnt/$i; done
    cp /etc/resolv.conf /mnt/etc/
    modprobe efivars
  • Finally we enter the chroot environment and install Grub in a way suitable for a removable device (see the first caveat above).
    sudo chroot /mnt
    grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable /dev/sdX

Now your external HDD is bootable. Reboot your computer, select it from the boot media selection of your UEFI BIOS and you're done!

201 comments

    • Let me Google that for you ;) https://askubuntu.com/questions/763472/what-can-i-do-to-fix-this-error-on-grub-efi/763746
      • Thanks for immediate reply,

        so I changed command to

        grub-install -d /usr/lib/grub/i386-pc --efi-directory=/boot/efi/ --removable -dev/sdb

        and output was:

        Installig for i386-pc platform.
        grub-install: error: failed to get canonical path of `/dev/sdb3'.

        by the way: sdb1 is EFI, sdb2 SWAP, sdb3 ext4 linux root, sdb4 ext4 - data

        Is it trying to install grub on my linux partition instead of EFI?



        • I suppose you meant --removable /dev/sdb over there :) First make sure that you are running this from inside the chroot jail in /mnt. The error you get means that GRUB can't find an /etc/fstab entry for the /dev/sdb3 partition, therefore it has no idea it's the root partition. You can also try adding --force to the GRUB installation command line to force the installation but if you're not inside the chroot jail you won't get a bootable drive.
          • Before, I did run the command:
            sudo chroot /mnt
            and line changed from
            ubuntu@ubuntu:
            to
            root@ubuntu:/# (and changed from green to white)

            If that's what u'r asking. I did also all the steps above - except fix windows 10boot. My emmc with windows is dead - that's why I'm installing Ubuntu to external HDD. So the original EFI partition on emmc is destroyed. And I don't care about running windows. Just Ubuntu from external.
          • Hi,
            found the mistake - missed one step, my bad - sorry for bothering with that.
            (missed sudo nano /mnt/etc/fstab)

            so, after including that, I run the installation with following amendments:

            had to run following commands as sudo (I get permission error if I wouldn't):
            sudo mount /dev/sda1 /mnt/boot/efi
            and
            sudo cp /etc/resolv.conf /mnt/etc/

            the instalation of grub in last step finished this time with following remarks

            grub-install: warning: this GPT partition label contains no BIOS Boot Partition; embedding won't be possible.
            grub-install: warning: Embedding is not possible. GRUB can only be installed in this setup by using blockllist. However, blocklists are UNRELIABLE and their use is discouraged..
            grub-install: error: will not proceed with blocklist

            After reboot I still can't see the external HDD to boot from.

            I tried this
            https://blog.hostonnet.com/grub-install-warning-this-gpt-partition-label-contains-no-bios-boot-partition-embedding-wont-be-possible

            to fix that, grub installed without errors - but still can't boot. (etc can't see HDD when booting)

            Any help here would be very appreciated - I'm fighting with this over a week. This is second approach to this. First I tried was (because that exactly computer I'm working with)
            http://www.jfwhome.com/2016/01/04/latest-steps-to-install-ubuntu-on-the-asus-t100ta/

            but that's for internal emmc not for external HDD, so I ended here.

  • Hi there.

    I finally got the opportunity to install Ubuntu on a 160 GB HDD, following the steps of your tutorial.
    At the end of the process I get Ubuntu boot when I select to boot from the external HDD, but the only problem I have is that before the Grub Menu appears, the following error messages appear:

    error: file '/boot/' not found.
    error: no such device: /.disk/info.
    error: no such device: /.disk/mini-info.


    Can you tell what is causing this error?
    Is there any solution?

    Best regards.
    • I have encountered this issue too. In my case, I forgot to turn off security boot in BIOS menu. Besides, I add an additional setting at step Install GRUB2 to turn off uefi secure boot as follows:

      grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable --no-uefi-secure-boot /dev/sdX

      That fixes the issue.

      P.S.

      I followed tutorial to create a portable Ubuntu successfully except for this tiny annoying message at startup. I guess grub-install enables uefi security boot by default in my case. However my two laptops (MSI GL62 6QD and thinkpad x1e) do not support well for Ubuntu security boot, I guess. That causes the error message.

      After I reinstall grub with --no-uefi-secure-boot specified, the error message disappears if I turn of security boot in BIOS.

      Thank you very much for your great tutorial and I hope others encountered this issue may find a solution.

       

    • Obviously you didn't follow all of the steps. Retry and make sure you don't forget to do anything. Do NOT take creative license in interpreting the instructions in the blog post, do NOT skip instructions you think don't apply to you. If there was something you could omit it wouldn't have been included in the first place. And please make sure that you are careful with the disk and partition names.
  • can u help me in my present condition, i followed the steps it went on smooth until this.. "mount /dev/sdXZ /mnt/boot/efi" it returned no such folder, so i manually created /boo/efi folder.. after that it went smoothly and completed installing grub. so now i am able to see two different uefi entires one for windows and one for ubuntu , windows is working as expected which i am very happy about, but if i choose uefi ubuntu it goes into (grub >) gnu grub prompt, i tried some commands there, 'boot' resulted in load kernal first, i also tried set root and set prefix commands.. no luck any suggestions to point the boot files from grub and boot to it.. NOTE: i have separate partitions for 'swap', 'efi', '/boot', '/'. everything formatted in ext4 primary except the efi which defaults to fat32 and thanks for the tutorial.. a video tutorial will be much helpful any plans on that?
    • The problem is that /boot/efi is a mount point where you are supposed to mount the EFI partition per the instructions. You didn't do that because you skipped over an entire section. Then you created a folder by that name which is of course not visible by the UEFI firmware during pre-boot because it's a folder inside an Ext4 partition, not a FAT32 partition itself.

      As I have written in a few comments above: do not skip any of the instructions, do not change their order. There is a reason why I've written all of that in a specific order :)

      So, the only thing you can do is start the process from scratch and this time be careful. If necessary, print out the instructions and use a highlighter pen to keep track of what you've done so far.
      • thanks for replying, i tried some tools like supergrub2 and boot-repair, now i am able to boot and use it, maynot be as intended or depicted by this tutorial, but atleast i will be able backup if wanted and try ur procedure again to see where i went wrong.. thanks again
  • I found the simplest way to install linux to a portable disk is to shut down the pc, disconnect all hard drives, boot from the usb, plug in the portable hdd, and go!
    • No, you are wrong. Your solution only applies to machines you can tear apart and have non-soldered storage. It also does not make a portable installation. If you plug in that drive on another computer or if you plug in a different mix of drives on your machine it will fail to boot. It's most definitely not portable. I will tell you everything that is wrong with what you wrote.

      For starters, you are missing the point that these instructions will be carried out primarily by people who have laptops which are a. under warranty or provided by an employer i.e. you can't put a screwdriver on them; or b. use proprietary screws or glue; or c. have soldered-on storage or otherwise require taking apart the entire machine to reach the drive's cable (or a combination of the above). In my case it was building the Ubuntu image on an Intel NUC. Not only it's a pain in the rear opening up the tiny computer and removing the m2 drive, its capricious EFI also give you lots of issues when you change the attached drives. So, no, removing the drive is not the universally "simplest" solution.

      But let's say this is not an issue. The biggest problem is that you are NOT doing a portable installation. The regular Ubuntu installation will result in an EFI System Partition which only works for the specific computer and the specific device name your drive got during boot. Please read up on how grub2-install works and why --removable is all important. Right now your drive won't boot on another computer, making it non-portable.

      I will give you an F-. Next time think why someone wrote a detailed article if there in an obvious "simplest" solution. Maybe the answer is that your "simplest" solution is actually broken in subtle but very important ways?
  • Is it possible to use an efi bootloader manager like clover or rEFInd instead of using your solution?

    I tried to follow your tutorial but somehow i made a mistake and couldn't make it work..
    • I guess you can always try? Don't ask me how, though. The method I found to be working and the exact steps to reproduce it is documented in the article you are commenting on.
  • I'm not sure how else to say this except that "you are a f'ing SUPERHERO". I'd love to support any upcoming projects you might have in the works. Email me whenever you see this. For anyone interested in this tutorial, please note that I was very hesitant myself until noticing that the dev made a point to say that anything posted had been tried himself and that's why his tutorials are so few and far between. Not to mention that everywhere else on the net remarks that this is simply impossible to accomplish. Bullshit! This tutorial is unbelievable in its accuracy and effectiveness! God Bless You my friend. Thank you ever do much!! You are the king in my book! Have a great day!



    I should mention that the only part that needs updating is that when arriving at the line where, in windows recovery steps, you have to do the command with /fixboot as the switch, the command fails with "Access denied". The workaround is to do the following :

    Z:\>format Z: /fs:FAT32

    (erase the entire EFI partition which was assigned in a previous step to the arbitrary Z:, so in keeping with the example variables...)

    Then, simply,

    Z:\>bcdboot C:\windows /s V: /f UEFI

    (This replaces the Just initialized partition with a rebuilt data by the Microsoft command line tools).

    That is all, then continue with rest of steps as posted, word for word.


    Oh. I almost forgot...I was setting up external bootable for my Surface Book 2 with the target being Kali Linux 2018.1, so the only other minor detail was that at the very end, when installing the grub loader to the external IS drive using live Linux off of USB stick, in the paths, I had to replace
    >umount /dev/ubuntu/... With, simply,
    >umount /dev/root/...

    That's really it!!

    Again, dev, you are a rockstar! This is amazing!! I can't believe it's working without issue whatsoever!!
    • Thank you for your kind words :) Yes, everything I post here is meticulously tested by yours truly. My blog is typically three parts field notes and one part prose. I am for quality, not quantity.

      Please do let me know how Kali works on your Surface Book. I have the older Surface Book and I was thinking of creating a Kali USB stick. My only hesitation has been that some stuff doesn't work even in Ubuntu (obviously the touchscreen since the driver not in the official, therefore signed Kernel yet; sound was dead; built in keyboard and touchpad only started working in 17.04 etc). Also tell me which external Ethernet card you're using because I've yet to find one which will reliably work in promiscuous mode.

      Now, regarding the fixboot switch, it requires Administrator privileges. I have a Win10 bootable stick from Anniversary Update. It is possible that MS changed something in between but I am incredulous. After all, how do you fix a bricked Windows installation if you are not allowed to fix the boot?! Then again, I was writing this tutorial based on what I was doing on a mid-2013 Intel NUC with Windows 10 Anniversary Update. It's possible that Surface Book applies more strict controls over what you can do. I'm pretty sure there were UEFI options to that end.