GRUB on USB Drive — adding OSes

boot-loaderdual-bootgrub-legacykernelusb

Some Background:

  • Coming from a largely Windows background (though I'm familiar with Ubuntu, etc.) and using a Windows 7 machine to complete this task
  • Have gotten GRUB installed successfully to the MBR of the USB drive (8 GB FAT32 drive):
  • Have created a basic structure on the drive: /boot/grub, /boot/img, /boot/kernel

Question:

I have some basic, beginner questions, but ones that I've had trouble finding answers to through Google / StackExchange, etc.

  • I understand that the /boot/img/[SystemName] folder will store the image for a specific system, which may use various (or the same) versions of linux kernels stored in the /boot/kernel directory (at least, that's how I'd like to set it up)
  • However, most of these systems just have a kernel in their directories called "linux" (not stating the version). I can search out which kernel these all use, but what's the bst place to get the kernels themselves to copy to /boot/kernel?
  • After I get the kernels, I imagine the rest is mostly copying the device to /boot/img/ and creating the proper entry in menu.lst, correct? I can do that on a system by system basis once I can get the kernels to refer to.

Overall Goal:

I'm attempting to create an 8GB usb flash drive that will allow me to boot multiple OSes from a GRUB boot menu. To add or subtract OSes, I would like only to have to copy the appropriate files to a /boot/img/[SystemName] and a /boot/kernel folder as appropriate and then edit the menu.lst file. So, this first step is about finding the kernels that many of these OSes share, as I'm hoping to reduce duplication.

Best Answer

What you are trying to achieve is stretching boot technology :) However I think it is possible, though I am not knowledgeable enough to give a complete walk-through.

First, like said before, distros have very different requirements. Second, the good thing on the other hand, you can also find distros which need minimal requirements.

I would recommend to use GRUB4DOS as bootloader. See this link how to use it with USB (because it has the find --set root -- command, which is important if you have mobile device like USB).

Then you have to decide how many partitions you will use. Standard "Full install" is always in a single partition. So if you have an 8 GB USB stick and take 4 GB partition (which allows minimal installation) you would be limited to 2 different "Full Installs" of main distros like Debian or Fedora.

However, there are some small and specialized Linux distributions. For example "Puppy Linux" is very small and has a special "Frugal Installation" mode. It comes in many flavors (e.g. there is MacPup with tries to implement an Apple like Desktop, or Fatdog64 which is a 64-bit Linux).

In this "Frugal installation" mode it just uses exactly 1 directory and can be installed in parallel to an existing Linux or Windows on the harddisk (or USB). I am sure there are other distributions that support similar modes.

Since Puppy Linux is small (< 150 MB) and assuming you reserve a small savefile for each installation (512 MB), you could easily install like 10 different Operating Systems on the USB stick. There are even smaller Linuxes (Slitaz, Tinycore), which you could use.

As example, I attach the menu.lst (GRUB4DOS) file from my current PC-install, The first 8 entries are all different Puppy Linux installation on hd0,2 (i.e. the 3rd partition on the 1st hardisk), then there is a minimal Debian installation in a small extra partition and also the original Windows-XP.

timeout=10
default=0  

  title Linux Buero (on /dev/sda3)
  root (hd0,2)
  kernel /puppy431-de/vmlinuz psubdir=puppy431-de pkeys=de ro vga=normal
  initrd /puppy431-de/initrd.gz

  title Live CD build (on /dev/sda3)
  root (hd0,2)
  kernel /puppylivecdbuild/vmlinuz psubdir=puppylivecdbuild ro vga=normal
  initrd /puppylivecdbuild/initrd.gz

  title sage developement(on /dev/sda3)
  root (hd0,2)
  kernel /Sage46dev/vmlinuz psubdir=Sage46dev pfix=nocopy ro vga=normal
  initrd /Sage46dev/initrd.gz

  title sage developement test and fun
  root (hd0,2)
  kernel /Sage-test/vmlinuz psubdir=Sage-test pfix=nocopy,noram ro vga=normal
  initrd /Sage-test/initrd.gz

  title Lupq 511
  find --set-root --ignore-floppies /lupq511/initrd.gz
  kernel /lupq511/vmlinuz psubdir="lupq511" pfix=nocopy pkeys=de ro vga=normal
  initrd /lupq511/initrd.gz 

  title Lupu 520 - New kid on the block
  find --set-root --ignore-floppies /lupu-520/initrd.gz
  kernel /lupu-520/vmlinuz psubdir="lupu-520" pfix=nocopy pkeys=de ro vga=normal
  initrd /lupu-520/initrd.gz 

  title wary beta (on /dev/sda3)
  root (hd0,2)
  kernel /wary/vmlinuz psubdir=wary ro vga=normal
  initrd /wary/initrd.gz

  title spup (on /dev/sda3)
  root (hd0,2)
  kernel /spup/vmlinuz psubdir=spup ro vga=normal
  initrd /spup/initrd.gz

  title Debian (on /dev/sda2)
  find --set-root --ignore-floppies /initrd.img
  kernel /vmlinuz root=/dev/sda2 ro
  initrd /initrd.img

  title Windows NT/2K/XP\nStart Windows if installed on HDD
  fallback 7
  find --set-root --ignore-floppies /ntldr
  chainloader /ntldr

boot

The menu.lst on your USB could look similar, the GRUB4DOS command find --set-root --ignore-floppies /lupq511/initrd.gz (looks for this file in all drives) could be very useful if you use USB, so you don't have to use fixed entries for your drive.

With the above information some comments on your original questions:

Q: * I understand that the /boot/img/[SystemName] folder will store the image for a specific system, which may use various (or the same) versions of Linux kernels stored in the /boot/kernel directory (at least, that's how I'd like to set it up)

A: I am not sure if that is going to work, since most of the major distributions expect to have exclusive right of their partition and install a specific directory structure for their files. In my opinion it is better to respect the default setup and provide what the distribution expects, i.e. some need an exclusive partition, some will be happy with just a directory on a shared partition. I don't say it not possible to install multiple OS's to 1 partition in a non default way, but it is begging for troubles and in my opinion not practical for a Linux newcomer. A possible workaround I mention at the bottom of my post ("Wubi-like" installs).

Q: * However, most of these systems just have a kernel in their directories called "linux" (not stating the version). I can search out which kernel these all use, but what's the best place to get the kernels themselves to copy to /boot/kernel?

A: I think the kernels should go exactly there where the distributions usually have them. There is no need to store them in a separate /boot/kernel folder, and I also would not recommend to try to share them between distributions. Storage space is minimal for a kernel (like 2-3 MB). There are really a lot of versions and sub-versions and sometimes there are even specific patches applied to kernels of distributions. To plugin in a different/untested kernel is an unneeded experiment.

Q: * After I get the kernels, I imagine the rest is mostly copying the device to /boot/img/ and creating the proper entry in menu.lst, correct? I can do that on a system by system basis once I can get the kernels to refer to.

A: As mentioned before, better create separate partitions for those distributions which need them and mix in the not so greedy distributions in their own folders. Treat kernel, initrd and rest of the distro as a unit.

One last idea. If you don't want to use different partitions you could try something like "WUBI" installs for the distros demanding a full install to its own partition. This means that you create large files with its own ext2/ext3 filesystems on the USB, then mount them as "drives" and install the OS into it. (I call it WUBI, because this is the best known application).

The following should be a Grub4dos menu.lst entry to boot a "Wubi install".

# Add the ntfs module - just needed for Installation on a Windows Partition
insmod ntfs
# Set root (normally would be sda1, or hd0,1 Change as necessary
set root=(hd0,1)
loopback loop0 /ubuntu/disks/root.disk
set root=(loop0)
linux /boot/vmlinuz root=/dev/sda1 loop=/ubuntu/disks/root.disk ro
initrd /boot/initrd/initrd.img
boot

From here.

You see, there are 2 "set root" commands, the second after "root.disk" which contains the Linux, is mounted as loop0.

I hope I could give some ideas, although it is no complete walk-through.

Related Question