Dual Boot openSUSE USB Stick Installer
In the latest round of upgrades and new installs of openSUSE around here I decided to take a different approach and use the network install and install from a USB stick rather than a DVD. While I was at it I decided that I'd try to make a dual boot installer that would allow me to install either the 32-bit or 64-bit version of the latest openSUSE (version 11.3) from the same USB stick.
First we need to download the openSUSE network installer images:
$ mkdir opensuse $ cd opensuse $ wget http://download.opensuse.org/distribution/11.3/iso/openSUSE-11.3-NET-i586.iso $ wget http://download.opensuse.org/distribution/11.3/iso/openSUSE-11.3-NET-x86_64.iso
Both of the openSUSE installers above are already bootable, but the idea here is to be able to run either one, so we want to boot the USB stick independent of either installer and be shown a menu that allows us to select the installer to run. To do this we'll use syslinux, which you'll probably need to install. Assuming you're using openSUSE to build the installer, install syslinux with the following command:
$ zypper in syslinux
Plug in your USB stick if you haven't already done so and find out what its device file is, you can do this by looking at the messages at the end of /var/log/messages or by mounting the stick and typing the mount command to view what's mounted and where. The device file should have the form /dev/sdX, where the X will be different depending on how many drives your system has. Once you know the device file you should unmount the drive if it's mounted.
The first step is to create a number of partitions on the drive. I use fdisk for this but any partitioning tool should work. Create the following partitions:
- Partion 1: Size: 20MB, Type: FAT16 (type code: 4)
- Partion 2: Size: 200MB, Type: FAT32 (type code: c)
- Partion 3: Size: 200MB, Type: FAT32 (type code: c)
The first partition is used to hold our menu for selecting the installer to boot. The 2nd and 3rd partions are used to hold the individual openSUSE installers.
Now format the partitions:
$ mkfs.msdos /dev/sdX1 $ mkfs.vfat /dev/sdX2 $ mkfs.vfat /dev/sdX3
Now we need to mount each of the openSUSE installer images and create bootable disks using the mkbootdisk script that's included with the installer.
First the 64-bit installer:
$ mount openSUSE-11.3-NET-x86_64.iso /mnt -o loop $ /mnt/boot/x86_64/mkbootdisk --64 --partition /dev/sdX2 /mnt $ umount /mnt
Then the 32-bit installer:
$ mount openSUSE-11.3-NET-i586.iso /mnt -o loop $ /mnt/boot/i386/mkbootdisk --32 --partition /dev/sdX3 /mnt $ umount /mnt
The mkbootdisk command expects a --32 or --64 option to specify the bitness of things, the --partition option to tell where the bootable image is going to be created, and the source directory for the files that are to be copied to the bootable image (in our case /mnt).
Now that we've got the openSUSE installers on the USB stick we install our menu by installing syslinux on the first partition. Then we have to mount the partition and copy the syslinux menu program, chain loader program, and our configuration files to it (see below and the attachments).
$ syslinux /dev/sdX1 $ mount /dev/sdX1 /mnt $ cp /usr/share/syslinux/chain.c32 /mnt $ cp /usr/share/syslinux/menu.c32 /mnt $ cp syslinux.cfg /mnt $ cp menu.cfg /mnt
Now use fdisk or another partitioning tool to make sure that only the first partition is active and bootable.
When syslinux boots a partition it looks for a config file to tell it what to do, this is the syslinux.cfg we copied above. Our syslinux.cfg contains:
default opensuse prompt 0 label opensuse com32 menu.c32 append /menu.cfg
The above tells syslinux that the default (and only) boot option is "opensuse" and that we don't want syslinux to display its boot: prompt. The opensuse option boots the "com32" program "menu.c32" which we copied to the USB stick above. So here, rather than booting Linux, we're booting a helper program that comes with syslinux. This helper program, as you've probably already guessed since it's named menu, displays a menu. The append /menu.cfg option here adds the name of the menu configuration file to the end of the command line that executes the menu program. The menu configuration file contains our menu:
default harddisk prompt 1 timeout 600 MENU TITLE openSUSE Installers label harddisk MENU DEFAULT MENU LABEL Boot from Hard Disk localboot 0x80 label start64 MENU LABEL Start 64 bit openSUSE installer com32 chain.c32 append boot 2 label start32 MENU LABEL Start 32 bit openSUSE installer com32 chain.c32 append boot 3
Here we can see our boot options, one to boot from the harddisk, which is the default and happens after the timeout of 60.0 seonds. The other options are to boot the 32-bit openSUSE installer and to boot the 64-bit openSUSE installer.
When booting one of the openSUSE installers the boot is done by executing another syslinux helper program: chain.c32 (which we also copied to the USB stick above). This helper program boots another boot loader by loading the MBR of another disk or partition. The append options to each of the chain loaded installers specifies what partition to boot use: append boot 2 boots the 64-bit installer on partition 2 and append boot 3 does the 32-bit installer on partition 3.
At this point your new dual boot openSUSE installer should be ready to run, except for one possible caveat: if the MBR on your USB stick isn't valid you'll need to install a new MBR. Test it, if it doesn't boot, then try copying a new MBR to the USB stick with the following command:
$ dd if=usr/share/syslinux/mbr.bin of=/dev/sdX bs=440 count=1
If all goes well you should see the following when you boot the USB stick:
If you have a big enough USB stick you could also create full installers by using the DVD installers instead of the NET installers.
Note that most of the above commands will need to be run as root, so be careful. Also note that if you are not using openSUSE to create the installers the path to the syslinux files may be different.
p.s. The openSUSE NET installers worked without issue.
Mitch Frazier is an Associate Editor for Linux Journal.