3

I would like to create a 64GB multiboot usb drive.

I want the first partition to be a 32GB fat32 partition so that I can use it for accessing files from windows. (Windows only displays the first partition on a removable drive).

I then want to put a couple (or more if possible) of linux distros on the later partitions.

I assume I will need a small boot partition (ideally syslinux)... but it can't be the first partition.

How would I best go about this setup?

All the utilities I have looked on (linux and windows) for making multiboot USBs don't give options for having an extra partition at the start of the partition table.

  • I have such a stick, with FreeDOS on the first partition which Windows also sees and uses as regular data partition. So it works fine and it's not a problem whatsoever. What have you tried, what didn't work? – frostschutz Nov 21 '15 at 17:59
  • I was hoping to have an empty first partition. – Beakie Nov 21 '15 at 18:01
  • if all of the computers you wish to boot from this stick are older than say 7 or 8 years, then your description of the device is logical. but if you're going to be using it on modern systems, FAT is the official /boot format. It's the only filesystem that is required to recognized by a UEFI firmware. With a modern system, you don't need syslinux or anything like it - just a folder at the root of the tree named BOOT. – mikeserv Nov 26 '15 at 9:24
  • The first partition need to be fat32, the remaining partitions need to be ext4 – Beakie Nov 26 '15 at 9:55
  • Related question from Ask Ubuntu: Multi-partition multi OS bootable USB – landroni Feb 27 '17 at 15:41
1
+50

I believe the tool you are looking for is YUMI. I have almost the exact same setup you are referring to on a 64G USB drive. You didn't specify if you wanted these to be Live distros or full installations, but here is my personal setup:

64G USB flash drive formatted using whatever format YUMI specified (I forget, but I believe it's Fat32 -- but it doesn't really matter, since it just works "out of the box"). From within YUMI, you can select multiple Linux ISOs, which it will give you the ability to Live Boot from whichever one you select at startup.

One thing to note, however, is that if your USB drive is not currently in the format that YUMI prefers, it will need to reformat the drive accordingly, so make sure any important files are not currently stored on the drive before re-formatting it to instal your first Linux distro.

YUMI automatically stores each of these distros in a directory on the root of this USB drive called multiboot, which contains everything related to YUMI and the stuff that is needed to run your Linux distros. You can use the rest of this USB drive to store whatever you want.

Personally, I have win, osx, and nix folders containing important tools and portable apps, and these directories are on this same USB drive right alongside the multiboot directory. If I boot into an OS normally and then insert this USB drive, all of my files are available to use.

However, if I'm on a Windows machine, I have the ability to boot directly from this USB flash drive into the YUMI bootloader (which I believe is a customized form of GRUB), and it allows me to select from all of the live distros it has installed in the multiboot directory. I think it even gives the option to boot Windows normally, or it may just be an exit option, which just reboots and then I can boot Windows normally from the internal drive.

If you want to persistently-preserve files across reboots and run Linux like a full installation, I believe YUMI has the option to create a separate static partition on the drive, but it claims to be limited only to Ubuntu. It may work with Debian as well, but I have never tried this method. Then again, I could be getting this specific feature completely confused with a feature included in UNetbootin, which the last time I used, did not support all of the multi-boot options that YUMI supports. In my personal opinion, YUMI is way better than UNetbootin.

It should be known, however, that I did encounter a downside when using YUMI:

At one point I had live versions of Backtrack, Knoppix, Crunchbang, and Linux Mint installed via YUMI. A few months later, I wanted to load this USB in YUMI and remove Backtrack and replace it with Kali Linux, but YUMI informed me that they had upgraded their bootloader, and as a result, if I wished to install additional distros, I would have to reformat the drive and start over from scratch using their new bootloader, which was incompatible with the older distros I had previously installed that used their old bootloader.

This would not be a huge deal, but it would be an annoyance to tar the contents of my normal files and move them off the USB and then re-install all of the other Live ISOs that I wished to keep via YUMI. However, it would more than likely be a dealbreaker if you wanted to have a separate partition to store files across reboots (which like I said, I could simply be confusing with a feature of UNetbootin, as opposed to YUMI).

All of that being said, from your specific question, I believe YUMI should adequately benefit the purpose of what you are looking to achieve. It's a great tool that has served me well in the past.

2

The following requires a computer using a BIOS to boot or supporting some form of "legacy" boot mode (Compatibility Support Module) – at least I think it does: I have no experience with EFI systems.


To create a bootable usb stick with syslinux you:

  • create the partitions
  • initialise the file-systems on the partitions
  • install syslinux onto a partition
  • mark syslinux partition active
  • install syslinux' mbr code

After these steps you should be able to boot from the usb stick and, upon booting from the stick, will be greeted with the syslinux boot prompt; there you can issue commands to load further code and continue the boot process.

In order to not having to type a long commandline on every boot one can create a file syslinux.cfg to hold the commandline, possibly multiple.

Commonly one also installs syslinux modules by copying the appropriate *.c32 files to the syslinux directory of the partition; examples for these modules are: menu.c32, chain.c32.

Example Image

Since I do not have a free usb stick lying around I created an 2GB image for the example by issuing:

dd if=/dev/zero of=example.img bs=1k count=2M

which I then attached to a loop device by running:

losetup --find --show example.img

This command requires the parameter max_part of the loop module to be set to a number at least as big as the number of partitions in the image file:

rmmod loop
modprobe loop max_part=10

If the loop module was built into the kernel you can specify max_part as a boot paramter to the kernel:

loop.max_part=10

Alternativly you may use kpartx to set the loop devices up:

kpartx -av example.img

Device nodes for the partitions can be found below /dev/mapper/. If you use kpartx and want to follow the example along you should set the dev_part variable appropriately.

Variables

For the examples I have set the following variables:

# device node
dev=$(losetup --find --show example.img)
# set to e.g. /dev/mapper/loop0 when using kpartx
dev_part=${dev}

# loop devices use the letter 'p' to denote partitions (e.g. /dev/loop0p1)
# drives normally do not (e.g. /dev/sda1)
part_divider=p

# path to syslinux modules and mbr
libpath=/usr/lib/syslinux

# Path to mount point; used when e.g. files need editing
mount_point=/mnt

# The number of the partition that you use to share files with windows
files_part_nr=1
# The number of the boot partition
boot_part_nr=2
# The number of the partition that holds a linux distribution CD's content
dist_part_nr=3

As an example distribution I chose Tiny Core Linux:

# Download Tiny Core's iso and set variable "isofile" to its destination
# filename
isofile=$(curl -# -OJ -w '%{filename_effective}\n' "http://tinycorelinux.net/6.x/x86/release/TinyCore-current.iso")

The curl command does the following:

  • -# Show progress with a bar on the terminal
  • -O Write file to a from the url derived name
  • -J Derive name from the "Content-Disposition" header instead of the url
  • -w Write filename to the standard output (which will be stored in the variable "isofile")

Create Partitions

MBR

# Create an empty msdos style partition table
parted -s   "${dev}"   mktable  msdos

# Create two primary partitions (i.e. sdb1, sdb2)
# one holding your files and one for syslinux
parted -s   "${dev}"   mkpart   primary   fat32     0MB   800MB
parted -s   "${dev}"   mkpart   primary    ext2   800MB   900MB

GPT

# Create an empty gpt partition table
parted -s   "${dev}"   mktable  gpt

# Create two primary partitions (i.e. sdb1, sdb2)
# one holding your files and one for syslinux
parted -s   "${dev}"   mkpart   files   fat32     0MB   800MB
parted -s   "${dev}"   mkpart   boot     ext2   800MB   900MB

Initialise File-Systems

# DATA
mkfs.vfat   "${dev_part}${part_divider}${files_part_nr}"
# BOOT
mkfs.ext2   "${dev_part}${part_divider}${boot_part_nr}"

Install syslinux (extlinux) onto a partition

Mount the boot partition and run extlinux:

mount   "${dev_part}${part_divider}${boot_part_nr}"   "${mount_point}"
mkdir   "${mount_point}/syslinux"
extlinux -i "${mount_point}/syslinux"

umount   "${mount_point}"

You may choose any other directory on the partition to hold syslinux' files: put files under the root directory: extlinux -i "${mount_point}"; put files under a directory called /boot: extlinux -i "${mount_point}/boot".

With syslinux the command would look as follows (You should not have the boot partition mounted):

syslinux -i -d /syslinux   "${dev_part}${part_divider}${boot_part_nr}"

Mark syslinux partition active

The default syslinux MBR bootloader code searches for a partition marked active to pass control to find the Volume Boot Record to load.

MBR

# Mark boot partition as active (MBR)
parted "${dev}"   set   "${boot_part_nr}"   boot         on

GPT

# Mark boot partition as active (GPT)
parted "${dev}"   set   "${boot_part_nr}"   legacy_boot  on

If you use gdisk to partition your drive you need to activate "extra functionality" by hitting x in order to be able to "set attributes" (a).

Install syslinux MBR code

dd conv=notrunc bs=440 count=1 if="${libpath}/mbr/mbr.bin" of="${dev}"

For a GPT partitioned drive you use gptmbr.bin instead of mbr.bin.

There also exists an alternative loader altmbr.bin that does not search for a partition marked active, but instead uses a specified partition; use it as per the following:

print '\x2' | cat ${libpath}/mbr/altmbr.bin - | dd conv=notrunc bs=440 count=1 iflag=fullblock of=${dev}

Boot

Add this point you should be able to start from the device and be greeted by the syslinux boot prompt.

qemu-system-i386 -drive file="${dev}",format=raw

Since syslinux is only able to load files from the same partition you will not yet be able to continue the boot process to an OS.

Load a Linux Distribution via Chainloading

Create Partition

Create another partition; either run (for an MBR type partition):

parted    "${dev}"   mkpart   primary   ext2   900MB   100%

or use (for GPT):

parted    "${dev}"   mkpart   distribution   ext2   900MB   95%

Then initialise the file system:

mkfs.ext2 "${dev_part}${part_divider}${dist_part_nr}"

Chainloading

Syslinux' chain.c32 module allows you to chainload to the Volume Boot Record of another partition which can be used to work around syslinux' limitation of only being able to load files of the partition whence it was loaded; that way one can also reuse the syslinux/isolinux configuration files included in the ISO image.

In order to be able to use the chain.c32 module you need to copy it and its dependencies (libcom32.c32 and libutil.c32) into the syslinux directory on the boot partition:

mount "${dev_part}${part_divider}${boot_part_nr}" ${mount_point}
cp "${libpath}/modules/bios/libcom32.c32" ${mount_point}syslinux/
cp "${libpath}/modules/bios/chain.c32" ${mount_point}/syslinux
cp "${libpath}/modules/bios/libutil.c32" ${mount_point}/syslinux
umount ${mount_point}

Next you unpack the ISO-image and rename isolinux.cfg to the name expected by syslinux: syslinux.cfg

mount "${dev_part}${part_divider}${dist_part_nr}" "${mount_point}"
7z x -o"${mount_point}" "${isofile}"
mv "${mount_point}/boot/isolinux/isolinux.cfg" "${mount_point}/boot/isolinux/syslinux.cfg"

I find in cleaner to also rename the isolinux/ folder to syslinux/, although that is not strictly necessary; I also remove some unneeded files:

mv "${mount_point}/boot/isolinux" "${mount_point}/boot/syslinux"
rm "${mount_point}/boot/syslinux/isolinux.bin"
rm -r "${mount_point}/[BOOT]"

TinyCore's iso seems to miss libutil.c32 (needed for menu.c32):

cp ${libpath}/modules/bios/libutil.c32 "${mount_point}/boot/syslinux"

Install the Bootloader on the partition and unmount:

extlinux -i ${mount_point}/boot/syslinux
umount ${mount_point}

Boot

When you now boot the image

qemu-system-i386 -drive file=${dev},format=raw

and enter the following at the syslinux boot prompt:

chain.c32 hd0 3

you should get greeted by the Tiny Core Linux syslinux menu.

Configuration

Mount the boot partition and create a syslinux.cfg file:

mount ${dev_part}${part_divider}${boot_part_nr} ${mount_point}

cat >${mount_point}/syslinux/syslinux.cfg <<EOF
LABEL tc
MENU LABEL Boot TinyCore
COM32 chain.c32
APPEND hd0 3

umount ${mount_point}

On disk partitioned using the GPT format you can use the partition's GUID or its label passing either guid= or label= to chain.c32:

APPEND label=<LABEL>

or

APPEND guid=<GUID>

You can use blkid to find both label and guid.


Grub2

GPT

For GPT grub2 requires an extra partition to store some of its boot code. With parted you create one with the following commands:

parted ${dev} grub_boot 95% 100%
parted ${dev} set bios_grub on

With gdisk you chose ef02 as the type for the partition.

According to the grub info document it should have a minimum size of 31KiB.

Install grub

mount ${dev_part}${part_divider}${boot_part_nr} ${mount_point}
# use --modules="part_gpt" for a gpt partition drive
grub-install -d ${mount_point} --modules="part_msdos ext2"
umount ${mount_point}

I do not know whether --modules is strictly necessary – at least using a loop device grub was not able to access files without it.

Chainloading

At the grub boot prompt type:

insmod chain
set root=(hd0,3)
chainloader +1
boot

And you should see the Tiny Core Linux syslinux menu again.

Configuration

For the Tiny Core Linux example put the following into /grub/grub.cfg on the boot partition:

menuentry "Tiny Core Linux" {
    insmod chain
    set root=(hd0,3)
    chainloader +1
}

To be independent of the order that the drives get listed in you can set the root by UUID; replace set root with:

search --set root --fs-uuid <UUID>

Use blkid to obtain the UUID.

Boot an ISO

Some distributions' live CDs can mount their file-system from within an ISO-image; together with grub's loop feature you can do the following (as an example I use the Archlinux) Live CD):

isofile=archlinux-2015.11.01-dual.iso

mount ${dev_part}${part_divider}${dist_part_nr} ${mount_point}

cp ${isofile} ${mount_point}

umount ${mount_point}

Then use the following in your grub.cfg:

menuentry "Archlinux LiveCD" {
    insmod loopback

    set isofile="archlinux-2015.11.01-dual.iso"
    search --set isodrive --file /$isofile
    probe --fs-uuid --set uuid $isodrive

    loopback loop ($isodrive)/$isofile
    set root=loop

    echo "Loading kernel vmlinuz"
    linux /arch/boot/i686/vmlinuz img_loop=$isofile img_dev=/dev/disk/by-uuid/$uuid
    echo "Loading initial ramdisk archiso.img"
    initrd /arch/boot/i686/archiso.img
}

I found the needed boot parameters for the Archlinux ISO in the archiso git tree.

0

Whatever tool you find which creates additional boot partition at the beginning will cause problems with windows, which will only display the first partition. But if you don't mind having syslinux files in the root of your FAT32 partition, you can simply install syslinux there.

Here's what I would do:

  1. Partition the drive as you see fit, with the first partition being 32GB FAT32
  2. Install Linux distributions you like, one by one, using syslinux
  3. After installing each distro, back up its syslinux configuration files somewhere

Once you're done, you should have your last distro readily bootable, and the correct config files to boot distros installed before it. Then you'll have to create syslinux menu in its config file and chain backed up configurations to boot each distro you have installed.

  • I don't want the first partition to contain any reference to syslinux etc. It needs to be an empty (windows readable) partition... with the rest of the partition dedicated to my boot distros. – Beakie Nov 27 '15 at 15:21
  • Why would it be a problem to have a couple of syslinux-related files on it? – Dmitry Grigoryev Nov 28 '15 at 20:10
  • I think it's reasonable to say "I just do" to save this thread from getting distracted from my question. I appreciate that you think I don't need to but I politely request you believe me :) – Beakie Nov 29 '15 at 22:28
0

On recent enough hardware ( 2007 and up) usb flash drives are nothing special ( just another hard drive). Therefore, you can use a windows install CD to format it as a regular "small hard drive (MBR)". You could install windows on the first 32GB primary partition ( you can use NTFS since fat is not that good at that size) and then add an extended partition, slice it up in chunks of 12Gb and install linux as usual. You could use a /home partition shared and mountable for all distros and recycle the same UID/GUID to make your home directory portable. Just make sure you have all SSD optimizations on for both windows and Linuxes and don't fill the thumb drive fully.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.