Brain Dump

A place to store my random thoughts and anything else I might find useful.

Archive for February, 2011

How To: Create Bootable g4l USB Flash Drive

Posted by mzanfardino on February 18, 2011

This ‘How To’ covers in detail how to create a bootable USB flash drive with the imaging software g4l installed. g4l (or ghost4linux) is a free and open source hard disk and partition imaging/cloning tool. The purpose is to eliminate the need for a CD in cases where a CD drive may not be available.

This article presumes one is running Linux (in my case Ubuntu 10.04 though in principal this should work for pretty much any Linux distro running a 2.6 kernel). I will describe the process for formatting the USB flash drive, mounting an ISO file to the local file system in order to copy files to the USB drive, and installing a bootloader and making the USB drive bootable.

While searching the web for similar solutions, I came across a few other blogs[1][2] that describe the procedure, only to discover that they lacked the critical component for how to make the drive bootable. Therefore, I’m going to make my own attempt to cover this topic in a more structured, comprehensive fashion.

Basic Outline

1. Prerequisites
2. Create a FAT partition on target USB drive
3. Copy g4l files to USB drive
4. Configure bootloader
5. Create boot image
6. Write MBR to USB drive
7. References

Prerequisites

There are a few software requirements that must be met before proceeding. Firstly, be sure to have a copy of the latest version of the g4l ISO file (you can download version 0.36 here.

Secondly, it will be necessary to have a bootloader available. In this article, I will be using syslinux. syslinux is a lightweight bootloader for MS-DOS FAT filesystems and will be used to generate the bootloader image. You can download the latest version here. I understand that GRUB or possibly LILO could be used, but for this article I will stick to syslinux

Lastly, be sure to have parted installed. parted is a command line tool for manipulating partition tables. This is useful for creating space for new operating systems, re-organizing disk usage, copying data on hard disks and disk imaging. This may already be installed with your distro, but if not, be sure to install it either from the package repository or from source.

Once the required software has been downloaded and/or installed, begin by opening a terminal window and mounting the g4l ISO to a local mount point. In the following example the mount point is the directory g4l created in the users home directory. NOTE: unless your system is configured to permit your user account to mount filesystems it will be necessary to have root privilege to mount the ISO. In the case of Ubuntu I use sudo, however it may be necessary to su root depending on your distro (your mileage may vary!)

$ sudo mount -o loop ~/downloads/iso/utilities/g4l-v0.36.iso ~/g4l
Next, expand the syslinux tar file. In the following example I expand the file into my home directory:

$ tar xjvf ~/downloads/iso/utilities/syslinux-4.03.tar.bz2
syslinux-4.03/
syslinux-4.03/version.gen
syslinux-4.03/MCONFIG.build
. . .
syslinux-4.03/linux/syslinux
syslinux-4.03/linux/Makefile
syslinux-4.03/version.mk

We are now ready to proceed with the real work!

Create a FAT partition on target USB drive

To being, mount the USB drive and observe the output from dmesg to determine what device identifier is assigned. Depending on your distro and if the drive has already been formatted it might auto-mount. If so, be sure to unmount the device before you proceed.

$ dmesg|tail
[ 2806.671425] sd 22:0:0:0: [sdf] Write Protect is off
[ 2806.671430] sd 22:0:0:0: [sdf] Mode Sense: 65 44 09 30
[ 2806.671433] sd 22:0:0:0: [sdf] Assuming drive cache: write through
[ 2806.675283] sd 22:0:0:0: [sdf] 3911616 512-byte hardware sectors: (2.00 GB/1.86 GiB)
[ 2806.675779] sd 22:0:0:0: [sdf] Write Protect is off
[ 2806.675782] sd 22:0:0:0: [sdf] Mode Sense: 65 44 09 30
[ 2806.675783] sd 22:0:0:0: [sdf] Assuming drive cache: write through
[ 2806.675787] sdf: sdf1
[ 2806.677432] sd 22:0:0:0: [sdf] Attached SCSI removable disk
[ 2806.677809] sd 22:0:0:0: Attached scsi generic sg6 type 0

The preceding output reflects the device /dev/sdf is assigned to the newly mounted USB stick. For the rest of this example it will be assumed that the device is /dev/sdf, however this may not be the case with your attempt, so be sure to tail dmesg shortly after installing the USB stick in order to determine the correct device assignment.

Now create a DOS partition and format it. Note that the first step is to delete any existing partitions on the device. This step is only necessary if the device has already been formatted (often a new USB stick will already have been formatted with FAT). Perform the following steps (again note the use of sudo – use whatever method is required by your distro in order to perform these steps with root privilege):

  1. Execute fdisk with root privilege:

  2. $ sudo fdisk /dev/sdf
     
    The number of cylinders for this disk is set to 2936.
    There is nothing wrong with that, but this is larger than 1024,
    and could in certain setups cause problems with:
    1) software that runs at boot time (e.g., old versions of LILO)
    2) booting and partitioning software from other OSs
    (e.g., DOS FDISK, OS/2 FDISK)
     
    Command (m for help):

  3. Print the current partition table:

  4. Command (m for help): p
     
    Disk /dev/sdf: 2002 MB, 2002747392 bytes
    37 heads, 36 sectors/track, 2936 cylinders
    Units = cylinders of 1332 * 512 = 681984 bytes
    Disk identifier: 0xeb1326d4
     
    Device Boot Start End Blocks Id System
    /dev/sdf1 1 2937 1955790 6 FAT16
     
    Command (m for help):

  5. Delete any existing partitions:

  6. Command (m for help): d
    Selected partition 1
     
    Command (m for help):

  7. Create the new primary partition (this example partitions the entire available space):

  8. Command (m for help): n
    Command action
    e extended
    p primary partition (1-4)
    p
    Partition number (1-4): 1
    First cylinder (1-2936, default 1):
    Using default value 1
    Last cylinder, +cylinders or +size{K,M,G} (1-2936, default 2936):
    Using default value 2936
     
    Command (m for help):

  9. Set the partition type to W95 FAT32 (this will support partition sizes greater than 2GB):

  10. Command (m for help): t
    Selected partition 1
    Hex code (type L to list codes): b
    Changed system type of partition 1 to b (W95 FAT32)
     
    Command (m for help):

  11. Set the boot-bit for the partition (this step may be unnecessary as we do this again toward the end using parted):

  12. Command (m for help): a
    Partition number (1-4): 1
     
    Command (m for help):

  13. Verify that the newly created partition is configured correctly before writing to the partition table:

  14. Command (m for help): p
     
    Disk /dev/sdf: 2002 MB, 2002747392 bytes
    37 heads, 36 sectors/track, 2936 cylinders
    Units = cylinders of 1332 * 512 = 681984 bytes
    Disk identifier: 0xeb1326d4
     
    Device Boot Start End Blocks Id System
    /dev/sdf1 * 1 2936 1955358 b W95 FAT32
     
    Command (m for help):

  15. Write the changes to the partition table:

  16. Command (m for help): w
    The partition table has been altered!
     
    Calling ioctl() to re-read partition table.
     
    WARNING: If you have created or modified any DOS 6.x
    partitions, please see the fdisk manual page for additional
    information.
    Syncing disks.

    The USB drive is ready to be formatted as VFAT. It may be necessary to remove and remount the USB drive prior to formatting. It may also be necessary to unmount the newly created partitions that might mount automatically as a result of the kernel caching any previously mounted partitions. In the following example we label the partition g4l-v0.36_0


    $ sudo mkfs.vfat -n g4l-v0.36_0 /dev/sdf1
    mkfs.vfat 3.0.1 (23 Nov 2008)

It will be necessary to remove and remount the USB stick (again). Depending on your distro, the OS ought to automagically mount the newly formatted USB stick. In the above example we labelled the partition g4l-v0.36_0 which will auto-mount as /media/g4l-v0.36_0.

Copy g4l files to USB drive

Assuming that the latest g4l ISO has been mounted to as g4l in the home directory as instructed above, it is a simple matter to copy all the files to the newly created partition:


$ cp -v ~/g4l/* /media/g4l-v0.36_0/
`/home/mark/g4l/bicode.o3' -> `/media/g4l-v0.36_0/bicode.o3'
`/home/mark/g4l/blank6.cpp' -> `/media/g4l-v0.36_0/blank6.cpp'
`/home/mark/g4l/blank6.exe' -> `/media/g4l-v0.36_0/blank6.exe'
. . .
`/home/mark/g4l/syslinux.cfg' -> `/media/g4l-v0.36_0/syslinux.cfg'
`/home/mark/g4l/test.png' -> `/media/g4l-v0.36_0/test.png'
`/home/mark/g4l/vesamenu.c32' -> `/media/g4l-v0.36_0/vesamenu.c32'

At this point, if you’ve looked at the blog posts referenced in the beginning of this article you will note that we are simply dumping the content of g4l into the root directory of the USB drive. This is for simplicity sake. However, if one wanted to, one could copy the contents of g4l into a subdirectory. However, if this step is taken, then in the following step it will be necessary to edit syslinux.cfg. Notes for what to edit in syslinux.cfg follow in the next section.

Configure bootloader

Once the files have been copied to the USB drive it is necessary to replace the default syslinux.cfg file with the provided isolinux.cfg file as such:

$ sudo cp /media/g4l-v0.36_0/isolinux.cfg /media/g4l-v0.36_0/syslinux.cfg

NOTE:This is the file that has to be modified if g4l was not copied to the root of the USB drive. The following is a snippet of the file (I have edited out much of the detail for sake of brevity):

DEFAULT vesamenu.c32
. . .
LABEL bz32.28
MENU LABEL ^A: bz32.28 386 build 2.6.32.28 01-07-2011
KERNEL bz32.28
APPEND initrd=ramdisk.lzma ramdisk_size=65536 root=/dev/ram0
. . .
LABEL hdt
MENU LABEL ^Z: Hardware Detection Tool 0.36
KERNEL hdt.c32
APPEND modules_pcimap=modules.pcimap pciids=pci.ids memtest=memtest
 
TIMEOUT 600
ONTIMEOUT bz37 initrd=ramdisk.lzma ramdisk_size=65536 root=/dev/ram0

All references to KERNEL, APPEND, DEFAULT (should only be one) and ONTIMEOUT must be modified to include the path to the appropriate files. Also, any directive that makes reference to a file, such as MENU BACKGROUND. The following is the same code example where the g4l files were copied to a directory boot:

DEFAULT boot/vesamenu.c32
. . .
LABEL bz32.28
MENU LABEL ^A: bz32.28 386 build 2.6.32.28 01-07-2011
KERNEL boot/bz32.28
APPEND initrd=boot/ramdisk.lzma ramdisk_size=65536 root=/dev/ram0
. . .
LABEL hdt
MENU LABEL ^Z: Hardware Detection Tool 0.36
KERNEL boot/hdt.c32
APPEND modules_pcimap=boot/modules.pcimap pciids=boot/pci.ids memtest=memtest
 
TIMEOUT 600
ONTIMEOUT bz37 initrd=boot/ramdisk.lzma ramdisk_size=65536 root=/dev/ram0

Create boot image

Once the g4l files have been copied to the USB drive and syslinux.cfg has been modified and moved to the root of the drive, we can then use syslinux to create a bootloader image and copy it to the drive, as follows:

  1. First, unmount the USB stick:

  2. $ sudo umount /media/g4l-v0.36_0/

  3. Next, generate the bootloader image and copy it to the USB drive. The process for creating the image will copy the image to the USB drive.

  4. $ sudo ~/syslinux-4.03/linux/syslinux /dev/sdf1
    /home/mark/syslinux-4.03/linux/syslinux: please specify --install or --update for the future

This is the point at which the other blogs end, leaving one to assume that at this point you can boot from the USB drive. This is incorrect! We still have to copy the MBR (master boot record) to the boot sector of the drive before the bootloader image can be loaded.

Write MBR to USB drive

After following the steps outlined above I was still confounded to discover that my USB drive would not boot. I continued to get an error message telling that it was an invalid boot device. I did some research and found the answer from the Syslinux Wiki[3]. The key is to copy the mbr.bin file provided with syslinux to the boot sector of the USB drive. This is accomplished as follows:

$ sudo dd conv=notrunc bs=440 count=1 if=~/syslinux-4.03/mbr/mbr.bin of=/dev/sdf
1+0 records in
1+0 records out
440 bytes (440 B) copied, 0.0255058 s, 17.3 kB/s

At this point the USB stick should be ready for use, however to ensure that the partition is indeed flagged as bootable, use parted to set the boot flag. (NOTE: you could set the partition bootable when defining the partition in fdisk, but this is the recommended method from Syslinux Wiki):

$ sudo parted /dev/sdf set 1 boot on
Information: You may need to update /etc/fstab.

That should do it. I use these steps to create multiple USB drives for use at work replicating source “GOLD” images onto new hardware which does not have a CD drive. It’s fast and easy and very reliable. If I have omitted something, or if someone has any suggestions, feel free to leave a comment.</p

References:

  1. IT Resource Center forums – bootable USB stick with G4L
  2. Radified Community Forum: Bootable USB stick with G4L
  3. Syslinux Wiki – How to Create a Bootable USB: For Linux

Posted in linux | 3 Comments »