Debian - Install to an USB memory and run from it like it was a disk

This note is about actually installing Debian onto an USB memory and the run the system from it, like it was a regular harddrive. It is not about putting a live ISO on a USB stick.

This was first tried on Debian Stretch 9.

Some requirements:
- Machine running Debian
- USB memory with at least 4 GB
- Root access
- Internet access

Note, the most obvious way to do this should be by connecting the USB memory to the host machine, in VirtualBox give it to the client machine and then just install to it.

This works until you to boot of the new installation as of VirtualBox 5.2, then you get FATAL: Could not read from the boot medium! System halted. This is because VirtualBox BIOS does not seem to support booting from USB devices.

Therefore in this guide is the USB memory connected as a disk to the VirtualBox.

Select ISO depending on USB size

You may select the installation ISO depending on the size of the USB memory. I found that Debian 9.9 MATE Live consumed a whole 4 GB stick so much that the installation aborted, while the net install without any graphical interface only consumed 1022 MB. Then adding MATE desktop by installing mate-desktop-environment(-core) consumes additional 750-1300 MB.

For Debian I found the following size limits:
1 GB - too small for Debian 9.9
2 GB - console mode works, too small for MATE Desktop (1.9 GB in total when I tried), maybe other desktop environment may fit
4 GB - fits MATE Desktop, web browser, partition and text editor, 

This guide follow the minimal path and therefore does a small install and then add the necessities afterwards. 

To get the minimal installer, download the latest Debian network install from minimal CD ISO.

Debian 10 could be too big for 4 GB USB memories, therefore possibly use Debian 9:

Also be prepared with a Debian live-USB to fix problems:

If you want the most recent version of the net installer you can go here:

Run the installer

To run the installer you usually put it onto an USB memory, and boot the machine off it.
You may do so if you have two USB memories - one for the live ISO and one as install target.

But if you don't, you may do the install with VirtualBox, the instructions here goes that way.
One benefit with this method is that grub will not be bothered with regular disks as the VirtualBox machine will only have the USB memory.

Install VirtualBox:

When VirtualBox is properly installed, connect the USB memory to the system, if it is not already connected.

Preparing the disk file for the USB memory

Find out the device name of it on the host, by Gparted, df or dmesg|tail. It should be something like /dev/sdb. Warning, make sure you get the correct name, wrong one will set the wrong memory or disk as target.

As root, go to your desktop folder and there create a VirtualBox hard drive file that points to the USB memory - replace /dev/sdX with the path to your USB memory.

cd Desktop (or cd Skrivbord in Swedish)
VBoxManage internalcommands createrawvmdk -filename "usb.vmdk" -rawdisk /dev/sdX

You get a file named usb.vmdk.

Start a root shell and run VirtualBox:

virtualbox &

In VirtualBox, create a new machine, set Debian 64-bit as OS and do not create a hard drive, instead select the usb.vmdk file previously created.

In the VirtualBox machine disk drive insert the Debian ISO file and start the VirtualBox machine.


Follow normal install procedure, but when asked for swap do not create one. Edit the partition table so you only have one partition, a bootable ext4 with root (/). Install grub onto it.

[!] Note, if you want to add Hiren's Boot CD, create a FAT32 partition as partition number 1, then create the ext4 as number 2.

When selecting additional software, select basic system tools and SSH server.

Installation should proceed without problem, when installed, unmount the ISO and boot.

You now have an VirtualBox that boots off a USB memory.

Boot problem 1

If you try the USB on a computer you may find that it refuses to boot, because the Debian installer could have missed to add the boot loader even though it said it did so.

To fix it, boot the VirtualBox or the machine with the live ISO you installed from, open a terminal and then install grub on the USB like it should have been done by the installer.

sudo bash
mount /dev/sdXY /mnt
for i in /dev /dev/pts /proc /sys ; do mount -B $i /mnt/$i ; done
chroot /mnt
grub-install /dev/sdXY

Boot problem 2

One problem I found was that the initial grub boot loader install used /dev/sdX references instead of UUID references in its configuration file. This results in inability to boot the USB memory outside VirtualBox, because /dev/sdX differ between machines. There are vague suggestions on how to make grub use UUID references instead. But I found that grub seems to solve this on it's own.

What I did was only these simple commands in the VirtualBox machine:

apt-get update
apt-get upgrade

This silently replaced the /dev/sdX paths with UUID= references and made it bootable outside VirtualBox. I did not change any configuration files.

In the VirtualBox you may also want to edit /etc/fstab and add noatime, to stop adding access times to every file read from.

Edit the line that looks like the one below so it has noatime in its options:
UUID=<your uuid> / ext4 noatime,errors=remout-ro 0 1

Run df -h to check how much space you have left. On Debian Stretch 9 with a 4 GB USB memory I had used only about 865 MB (1022 MB with 9.9).

Add more - sudo, WiFi drivers

Basic needs, get vim, sudo, WiFi-drivers for Intel cards. Edit /etc/apt/sources.list, edit the line and add contrib non-free, like this:
deb stretch main contrib non-free
deb-src stretch main contrib  non-free

apt update
apt-get install sudo firmware-iwlwifi
adduser <username> sudo

sudo +3108 kB
firmware-iwlwifi +46,7 MB

Add more - console tools

If you intend to run this as a console only system, you may want to install some more. net-tools is ifconfig and pciutils is lspci.

apt-get install net-tools htop vim pv iotop pciutils lshw memtest86

Edit /etc/default/grub 

Decrease the timeout at GRUB_TIMEOUT=<seconds>

Edit GRUB_CMDLINE_LINUX so it does not have quiet but has net.ifnames and biosdevname so it uses traditional network interface names (ethN, wlanN):

GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"

Save the file and run update-grub to update with the changes and possibly (grub-install /dev/sdXY).

Also edit /etc/ssh/sshd_config to get root login allowance. Uncomment so it says:
PermitRootLogin yes

service sshd restart

Add more - Login manager and Graphical interface with

Comparison of desktop environment disk consumption:

apt install
  xfce4 = +600 MB
  xfce4 xfce4-goodies = +656 MB
  lxde-core = +670 MB
  mate-desktop-environment-core = +773 MB (not enough applications for me at least)
  kde-plasma-desktop = +1598 MB
  task-xfce-desktop = +2071 MB
  task-lxde-desktop = +2130 MB
  cinnamon-desktop-environment = +2904 MB
  task-gnome-desktop = +3011

Graphical interface with LightDM and MATE desktop:
apt-get install lightdm mate-desktop-environment-core mate-applets network-manager network-manager-gnome mate-power-manager

network-manager +21 MB
network-manager-gnome +15MB

You need the gnome package to get the network status applet working. The power manager is to manage how it handles lid open/closing and power buttons.

Edit /etc/NetworkManager/NetworkManager.conf to make the network applet manage the interfaces, change the section below so managed says true:


Restart network manager:
service network-manager restart

I also had to restart the virtual machine to get the network connection icon.

To get auto-login with LightDM, edit /etc/lightdm/lightdm.conf, find the #autologin-user= line, comment it out and fill in the username to login.

If you want to autologin, then you do not want to enter password to unlock the keyring either. Install seahorse:
apt-get install seahorse

Run it as the local user:

Then right click on Login in the left panel, select change password, enter the password, then when prompted for a new one leave them blank and ignore the warning. You will then not be prompted for login each time.

Add more - Partition editor, package manager, web browser, text editor, git, disk monitor, audio

apt-get install gparted synaptic pluma chromium git smartmontools firefox-esr firefox-esr-l10n-sv-se pulseaudio

gparted +12,1 MB

If you install Google Chrome / Chromium, you may want to move the cache to a RAM disk:

For Firefox no RAM disk is needed:

You seem to get some kind of basic sound system without Pulseaudio, but it does seem to refuse to use any other sound card than the default without it.

To start the Pulseaudio daemon after installation run pulseaudio --start as the regular user and not root.

Add more - remote desktop client

To get Remmina, add Backports. Edit /etc/apt/sources.list, add this:
deb stretch-backports main contrib
Then update
sudo bash
apt-get update
apt install -t stretch-backports libssh-4 remmina

An alternative if Remmina is too big is rdesktop.

Add more - ISO Hiren's Boot CD

It is possible to add Hiren's Boot CD to the boot menu.

However, there are some requirements:

- The contents of the CD must be extracted and placed on a FAT32 partition.

- The FAT32 partition must be the first partition numerically - sdX1, because Grub4Dos inside the ISO expects this. This means that it is not enough to just move the current partition to the right and create a new partition to the left of it. You must renumber the partition (so sdX1 actually is sdX1), and this will also break Grub, so you will have to re-install it on sdX.

Create a FAT32-partition in front of the other partitions.

Ensure the partition is numerically number 1 by using sfdisk, see the note on how to change partition order and renumber partitions. Check that Linux boots as before even with the FAT32 in front of it.

You should end up with:

/dev/sdX1 - the FAT32
/dev/sdX2 - the Linux partition

Download the ISO and open it in Engrampa or another viewer. Mounting it seems to fail, it errors access denied when the mounted directory is accessed, but opening the ISO in a viewer works.

Extract the HBCD folder to the root of /dev/sdX1.

Go into the directory and extract grub.exe:

cd HBCD/Dos/
mkdir tmp
cp dos.gz tmp/
cd tmp/
gunzip dos.gz
mkdir img
mount dos /img -o loop
cd /img
cp grub.exe ../../../../ # copy it to the root directory in sdX1
cd ..
umount /img
cd ..
rm -rf tmp/

The contents on the FAT32 partition should be grub.exe and HBCD/.

Then on the Linux partition containing the Grub configuration, edit:

Add this at the bottom:

menuentry "Hiren's Boot CD 15.2" {
 linux16 (hd0,1)/grub.exe --config-file="find --set-root /HBCD/menu.lst; configfile /HBCD/menu.lst"

Update grub:
grub-install /dev/sdX


Add more - Debian live ISO and other live ISO:s

It is possible to add a live ISO.

Notice, in this example is Debian netinstaller, this can be live booted like this, because it lacks support for ext filesystems, so it ends up in missing cd-rom drivers, because it expects to run of a cd-rom setup.

Create an iso/ directory in the Linux partition.

Put the iso:s there.

Mount it and find out where vmlinuz(.efi) and initrd.gz resides

mount /iso/<isofile>.iso /mnt
cd /mnt
find|grep vmlinuz
find|grep initrd

Note the paths, for example for Debian netinstaller:

Edit /etc/grub.d/40_custom, add this at the bottom:

menuentry "Name of the Live ISO" {
 set isofile="/isos/<name of the iso>.iso"
 loopback loop (hd0,1)$isofile
 linux (loop)/<path-inside-iso-file-to-vmlinuz/vmlinuz.efi>/vmlinuz boot=casper iso-scan/filename=${isofile} quiet splash
 initrd (loop)/<path-inside-iso-file-to-initrd.gz>/initrd.gz

Example, Debian netinstaller:
menuentry "Debian 10 netinstaller live" {
 set isofile="/isos/debian-10.0.0-amd64-netinst.iso"
 loopback loop (hd0,1)$isofile
 linux (loop)/install.amd/vmlinuz boot=casper iso-scan/filename=${isofile} quiet splash
 initrd (loop)/install.amd/initrd.gz

Adding Windows installer ISO:s

The Windows (7) installer needs the file structure of an extracted ISO, not the ISO, therefore the ISO cannot be added directly.

But the Windows (10) ISO:s can be extracted to a separate partition on the USB drive and then GRUB can boot that.

Create a new partition on the USB drive beside of the Linux partition using gparted or cfdisk. If using cfdisk, use type 7 HPFS/NTFS/exFAT.

Format the partition that was created as NTFS:
mkfs.ntfs /dev/sdXY

Make some temporarily mount locations for the ISO and the target partition on the USB drive:
mkdir -p /mnt/windowsiso
mkdir -p /mnt/usbwindows

Mount the Windows installer ISO:
mount -t udf /path/to/windows.iso /mnt/windowsiso

Mount the target partition on the USB drive:
mount /dev/sdXY /mnt/usbwindows

Copy the contents of the Windows installer ISO to the partition on the USB drive:
rsync -vr /mnt/windowsiso/ /mnt/usbwindows/

Sync and unmount:
umount /mnt/usbwindows
umount /mnt/windowsiso

Boot the USB drive, start Linux and login.

Open /etc/grub.d/40_custom in a text editor, add the following at the bottom and save the file:

menuentry "Windows 10 Installer" {
    insmod ntfs
    search --set=root --file /bootmgr
    ntldr /bootmgr

Update grub:

The Windows installer menu entry should now be available when booting the USB drive. Note, a blinking underscore appears for several seconds when booting the Windows 10 installer ISO, please be patient.


This is a personal note. Last updated: 2022-11-12 22:04:49.







Don't forget to pay my friend a visit too. Joakim