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!
I tried a few, but didn't work so I just suck it up and enter my password after boot and all is well on that machine.
I just think it's crazy (funny) that the fully portable device boots on the machine that has the Nvidia card and all the issues you would expect to occur; do not, yet the installed version which I assume detected and installed the Nvidia drivers during the install is all twitchy.....
At the end of the day, on the two machines I have here, it worked and works.
I'm also assuming that because I performed all the tasks related to creating the portable install on a laptop with Intel GPU that the portable install has Intel or something comparable, anything other than Nvidia drivers installed, and they just happen to work with my desktop Nvidia card ? Maybe ?
Most Intel CPUs released over the last decade or so have integrated graphics so it makes sense that a Linux installation set up without a specific graphics driver will boot just fine. As I said, the Intel graphics driver is part of the kernel and it's loaded at boot if it's relevant i.e. if you have an Intel CPU with integrated graphics. Even if you set up your portable installation on an AMD CPU it'd boot on machines with an Intel CPU and have graphics. Modules are loaded conditionally on boot as long as they're included in the initial RAM disk (typically called initrd.gz).
Speaking of which, I had some trouble with the initial ramdisk and Ubuntu 20.04 on my old but trusted Intel NUC with an old processor (mid-2013 vintage). Apparently Ubuntu switched its initial ramdisk compression from gzip to LZ4 and it stopped working on my machine. I had to edit
/etc/initramfs-tools/initramfs.conf
and setCOMPRESS=gzip
, then runsudo update-initramfs -u -k all
to regenerate my initial ramdisk. If you get an immediate boot failure i.e. your kernel doesn't even load then this is something you might need to do. Apparently LZ4 initial ramdisk compression is a bit of a hit and miss?I had the idea of cloning the portable installation to another drive, retaining the customization on that install to the clone. The clone drive was smaller so:
I partitioned EFI and SWAP normally, made smaller / and /home partitions and then copied all files and folders from / and /home to the clone.
Edited fstab to the correct UUIDs for all, i.e EFI, SWAP, / and /home and basically followed every step just it doesn't show up as a boot option.
Tried in chroot to grub-mkconfig -o /boot/grub/grub.cfg first, then your command grub-install -d /usr/lib/grub/x86_64-efi --efi-directory=/boot/efi/ --removable /dev/sdX but no luck.
Scratching my head.
How did you copy the files? Did you use a passthrough tar or another method that preserves ownership, permissions and any extended attributes? Or did you just use cp?
Did you also change the UUIDs in the /etc/grub.d files (if present) and /etc/initramfs-tools/conf.d/resume? You'll also need to run mkinitramfs before reinstalling GRUB2 if I recall correctly.
I don't remember doing anything different about 3 months ago when I did the same.
I'm in over my head, and I figured as much.
May try installing on top of the partitions I've created but preserving the /home directory in the process. Continue like a fresh install repeating the steps above.
Thanks & Cheers....
I did the clone by using tune2fs to mimic the previous UUIDs, cp -rp to move everything. dd to clone the efi partition and edited fstab for the new swap UUID
Did it more as a learning tool, and it works....
I did manage to install Ubuntu on external hard drive, but as you've posted the Grub is installed on my main internal hd. I'm still able to access windows 10 (using it to type this rn) through the boot menu (pressing f12) and choosing Windows Boot Manager instead of "ubuntu" and also changing the boot order. So i think dont need the recovery windows usb. Should i proceed with the "Fix windows 10 boot"? I don't mean to bother, just afraid to mess my Windows up.
Hello and thanks for these instructions, they really paved the way to me using Linux as my main OS.
I am actually curious if there is a way to dual boot on multiple computers. Specifically, I have a PC and a laptop that where I now now use Linux more frequently. The ability to just take the USB from one system and run it on the other (and potentially any other PC) is what makes it useful for me. The problem I have seen so far with GRUB is that you would need to assign the Windows Boot Manager partition on fstab for both PCs (or simply remove the USB every time you want to boot to Windows). Is there a way to automatically find the Windows boot partition instead of specifically assigning it?
As for the section F, you can avoid that by installing Linux inside a VM. I used both VMWare Workstation Player and VirtualBox to do that and it worked like a charm. I basically set up the VM to expect a Windows installation (not sure if that is necessary though), then boot with the ISO file for the Linux distro, connect the USB to the VM guest and in the process make sure to select a partition on the USB stick to contain the bootloader. This way you don't mess with your Windows installation if you don't want to. As a side effect, it seems that if you choose to boot from the USB stick, it loads the Linux installation directly without giving you the option to boot into Windows, but it also removes the other options you usually have with GRUB, so you may want to install it, though you don't need to chroot.
I can tell you that using the instructions in this article I've created a bootable USB-attached SSD which I've used with four different computers. I didn't have to do anything special.
Regarding GRUB and the Windows Boot Manager, my advice is to NOT use GRUB to boot into Windows. It's incompatible with BitLocker, the full disk encryption used by Windows 10 Professional and higher. If you make that mistake your computer will boot into BitLocker's recovery. Moreover, as you noted, it's not a very portable or convenient way when you are switching computers.
Besides, GRUB will auto-detect all EFI boot partitions present on the system and include them in the boot menu by default. It's part of the default GRUB configuration on Debian-based distributions. If you're using a different bistro I have no idea. All I can tell you is that I never add any EFI volume in my fstab besides Linux'. I am not even adding my Windows partitions since they're all encrypted with BitLocker, making them inaccessible to Linux.
The best thing you can do is enter your computer's boot disk selection. With most computers it's holding F9, F10 or ESC during boot. If you're not sure consult with your computer / motherboard manufacturer. You can select which drive / partition to boot. Windows Boot Manager will take you to Windows. Your external device appears under a different name or not at all, depending on whether you followed my instructions (which you didn't as we're about to see).
Regarding section F, using a VM is far from being straightforward for most people. It also has some repercussions which might not be self-evident. You are essentially lying to the installer about your computer. It sees less memory, different hardware etc. Usually this doesn't cause a lot of problems. Modern distributions have excellent hardware auto-detection. Still, it's a bit iffy if you ask me. Definitely not something I would recommend.
As for the need to chroot, you are wrong. It has nothing to do with whether you used a VM, disconnected your Windows boot drive or disabled the Windows boot drive from UEFI. It has to do with making your USB drive bootable across different devices. I EXPLICITLY say so in the article:
If you didn't follow that part of the instructions you may have trouble booting into your Linux USB drive on other computers. Specifically, you may have to add them to Windows Boot Manager which kinda beats the purpose of having an installation that you can boot from even if your main drive is dead or you're using someone else's computer.
I really appreciate the in-depth reply, especially the part about booting into Windows. While I use Win 10 Pro on my desktop, I think I am not using BitLocker (at least not intentionally), so I haven't really encountered the issue you noted. At first I followed your instructions on my laptop which is running Win 10 Home. But I could be wrong, I remember GRUB giving an option to use Windows Boot Manager to boot to Windows, not just straight up boot by itself, though I could be wrong. Would that solve the issue of BitLocker?
With regards to booting on other computers, so far it has been working fine between my laptop and desktop. Usually all it takes is to switch the boot priority to removable/USB devices. I have to say that this way, I get absolutely no boot options, so no recovery mode, etc, unless that is something that can be changed.
I do have to say that on my desktop I noticed a weird hang while using Pop! OS which was not present on my laptop (note that the desktop has by far superior hardware), though even with Windows I notice some weird behavior... Basically something stops responding, making the whole system frustrating to unusable. Not even the terminal responds, nor force shutdown commands. Now I am looking how it is with Kubuntu, and so far no issue. The other annoying thing is that every time I shutdown my desktop, it reboots itself back into Linux, until I either force it to boot to windows and shutdown from there, or press the power button until it shuts down (neither of which are good solutions). On the laptop it shuts down normally.
I forgot to clarify, that by "no need to chroot" I meant that since you can boot properly into that Linux installation you should be able to perform the same operations to install GRUB without first chroot from another linux installtion/live disk.
Windows 10 Home does not have BitLocker. It's a Win10 Pro and Enterprise feature. That's why you could use GRUB to boot into Windows. Even if you have BitLocker GRUB will find the Windows 10 EFI partition and add a Windows boot entry. Selecting it boots Windows... which promptly detects it wasn't a clean boot, clams BitLocker shut and shows you the BitLocker recovery screen. This is how things should work. It's not a bug, it's a Windows 10 feature. It prevents any weird fuckery which could compromise the integrity of your system. Hence, the only way to boot Windows 10 Professional or Enterprise is using your motherboard's boot selection screen.
I currently have a ~3 year old old Asus laptop (I traded it for my old Mac mini) as my Windows 10 / Linux device. By default, it boots into the attached USB disk. I have to hold down ESC, its boot selection key, when powering up to select the Windows drive when the USB drive is attached. If I forget and get to the GRUB screen I know it's too late and I have to CTRL-ALT-DEL my way out of it.
GRUB boot options are defined by the GRUB configuration. I can tell you that Kubuntu offers the latest kernel, the previous kernel, single user recovery mode and any third party EFI boot drives detected when installing GRUB. I have not used Pop! OS and I don't think I ever will because it's very militant about not using blobs (closed source drivers). I know that my WiFi and BlueTooth wouldn't work and connecting an external display wouldn't work either. They all require drivers with blobs. I am mostly using the laptop connected to a big monitor so that would be silly. Also, I am a KDE fan ever since my first actually working Linux installation, Mandrake Linux back in 2001.
Regarding shutdown, that's weird. Shutdown and reboot send different ACPI commands to your system. You probably need to check if your desktop motherboard requires something special to make ACPI work on it correctly under Linux. If you can't fix it and it just reboots, get to the GRUB page, press the down array so the timeout doesn't go off and then shutdown by holding the power button. At this point no OS is loaded, the disk is not in use and you can safely kill the power.
I suspect something has changed with Pop! OS since they now have options to install it with proprietary nvidia driver support. On my laptop I didn't have particular issues, but when I booted on the desktop it was missing the PCI-E WiFi driver, which is the same issue with any linux distro, but I could solve same way I did with Kubuntu, ie either take the USB to my laptop and install the driver there then back to the desktop, or use a VM from the Windows installation.
With regards to GRUB options, I haven't really done anything post installation, so I think it just sees the system as only having Linux. In this way that I installed Linux (through a VM with no other OS in the VM), it just straight up boots into whatever Linux distro I use without any boot options (I only see them if I press Esc). Probably I should get that fixed at some point.
As for the shutdown issue, I disabled "Power On By PCI-E/PCI" and now it shuts down normally, though I can't use WoL anymore. Then again, I only need that to work when I'm away travelling and I take the Linux stick with me, so it's not a big loss right now.
Hi Nicholas
Thanks to your excellent article I have been able to make a number of full installations of Ubuntu on USB HDDs and run them on various machines over the past years.
Although the installations run well I encounter problems during installation:
1. When editing the /etc/fstab file there should be a line with /boot/efi already in it. This line is missing, so I don't comment anything with # but just add:
UUID= ............. /boot/efi vfat defaults 0 1
2. When I come to sudo mount /dev/sdXZ /mnt/boot/efi there is no /efi in /boot and I have to make the /efi directory first before executing this command.
In the end I do have a bootable HDD but I would like to know what exactly is going wrong here?
Thank you,
Hiram
Both issues seem to have the same root cause.
It would appear that when you are doing the initial installation it's not installed for booting in EFI mode (it boots using the legacy MBR mode). As a result it doesn't create or mount an EFI partition.
My instructions were written on the assumption that the initial Linux installation is in EFI boot mode. Essentially we're tweaking an EFI booting Linux installation so it can boot on any computer instead of just the one we installed it on.
Thank you for your fast reply.
It is dawning on me what could have gone wrong. Therefor in order to check if I'm on the right track here, I'm asking you the following question:
Is it possible to do what you have described in your article with a Ubuntu 32-bit PC (i386) desktop image?
Or asked the other way round: Is using a Ubuntu 64-bit PC (AMD64) desktop image mandatory in order to achieve the desired result?
Thank you for your help,
Hiram
I haven't used a 32-bit bistro image in the past ten years so I wouldn't know :) I can tell you, though, that the majority of 32-bit mainboards didn't have UEFI firmware so it's very likely that the distribution you are using goes with MBR as a reasonable default.
Ok, so now I'm using Ubuntu-18.04.4-desktop-amd64.iso.
While installing Ubuntu regularly, and when prompted about the disk layout I chose "something else", according to your article. I created a / partition (ext4), a swap partition and a /home partition (ext4), all primary. When I click "install now" a warning pops up:
"No EFI system partition was found. This system will likely not be able to boot successfully, and the installation process may fail.
Please go back and add an EFI system partition or continue at your own risk."
I can't find any comment on this in your article. What do you recommend?
My machines already had an EFI partition (for the main OS) so I didn't have to create one. Since yours does not have an EFI partition create on during the installation of Ubuntu.
When setting up the partitions the first partition you create needs to be 100MB at the beginning of the disk, Primary, and Use as should be set to EFI System Partition. Then proceed with the rest of the partitions as discussed in the article.
This of course means that you will skip over the step of creating an EFI partition later on since you already have it. You will only need to reinstall GRUB2 so that your external drive boots on any device you plug it in.
No more problems during installation. The new external drive boots perfectly. So far I tested it on 3 machines.
Thank you for your help and for making this procedure so clear and obvious.