Now, tech how-tos are not what I tend to write about. However, my nephew (Jamal) recently mentioned that he was thinking of playing around with Linux. I can’t remember if he asked, or I suggested, but the discussion got around to running from a USB key. Your reasons for wanting to do this may vary. I have a locked down corporate laptop and don’t want to travel with two devices. You might just want something a little more permanent than a live CD.
In any case I had done this in the past, and offered my (rather eclectic) notes to help J. As it happened, my Linux on a stick went walkabout recently. I think it fell off my keyring at some point. So I’m in the process of building another which gives me an opportunity to clean up my notes and improve the process.
So what exactly are these instructions for?
These are the steps I used to build a bootable USB with a full persistent Ubuntu install. The goal is to produce a bootable USB just like you’d use to install Linux from, that can theoretically boot on any EFI enabled PC that your distro supports and to be able to use that install just like you would a normal installation to hard drive.
We’ll be building a pretty stock standard Ubuntu 19.10 with just a few tweaks to help it run better from a USB, and hopefully reduce the flash wear on the device. Wear may not even be a “thing” any more with modern USB keys, but these changes can’t really hurt, and they make the system more responsive.
You’ll need the following:
First, lets get ourselves a bootable Ubuntu installer. We’ll use this as both a rescue disk and install to prepare the big drive and do the install to it.
Now, we’ll use this temporary OS running in RAM Disk to create a second bootable Linux USB with “persistence”. We will never use this drive as is. However, creating a persistent drive nicely partitions the target drive and ensures all the hairy stuff like EFI partitions are created and initialised correctly.
Note that all the software you’re installing from here on on the installer USB is only in RAM, if you shutdown or reboot it’s all gone and you’ll need to start again from this point.
Install mkusb as per the guide. i.e. open a terminal and run the following commands;
sudo add-apt-repository universe
sudo add-apt-repository ppa:mkusb/ppa
sudo apt-get update
sudo apt install --install-recommends mkusb mkusb-nox usb-pack-efi
Now we’ll run mkusb to create the persistent drive
Run the tool to format the target drive
sudo mkusb
You now have 2 bootable USB’s. The small one you’re currently running from, and a newly created large target USB. Now we’re going to install Ubuntu onto the big one. We’ll delete the persistent partition and the 2Gb ISO partition because we won’t ever actually run the big disk as an installer, and we need to create some space to install Ubuntu into.
Now you’re at the manual partitioning and installer page. For the purposes of this guide we’ll assume you’re installing to a 64Gb USB on /dev/sdb. Adjust your steps if your set-up differs.
This is a very simple install, one mount point and no swap. Feel free to partition the drive differently if you wish. You could add swap if your PC/laptop needs it. I’ve run on a 8Gb Lenovo Carbon that seems to work fine without swap.
We are very nearly done. We just have to do a little bit of surgery to update the grub config on the EFI partition to boot the new install. The installer may have ejected the target USB, if so you’ll need to temporarily mount your new Linux partition and the EFI
Locate the EFI and EXT4 partitions on the target USB (/dev/sdb)
sudo fdisk -l /dev/sdb
Create a mount point for the EFI partition and mount it, assuming the EFI partition is on /dev/sdb2.
sudo mkdir /media/efi
sudo mount /dev/sdb2 /media/efi
Check the EXT4 partition is mounted using the “mount” command if not do the same for it using these commands. This assumes that the partition is on /dev/sdb3 and we’ll mount it to /media/targetusb. If that partition is already mounted, you can skip this step and use wherever it’s currently mounted instead in the next step’s copy commands.
sudo mkdir /media/targetusb
sudo mount /dev/sdb3 /media/targetusb
Copy the grub config and image files from the newly created Ubuntu install to the EFI partition so they’ll be used when booting from the BIOS. J, If you get this far you’re on you own for the moment. I’m fairly sure the system will work just copying the grub.cfg, but I did copy the kernel image as well. Unfortunately I left my drive at home so I can’t check it. I’ll fix the following steps in the next couple of days (when I also spell check this guide)
sudo cp /media/targetusb/boot/grub.cfg /media/efi/efi/boot
sudo cp -r /media/targetusb/boot/XXXXXX /media/efi/efi/boot
That’s it you’re done (for this step). The Target (big) USB should now contain a bootable USB with Ubuntu installed. Restart, eject the install disk, leave/insert the big USB and boot from BIOS using the newly created drive. It should open up to an Ubuntu that looks almost identical to the one you installed from except it’s probably got a first time boot wizard screen.
Complete/close the wizard and test the new install by creating a file on the desktop, then rebooting. If the file is still there, You’re done!
There are a couple of things we should do to improve performance on USB. This will also help reduce “wear” on the flash, helping make it last longer. For this section you’ll need to create and/or edit some system files. As I’m familiar with “vi” for this kind of thing I use the command “sudo vi the-file-i-need-to-edit”. If you don’t know how to use vi, feel free to use emacs, or a gui editor like sublime (what I’m using to write this).
First, let’s turn off access time writes. For this you need to edit /etc/fstab and add the “noatime” parameter to the “/” mount.
Edit /etc/fstab and add “noatime” to the line with the “/” mount point. It should look something like this.
UUID=GIUD-OF-YOUR-USB-DRIVE / ext4 noatime,errors=remount-ro 0 1
Now some guides suggest moving /run and /tmp to ramdisk, but it looks like this has already been done in this distro. The idea is that we want to reduce unnecessary writes to the USB by creating temporary filesystems in memory. But we’ll go ome better. Instead, what we’ll do is install a package called goanysync. This also creates a ramdisk for busy directorys, but it periodically syncs them back to actual USB. That way the files persist between reboots. Handy if you need to inspect a log.
First install the goanysync package.
I found that goanysync didn’t work “out of the box” after rebooting as the /run/goanysync directory wasn’t persisting between boots. Probably because /run is a ram disk. So we’ll use the rc.local service to create the directory at boot. You can also use this script if you need to run any other commands at system start.
Create a file called “/etc/rc.local” with the following contents.
#!/bin/bash
if [ ! -d "/run/goanysync" ]; then mkdir /run/goanysync; fi
Make the file executable.
chmod ugo+x /etc/rc.local
Edit the goanysyc service file /lib/systemd/system/goanysync.service to make it run after the rc-local service. i.e. make it should look something like this.
[Unit]
Description=goanysync directory symlinker and content syncer
Wants=local-fs.target
After=rc-local.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/goanysync start
ExecStop=/usr/bin/goanysync stop
[Install]
WantedBy=multi-user.target
Edit WHATTOSYNC in /etc/goanysync.conf (the config file) to add the log and browser dirs. You can play with this to add more if you want. It should look like this (with your login instead of cain)
#
# /etc/goanysync.conf
#
# Define tmpfs base path, this is where WHATTOSYNC directories will be linked.
TMPFS = /dev/shm/goanysync
# rsync binary file to use.
RSYNC_BIN = /usr/bin/rsync
# Define source directories in the WHATTOSYNC comma-separated list. These
# directories content will be moved under TMPFS path and the directory itself
# replaced by symlink to the aforementioned path.
#
# An example could be:
#
WHATTOSYNC = /var/log, /home/cain/.mozilla/firefox /home/cain/.cache
Enable Both goanysync and the rc-local service to run at boot with the following commands.
sudo systemctl enable rc-local
sudo systemctl enable goanysync
Reboot, and check. The commmand “ls -l /var” should show the log directory as a synlink. If not check the services with the following commands
sudo systemctl status rc-local
sudo systemctl status goanysync
Finally, lets get to the clock. Linux sets the system clock to UTC which is the sensible thing to do. Unfortunately Windows doesn’t, it uses local time. Which means as you dual boot back and forward one or the other will of off unless you live in London. It’s not ideal, but the best solution is to make Linux use local time as well. We’ll let windows take care of daylight saving time etc.
From a terminal run the following command.
sudo timedatectl set-local-rtc 1 --adjust-system-clock
Make sure the time is correct, and adjust as necessary.
I use a Mac about 20% of the time, so making the new install look a little like my mac book pro makes using the desktop a little smoother. Fortunately Ubuntu 19.10 is already using gnome and has the tweaks tool so the process is fairly painless.
Lets do the superficial changes first.
Now Lets install a nice mac like icon pack, It’s not that the gnome icons are bad, it’s just that it reduces confusion when hunting looking for a particular function/app.
Finally let make the dock a little more mac like. We’ll use the Dash to dock, and install it from source.
Install git, download the dock and build it. From a terminal window run these commands.
sudo apt install git
sudo apt install gettext
mkdir ~/dev
cd ~/dev
git clone https://github.com/micheleg/dash-to-dock.git
cd dash-to-dock
make
make install
There you go! You should now have a nice looking functional Linux distro on a bootable USB. It’s a good starting point to customise for your own use.
Thanks to Jamal who ran these instructions from scratch and verified that they work and can be understood by someone other than me.
Also, the Following sites: