Create LiveUSB in a general way

We can produce our own LiveUSB manually. The following are the steps that based on Arch Linux distro.

  1. Build a kernel that supports AUFS, SquashFS, and optionally vfat support. So that we can mount these filesystems. In Arch Linux, we can build linux-pf for these supports. This package can be found from AUR.
  2.  Then we can generate the initramfs. In Arch Linux, we can use mkinitcpio to create an initramfs image. For instance,
    mkinitcpio -k /boot/vmlinuz-linux-pf -c mkinitcpio-custom.conf -g initramfs.img

    (In Arch Linux, it is recommended to add in some modules in the mkinitcpio configuration file: zram, squashfs, loop, fuse, aufs, vfat)

  3. Besides that, we also need to prepare a squashfs so that it will act as a read only filesystem with workable programs. In order to create the squashfs, we can prepare it by using the existing filesystem.
    The important folders are: bin, etc, home, lib, mnt, opt, root, sbin, srv, usr, var.
    The important folders but let them empty are: dev, media, proc, run, sys, tmp.
    And also need to comment the lines in the /etc/fstab, so that after boot, there is no automount.
  4. Then we can prepare a USB pendrive so that it can boot by using syslinux. syslinux will run the syslinux.cfg, which can be located at /syslinux or /boot/syslinux. The simplest way to make the syslinux.cfg to boot is something like
    DEFAULT myliveusb
    LABEL myliveusb
    KERNEL vmlinuz-linux-pf
    APPEND initrd=initramfs.img

    By this, it will use the kernel vmlinuz-linux-pf which is built at the beginning (in step 1), and initrd with the initramfs.img that is generated (in step 2). These files need to be put at the same path with syslinux.cfg.

  5. In order to boot properly, we need to modify the “init” file in the initramfs.img. This image is actually compressed cpio. We can extract the data by
    zcat ../initramfs.img | cpio -i

    The extracted data contains some scripts, kernel modules, and libraries that are required to boot up. So, we just modify the init script.
    In the init script, we may need to disable the fsck_root (in Arch Linux) so that it will not fsck the root file.
    Then, we need to add in the statements to mount the USB pendrive and created squashfs.
    Therefore, we add in the following statements to somewhere before the initramfs switch the root.

    #The statements are based on
    mkdir -p /mnt/usb /squashfs /tmpfs
    mount -t vfat -o ro /dev/disk/by-label/MYPENDRIVE /mnt/usb
    mount -t squashfs -o ro,loop /mnt/usb/path-to/root.sfs /squashfs
    mount -t tmpfs none /tmpfs
    #cd /tmpfs ; mkdir -p tmp var/log ; chmod 1777 tmp ; cd / #This step is optional
    mount -t aufs -o br=/tmpfs:/squashfs none /new_root #where the new_root is the root which will be switched according to Arch Linux

    Finally we need to re-compress by

    find . | cpio -o -H newc | gzip > ../initramfs.img

    If we read through the init script, at the end there is a statement that calls “switch_root” which will switch to the /new_root. Then, the system will boot successfully.

The AUFS is required because SquashFS is read-only. The following is the explanation of the statements above,

mount -t vfat -o ro /dev/disk/by-label/MYPENDRIVE /mnt/usb

is to mount the current USB pendrive to the /mnt/usb. We use the /dev/disk/by-label because it is the easiest way by referring the pendrive based on the label. /dev/sd{a,b,c} and so on are not applicable because different computer may have different number of storages. After this,

mount -t squashfs -o ro,loop /mnt/usb/path-to/root.sfs /squashfs

we mount the root.sfs which is created by mksquashfs. Then,

mount -t tmpfs none /tmpfs

we mount the tmpfs to a new folder /tmpfs. So that we use the memory for read-write operation. We do not use the default /tmp because it is used by initramfs.

cd /tmpfs ; mkdir -p tmp var/log ; chmod 1777 tmp

This is to create a tmp folder with the 1777 ownership as /tmp in the root. Finally,

mount -t aufs -o br=/tmpfs:/squashfs none /new_root

we mount the tmpfs and squashfs unionly to the /new_root

Because tmpfs is writable, squashfs is read-only, but they are mounted unionly in the new_root, as a result after switch_root, then it can boot and write to the new_root file system, as all the data are actually stored in the memory (as tmpfs occupies the memory).

By this, we can also create our own filesystem as a file (formated with ext4), and mount it unionly to the /new_root. So, that we can “save” the data and restore it during the next boot. (I have not yet tested this step by editing the init script.)

AlphaOS a really great LiveUSB

These days, want to compile old projects. Firstly, I compiled all my code using Arch Linux. Then I decided to install my project to a LiveUSB, so that I need not to partition or use virtual machine on the target computer.

So I planned to use KNOPPIX.  I tried Linux Mint in VirtualBox, since it is based Debian, but failed to compile my code due to the CEGUI version is not the latest as Arch Linux.

As a result, I decided to use ArchPup (Puppy Linux). But ArchPup is superseded by AlphaOS. And, it solved my problem.

However, there are some limitations. Firstly, the latest version only support 64-bit computer. Secondly, problem of hardware driver. I wanted to install the broadcom-wl, but I cannot get the linux-headers. And the linux-headers of AlphaOS is different from Arch (because of different built). AlphaOS lacks of documentation on how can we produce or customise it. As a result, I can only use the default kernel and run my project without network connection.

Since the official site mentioned about Linux Live Kit. So, I tried to create my “dream LiveUSB” from the Arch Linux in the VirtualBox by this Linux Live Kit. However, I failed. I tried to compile the kernel with linux-pf (because it supports AUFS), then build the image using Linux Live Kit. But the OS was freeze in VirtualBox if I use the linux-pf kernel. This may be the caused by virtualbox-guest-modules.

Now, I am still trying to build my dream LiveUSB.