There's always time to play

Wednesday, January 7, 2009

Creating a multiboot USB-stick using syslinux

Since I have an eeepc-701, I need a way to boot it from external media so I can mess with it. I have a Corsair Flash Survivor (16GB), so I'm going to use that for rescue-goodness. I'll give step by step instructions on how to create a similar boot disk. In these instructions I'll assume that /dev/sdc is the usb drive, /dev/sdc1 is the partition we're using for the filesystem. Further mine will be mounted at /media/Corsair and I'll also assume you can find the appropiate packages if you haven't gotten them yet (dosfstools and syslinux in gentoo). Last but not least most of these commands will need root permissions, so prepend them with sudo if that's your thing, or become root and do it all as root.

Format the usb drive as fat 32
Of course there are other options than fat 32 to create a bootable usb drive, but syslinux needs a FAT filesystem to work.
# mkdosfs -F 32 -n Corsair /dev/sdc1

Mount the usb drive
Unplugging and replugging will work for me as I use Gnome with automount support, should probably work for most people using a larger desktop environment. If not:
# mkdir -p /media/Corsair
# mount /dev/sdc1 /media/Corsair

Create a syslinux directory
Syslinux needs somewhere to store its files, I prefer doing that in a directory so I don't get a cluttered view every time I look at the files on my usb drive.
$ mkdir /media/Corsair/syslinux

Unmount and install syslinux
Unmount in whatever way suits you, just don't unplug yet. The -d option tells syslinux to use our directory 'syslinux' to store its files, just make sure the directory is there before running syslinux.
# umount /media/Corsair
# syslinux -d syslinux /dev/sdc1

Mount again
Remount the device to put more on it than just syslinux.
# mount /dev/sdc1 /media/Corsair

There's only two things left to do now:
1. Move images to the usb drive
2. Create the syslinux.cfg file

Move images to the usb drive
I create two directories to start with: gentoo and gparted. Inside the gentoo directory I put the kernel, initrd and squashfs from the minimal install cd and renamed them to include the release number in the files. At first I named my kernel just 'kernel-2008.0', but that seems to confuse syslinux so I renamed it to kernel-2008.0.img in the end. Better extensions suggestions for the kernel are welcome. I also copied all the .msg files from the gentoo cd to the syslinux directory I created on the root of the filesystem, so I can press F1-F6 and see irrelevant gentoo messages, however, changing these is easy and will be done when I have more time. It also seems gentoo needs a file called 'livecd' on the root, else it won't find the media as the fs media. It's cluttering the drive, but removing the file will just cause gentoo not to find a valid root fs. Last but not least I compiled a kernel that has support for most of the hardware in my eeepc 701/4G surf, and named that 'kernel-eee' straight on the root of the USB drive. I needed at least 2.6.28 so I could have support for the onboard network card, whatever way I'm installing it I'm gonna want network support. The kernel is monolithic (no modules and no module loading support) and works fine with the gentoo 2008.0 squashfs.

Inside the gparted directory I again put the kernel, initrd and squashfs files. I just took them from the livecd, left names as they were.

Create the syslinux.cfg file
I took most of this file straight out of the isolinux.cfg that came on the gentoo cd and customized where necessary.
default gentoo
timeout 150
prompt 1
display boot.msg
F1 kernels.msg
F2 F2.msg
F3 F3.msg
F4 F4.msg
F5 F5.msg
F6 F6.msg
F7 F7.msg

label eee
kernel /kernel-eee
append root=/dev/ram0 init=/linuxrc dokeymap looptype=squashfs loop=/gentoo/minimal-2008.0.squashfs cdroot initrd=/gentoo/initrd-2008.0.igz

label gentoo
kernel /gentoo/kernel-2008.0.img
append root=/dev/ram0 init=/linuxrc dokeymap looptype=squashfs loop=/gentoo/minimal-2008.0.squashfs cdroot initrd=/gentoo/initrd-2008.0.igz vga=791

label gentoo-nofb
kernel /gentoo/kernel-2008.0.img
append root=/dev/ram0 init=/linuxrc dokeymap looptype=squashfs loop=/gentoo/minimal-2008.0.squashfs cdroot initrd=/gentoo/initrd-2008.0.igz

label gparted
kernel /gparted/vmlinuz
append initrd=/gparted/initrd1.img boot=live union=aufs noswap vga=791 ip=frommedia nolocales live-media-path=gparted

label memtest86
kernel memtest86

Syslinux uses relative paths by default, so if you use no '/' syslinux will look for the files inside the dir syslinux is. The solution is simple, use absolute paths for the kernel and initrd and it's all OK. Most important change made to this file is the append lines. For gentoo, the loop parameter needs to point to the squashs image, so I changed that to /gentoo/minimal-2008.0.squashfs (name of the image in my case). I added a line for my eeepc kernel, which just boots into a gentoo minimal cd.

Next was gparted. Gparted supports a 'live-media-path=' parameter, this needs to be used when the gparted squashfs image is not directly in the root of the filesystem on the usb drive. Other than that gparted just looks for any file with name *.{squashfs,ext2,ext3,jffs2} so the name doesn't really matter as long as the extension hasn't changed.

I also left the memtest line in place, added the memtest image to the root of the drive and my rescue-drive is mostly done.

It should also be possible to do the same thing using grub, except for the F1-F6 messages and the default message (or can grub do that too?). I'm definately gonna add grub to it, probably replacing syslinux with grub. Using grub might also allow for use of other filesystems on the drive, which might end up being a big plus too. Come back again to read about that, once I've tried it myself.


Graham said...

promotional usb sticks
are a fabtastic way of getting some advertisment as well as giving a useful and thoughtful executive gift.

moobot said...

This is useful as I always have promotional usb sticks lying around. got quite a few boot-able usb drives, but I'll see how this multiboot solution works out.


kroweer said...

Thanks for this, it has helped me.

One thing, though, you are (I believe) missing a vital step: installing the MBR.

After installing syslinux, you need to run:
dd conv=notrunc bs=440 count=1 if=/usr/lib/syslinux/mbr.bin of=/dev/sdX