Creating Bootable USB Image with GRUB

When compiling custom Kernel or initrd, its easier to create a bootable ISO image using mkisofs command.
But its a bit tricky to create a similar disk image for USB which can be burnt into any USB drive later or can shared.
Below is 'a way' to create a bootable USB disk image which uses GRUB bootloader.

(I have used CentOS 5 as root user for creating the image.)

Please refer to unix man pages for specific commands. (e.g. man mkisofs)

Step 1: Creating the image
Using 'dd' command first create a image file with null bytes.

 dd if=/dev/zero of=/tmp/disk.img bs=1024 count=250000

bs is blocksize and count is number of blocks. This will create a image file of size 245MB. Modify the count according to the need.

Step 2: Next we need a loopback device  which would be attached to the disk image so that other applications can use the image file as block device.   

losetup -f 

gives the first free loopback device that can be used. (say /dev/loop0 is free)   

losetup /dev/loop0 /tmp/disk.img

Step 3: Create a partition in the image using the loopback device. fdisk can be used to do that.

fdisk /dev/loop0

Provide proper options for fdisk.
(I gave n->p->1->Enter->Enter->t->c->w to create a FAT32 partition in the image)

Step 4: Next we need another loopback device for the partition we have just created to make the partition available for other applications as device. Now the loopback device /dev/loop0 is similar to /dev/sda. What we need a loopback device attached to the partition, for example a device like /dev/sda1.  

fdisk -ul /dev/loop0

will show the partition and block size. losetup takes offsets as the number of bytes to skip at the beginning of the file. The output from fdisk -ul /dev/loop0 shows that the first partition starts at block 63, and each blocks are of 512 bytes. So partition 1 starts at byte 32,256.

losetup -o 32256 /dev/loop1 /dev/loop0

This command will create another loopback device and attach to the parition created above.

Step 5: Now we need to format and mount the partition attached to the device /dev/loop1

mkfs.vfat /dev/loop1

This command formats the partition with file system as FAT.
(here a message may show up as
"Loop device does not match a floppy size, using default hd params"
but which seems fine as the image worked.)

Next create a temporary directory and mount the partition to it

mkdir /mnt/tmp
mount /dev/loop2 /mnt/tmp

Step 6: Copy the Kernel and Initrd files to the mount directory.

Step 7: Copy GRUB related stuffs.

mkdir -p /mnt/tmp/boot/grub
cp /boot/grub/stage1 /boot/grub/stage2 /boot/grub/fat_stage1_5 /mnt/tmp/boot/grub

Then create a grub.conf file in the grub directory. A default grub.conf file seems likedefault=0

title My USB Linux
root (hd0,0)
kernel /mykernel rw root=/dev/ram0 init=/init ramdisk_size=524288 ramdisk_blocksize=1024
initrd /initrd.img

Provide proper kernel and initrd names.

Step 8: Install GRUB. The following command will take to the grub console

grub --device-map=/dev/null

And the following grub commands needs to be executed.

device (hd0) /tmp/disk.img
root (hd0,0)
setup (hd0)

Step 9: Cleaning the mess.

umount /mnt/tmp

Deleting the loopback devices

losetup -d /dev/loop1
losetup -d /dev/loop0

And thats it. A bootable disk image is ready. Now it can burnt to any USB using any software like 'Image Writer'




1 of 17