How to use a USB stick for both Slackware15-Live and storing data
Table of Contents
Introduction
Recently Slackware released its new stable version, 15.0, and I decided to update my system moving from the “-current” flavor to stable. I usually set up my laptop in dual-boot with the main operating system (which is almost always a Linux flavor) and a rescue/maintenance live system that runs completely in RAM. In particular I use the latter for these two purposes:
-
Configure the main system in all possible scenarios: for instance when the root partition of the main system needs to be unmounted.
-
Browse the web when the security should be at the top level: the live system always starts from the same snapshot so it doesn’t persist the data. For example this is very useful when you want to check your bank account without the risk of being spied by a malware.
The same steps to install the live system can be followed to install it directly on the Hard Drive or on a USB stick. In this article I will explain how to do that.
In general the Linux live distributions provide an ISO image which can be put on a CD-ROM or on a USB stick copying the image byte-by-byte. However, following this approach, you won’t be able to use the device for anything else. It would be nice to be able to use directly the hard drive and boot the live system from it. The flexibility of my approach overcomes all the issues just introduced.
These are my requirements:
-
The system must run entirely from RAM to enable the unmounting of the USB drives and hard drives during system execution.
-
The procedure must allow the user to choose if he wants to keep the ISO image on the hard drive or if he wants to create a bootable USB. In the latter case all the space on the USB device must be available to the user. In other words the USB drive is not dedicated entirely to Slackware Live, but it can be used for storing other files.
-
The target must be a UEFI system (64-bit)
Install GRUB-2 on the USB drive
If you want to keep the ISO image on your hard drive and you have Grub-2 already installed you can skip this section.
I had a 32 GB USB drive and I used cfdisk to create a GPT table and three partitions:
Block Device | Description | Filesystem | Size | Label |
---|---|---|---|---|
/dev/sdX1 | the EFI System Partition (ESP) | FAT32 | 1 GB | USBESP |
/dev/sdX2 | for Grub-2 and Slackware Live ISO image (~4.2 GB) | EXT4 (without journaling) | 5 GB | USBBOOT |
/dev/sdX3 | this partition is the remaining free space | exFAT | 26 GB | USBDATA |
$ cfdisk -z /dev/sdX
$ fdisk -l /dev/sdX
$ mkfs.fat -n USBESP -F 32 /dev/sdX1
$ mkfs.ext4 -L USBBOOT -O ^has_journal -m 0 /dev/sdX2
$ mkfs.exfat -L USBDATA /dev/sdX2
The layout of the USB stick seems a little bit “unusual”: why do I need three different partitions? If the ISO image is a file and it can be stored in USBDATA, therefore just two partitions are enough (see the last section where I describe the experiment I did and the missing step required to reduce the number of partitions).
We are now ready to install Grub-2 and create an automatic configuration:
$ mkdir -p /mydisk/USBESP /mydisk/USBBOOT
$ mount /dev/disk/by-label/USBESP /mydisk/USBESP
$ mount /dev/disk/by-label/USBBOOT /mydisk/USBBOOT
$ grub-install \
--directory=/usr/lib64/grub/x86_64-efi \
--boot-directory=/mydisk/USBBOOT \
--efi-directory=/mydisk/USBESP \
--removable \
--target=x86_64-efi \
/dev/sdX
$ grub-mkcongif > /mydisk/USBBOOT/grub/grub.cfg
Copy the ISO image of Slackware Live 15.0 in /mydisk/USBBOOT.
Configure GRUB-2
I assume you have created the USB stick from the previous section or you have a computer with installed a Linux distribution and Grub-2. I have my Slackware Live ISO image in /mydisk/USBBOOT and the Grub configuration file in /mydisk/USBBOOT/grub/grub.cfg. Take note of where you have those files and substitute them where necessary.
Open your grub.cfg and look for the section with the menu entries. Even if your grub config has no entries, there should be a section with a comment like this:
### BEGIN /etc/grub.d/10_linux ###
Copy one of your existing entries and modify it, or copy and adapt my configuration:
menuentry "Slackware 15 Live" --class gnu-linux --class os --class icon-linux {
load_video
insmod gzio
insmod ext2
set iso='slackware64-live-15.0.iso'
set bootparms='load_ramdisk=1 prompt_ramdisk=0 rw printk.time=0 kbd=us'
# search -f /$iso --set=root
set root=(hd0,gpt2)
loopback loop /$iso
linux (loop)/boot/generic $bootparms locale=en_US.utf8 tz=UTC livemedia=/dev/sdX2:/$iso toram 3 # debug=3 rescue
initrd (loop)/boot/initrd.img
}
As you can see I preferred to set the root directly to (hd0,gpt2) rather than rely on the autodiscovery (see the line “search -f /$iso –set=root”). My approach is less flexible, but it is simpler to debug. Feel free to comment my line “set root=(hd0,gpt2)” and uncomment the previous line to enable the autodiscovery.
The other parameter that you need to change from my snippet is “sdX2”. You should put your block device that refers to the partition that contains the ISO image.
The main parameters that the bootloader passes to the kernel (and initrd) are:
-
“kbd=us”: set the US Layout for the keyboard
-
“locale=en_US.utf8 tz=UTC”: set the locale and time reference
-
“livemedia=/dev/sdX2:/$iso”: this parameter is used by the init script in initrd.img to mount the partition that hold the ISO image
-
“toram”: with this parameter the bootstrap will copy everything in RAM and will disable the automatic mount of all persistent storage (USB, hard drive).
-
“3”: this is the runlevel. I prefer to start the OS in text-mode. Remove this number if you prefer the X server to start automatically.
Reboot and login to Slackware Live 15.0
Let’s reboot and see if the new system boots correctly. If you have used the same configuration as me for Grub-2, after the bootstrap, you should be able to see the login prompt still in text-mode. You can use one of the following users:
Username | Password | User type |
---|---|---|
live | live | regular user |
root | root | administrator |
Now you can choose the window manager and start the X session:
$ xwmconfig # This will present a list of the available wm and let you select the default
$ startx
The beauty of simplicity: the KISS principle in Slackware
When I was a kid, I was very curious to know how things worked. Electricity and computers were my favorite topics. One of the big questions I had was “What does happen when the computer has been switched on”. Installing dual-boot systems and playing around with Linux helped me a lot to increase my understanding of it. If you are a person like me, you probably want a little bit more than just a guide to follow step-by-step. You want to know the basic concepts behind each step and how I figured out this process.
I believe the KISS principle (Keep It Simple, Stupid) is one of the best discovered. It basically means that if you can do one thing in two ways, keep the simplest. Don’t be a stupid. In other words, you should introduce complexity only when required. In Slackware the implementation of this concept allows you to feel the system at your fingertips and it helped me to figure out how to use its live flavor exactly as I wanted to do.
Before finding out the option “toram” was already implemented I was about to download the Slackware Live image, learn how it works, and customize it to run fully in RAM. I used to use other distributions already providing that behavior (Puppy Linux is probably the most famous), but since I use Slackware as my main system it makes a lot of sense to have it also as the live system. I will be able also to generate my own live edition that suits exactly my needs.
The second advantage coming from the application of the KISS principle is the easiness of the troubleshooting process.
If you are not new to the booting process, you probably already know the following things will happen when you switch on your computer:
-
The processor starts executing the firmware of the computer (the BIOS for old systems, and UEFI with a modern laptop)
-
In the case of UEFI there is a bootmanager that looks inside the EFI System Partition (ESP) and decides which entry to run.
-
The entry is usually a bootloader, Grub-2 in our case; the bootloader finds the kernel and the initrd, loads them in RAM and executes the kernel.
-
The kernel performs some initialization and uses the initrd as a temporary root filesystem.
-
The kernel looks for the /init or /sbin/init file in the initrd and runs it. This should perform the remaining task for the boot process (mainly it sets up the root filesystem and switches to it)
The init file can be any executables, but the simplest case is when it is a shell script so, with no surprise, we find this is exactly what the Slackware folks decided to use in their initrd. If you want a deep understanding of how it works (so you can customize it if you need to do so), just extract the files in initrd.img and open the init file with your favorite text editor.
$ mount -oro /mydisk/USBBOOT/slackware64-live-15.0.iso /mnt
$ file /mnt/boot/initrd.img
usb/boot/initrd.img: XZ compressed data, checksum CRC32
$ xzcat boot/initrd.img | file -
/dev/stdin: ASCII cpio archive (SVR4 with no CRC)
$ mkdir /tmp/slacklive-initrd; cd /mnt/slacklive-initrd
$ xzcat /mnt/boot/initrd.img | cpio -i
$ vim init
As you can see it is a “cpio” archive compressed with “xz”.
Read the first lines and you will find all the options that can be used in the configuration of the bootloader. This way I discovered there is a parameter called “rescue” which is very convenient when your system doesn’t boot properly complaining about not being able to find the root device. This isn’t used only in the initrd of the live edition of Slackware, but also in the initrd of the main system. You can create an additional boot entry with this parameter in case you are a Slackware user.
Reading the init I found other interesting options:
-
“livemedia=scandev:/path/to/slackwarelive.iso”: you can use “scandev” instead of /dev/sdX2 if you want to let the system figure out where the Slackware ISO is
-
“nop” (no persistence): if you want to boot a fresh system that mounts only the root filesystem from USB (read-only)
-
“toram=os”, “toram=core”, “toram=all”: the first option loads the OS in RAM but lets it mount a persistent partition to save changes. The second loads only the core of the OS and puts it in RAM, while the last one is equivalent to “toram” (the full OS is loaded in RAM and any automatic mount in read-write mode is disabled)
Issues faced and improvements
As promised, I will now explain why I ended up with three partitions in the USB drive and how you can use only two.
What was the issue with two partitions in the layout of the storage device
In the beginning I started partitioning the USB into two slices. I used the FAT32 filesystem since that is the standard for ESP and USB sticks. It is a very basic filesystem implemented both in Linux and Windows and is reliable enough for the kind of data that a USB should keep. The first problem is that the maximum size of a single file in a FAT32 filesystem is about 4 GB, but the ISO of Slackware Live has a bigger size.
I found that both Linux and Windows support an improved version of FAT, called exFAT, and that was my second choice. The problem is that the initrd of Slackware Live does not have the exFAT kernel module in it.
Therefore, if the filesystem is the problem, I can split my USB drive into 3 partitions. The first is the ESP. The second will use an EXT filesystem (available only under Linux) and will keep the ISO image. The purpose of the third partition is only to keep any other file that I want to put on the USB drive. I will use the exFAT filesystem since I want to use it both on Linux and on Windows (and on other operating systems).
At this point I made another mistake: I used the ext2 filesystem. In particular the ext2 is the old standard filesystem. Ext3 is basically ext2 plus the journaling feature. Ext4 is the new standard filesystem. I didn’t want the journal to be active since it lowers the life of your flash drive increasing the number of write operations. Then I initially opted for ext2 because it felt to me more similar to FAT than an ext4 with journaling disabled. It took me a while to figure out why it wasn’t working because the error wasn’t that clear and if you use the “rescue” boot parameter to stop the booting process and you try to mount the partition with:
$ mount /dev/sdX2 /mnt
it seems to work fine. I finally dug into the init script and following the lines of bash code I found out the init script automatically gets the filesystem and executes a command similar to:
$ mount -t ext2 /dev/sdX2 /mnt
Eventually, when I tried this command in rescue-mode, I got the same error I could read during the bootstrap. This apparently weird behavior is because the initrd does not contain the kernel module for ext2 and the mount command looks only for it when the parameter “-t ext2” is specified (thus we have the failure). When the filesystem is not given, it tries all the modules including the ext4 which can mount the ext2.
That is how I came out with that three-partition layout.
Use only two FAT partitions in the layout of the USB drive
If you find my three-partition layout more as a workaround rather than a solution I feel that too. At the moment it is good enough and I am keeping it that way, but the next time I will address the issue at the root. Rather than changing the filesystem of the partition that holds the ISO image, you can rebuild the initrd including the exFAT module.
It should be as simple as this (use the root user):
$ mkdir initrd-folder; cd initrd-folder
$ xzcat /path/to/initrd.img | cpio -i
$ mkdir -p lib/modules/5.15.19/kernel/fs/exfat
$ cp /lib/modules/5.15.19/kernel/fs/exfat/exfat.ko lib/modules/5.15.19/kernel/fs/exfat/exfat.ko
$ find * | cpio -o | xz -c > /path/to/initrd-exfat.img
and don’t forget to put it on the USB drive and update manually grub.cfg to make it use the new initrd rather than the old one. If you are not on Slackware 15 or if you have updated your kernel, you can download the package “kernel-modules-5.15.19-x86_64-2.txz” from the official repository of Slackware and extract the file exfat.ko (or you can temporarily put the Slackware Live ISO on a USB with “dd” and rebuild the initrd from it).