2004-01-27
| Revision History | |||
|---|---|---|---|
| Revision v0.0 | 2004-01-27 | Jing S. Tang | Initial draft |
| Revision v0.1 | 2004-01-28 | Jing S. Tang | Revised based on comments from Charles Curley |
This document explains how to create a Linux bootable USB disk step by step. The target USB disk will contain the GRUB boot loader, the boot file system and the root file system. In another word, it will contain the whole Linux operating system. In case your BIOS does not support booting from USB, the USB disk created using this HOW-TO can still work together with the boot floppy. In that case the only difference is that the GRUB boot loader resides on the floppy rather than on the USB.
This HOWTO describes how to make a bootable Linux USB disk from the ground up.
I'd like to thank the following people who helped me improve this HOWTO:
Charles Curley
Feedback is most certainly welcome for this document. Send your additions, comments and criticisms to the following email address : <tangshanjing@yahoo.com.cn>.
This document demonstrates how to create a bootable USB disk. Firstly you will learn how to create a bootable floppy disk to boot up your PC in section 3. Section 4 shows you how to repartition your USB disk to create a bootable Linux partition as the boot file system, and a Linux root file system on the USB. You will need to patch your kernel in order to successfully mount the root file system on the USB. This is in section 5. Section 6 tells you how to prepare your root file system so that it will boot to a bash shell. And section 7 shows how to boot your PC both by using the GRUB config file and manually. You should be able to boot your machine from the USB disk by carefully following the steps showing in this doc.
The checklist of things you will need are listed here:
3.1 Building GRUB
Download GRUB package from here: http://www.gnu.org/software/grub/grub-download.html
Unpack the GRUB to /home/mylogin/grub<ver>, where <ver> is the version number of the GRUB.
cd /home/mylogin/grub<ver>
./configure
make
Read /home/mylogin/grub<ver>/INSTALL for details.
3.2 Raw write the stage1, stage2 to a floppy disk
3.2.1 In DOS OS environment
The wrtdsk DOS utility can be downloaded here: http://www.cs.vu.nl/pub/minix/dosutil/
The rawrite dos utility comes with many Linux disty CD-ROMS including Red Hat and Fedora could also fulfill this task.
C:\a>copy /b stage1+stage2 stageall
C:\a>wrtdsk a: stageall
CMOS floppy drive data:
Drive A: 1440K
Drive B: none
Please insert floppy in drive A: for density check and press any key.
Guessed floppy capacity is 1440K.
Copying 200 sectors from STAGEALL to A:
Please insert disk #1 and press any key.
CYL 5 SID 1 SCT 2
Done.
3.2.2 In Linux OS environment
dd if=stage1 of=/dev/fd0 count=1 bs=512
dd if=stage2 of=/dev/fd0 seek=1 bs=512
This doc uses sfdisk to do the partitioning for the USB disks. Here is a brief introduction on sfdisk. The -l option of sfdisk lists the partitions info on the target device:
[root@localhost alant]# /sbin/sfdisk -l /dev/sda
Disk /dev/sda: 1000 cylinders, 2 heads, 32 sectors/track
Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from 0
Device Boot Start End #cyls #blocks Id System
/dev/sda1 * 0+ 399 400- 12799+ 83 Linux
/dev/sda2 401 700 300 9600 83 Linux
/dev/sda3 701 999 299 9568 83 Linux
/dev/sda4 400 400 1 32 83 LinuxThere're 4 partitions in the above example, /dev/sda1 is an active (denoted by * under the Boot column) Linux partition (with the Id hex 83) starting from cylinder 0 to cylinder 399, /dev/sda2 is an inactive Linux partition starting from cylinder 401 to cylinder 700, /dev/sda3 is an inactive Linux partition starting from cylinder 701 to cylinder 999, and /dev/sda4 is an inactive Linux partition starting from cylinder 400 to cylinder 400.
The sfdisk with no options performs repartition for the target disk. It takes input from standard in with the following format: Start End Boot Id. Where Start is the start cylinder, End is the end cylinder, Boot denotes if the partition is bootable (* is bootable, default is not bootable), and Id is the partition type. For example the user should input "0 500 83 *" to create a bootable Linux partition starting from cylinder 0 to cylinder 500.
Details please see the man page for sfdisk: http://www.die.net/doc/linux/man/man8/sfdisk.8.html
4.1 Find out the correct scsi driver
This can be done by querying the size of each of the scsi device using the "sfdisk -l" command.
/sbin/sfdisk -l /dev/sda
/sbin/sfdisk -l /dev/sdb
... ...
The following example shows a USB disk of around 128MB in size (1003*130560 is about right).
[root@localhost root]# sfdisk -l /dev/sda Disk /dev/sda: 1003 cylinders, 5 heads, 51 sectors/track Units = cylinders of 130560 bytes, blocks of 1024 bytes, counting from 04.2 Creating two partitions for boot and root file systems
This section uses /dev/sda as an example. Depending on what other hardware and/or drivers you have
installed, Your USB device may show up as of some other SCSI device: /dev/sdb, /dev/sdc, etc.[root@localhost root]# sfdisk /dev/sda
0 500 83 * <--- User input to create a bootable partition for the boot file system.
501 500 83 <--- User input to create a partition for the root file system.
4.3 Making the boot, and root file systems
/sbin/mkfs -t ext2 /dev/sda1
/sbin/mkfs -t ext2 /dev/sda2
4.4 Installing the GRUB boot loader
This step installs the stage1, stage2 boot loader files to the boot file system.
mount -t ext2 /dev/sda1 /mnt/usb
cp stage1 /mnt/usb
cp stage2 /mnt/usb
4.5 Setting up the GRUB boot loader
Make sure there are no hard disks connected to the PC other than the USB disk. Caution: this is very important because if there are already hard disks connected to your PC, the following steps would write the boot loader to the first hard disk hence it will damage your operating system on the hard disk. To physically disconnect hard drives, perform a graceful shutdown ("shutdown -h now") first. Then insert the floppy disk created in section 3 into the drive, then power on to boot the PC.You should be able to get the grub> prompt.
Issue the command root(hd0,0) under the grub> prompt.
grub> root (hd0,0)
Then issue the setup command to set up the GRUB stage1, and stage2 boot loader. This will put the stage1 to the first sector of the sda1 partition, then embed the location of the stage2 to the stage1 so that the stage1 can locate the stage2 on boot loading.
grub> setup hd0
5.1 Compiling the kernel
This section uses kernel source version 2.4.23 as an example. You can select whatever version of kernel as long as it supports USB.
5.1.1 Configuring the kernel
Make sure the configuration for the kernel supports the USB and the serial console. A good way to find out which other components a given computer requires is to do an lsmod and build those modules into the kernel. But at least the USB should be built into the kernel.
5.1.2 Patching the kernel
Make sure the mount_root() function contains the patch for detecting the USB disk. There's a bug for the mount_root() originally. The mount_root() was called before the USB disk being detected and initialized completely hence the mount_root() would fail if the root partition is located in the USB disk. Following is the patch for the 2.4.23 kernel:
--- init/do_mounts.c 2003-11-28 13:26:21.000000000 -0500
+++ init/do_mounts.c.mount_root 2006-01-29 10:45:53.000000000 -0500
@@ -759,6 +759,19 @@
static void __init mount_root(void)
{
+ static DECLARE_WAIT_QUEUE_HEAD (jordi_queue);
+
+ printk ("\n\n\n---------------------------------\n");
+
+ printk (" WAITING FOR A WHILE (1000) \n");
+
+ printk (" TO DETECT THE USB DISK \n");
+
+ sleep_on_timeout (&jordi_queue, 2000);
+
+ printk ("---------------------------------\n\n\n");
+
+
#ifdef CONFIG_ROOT_NFS
if (MAJOR(ROOT_DEV) == NFS_MAJOR
&& MINOR(ROOT_DEV) == NFS_MINOR) {Check the file init/do_mounts.c to see if it already contains the above patch. If not, save the above patch to a patch file named kernel2.4.23.patch. Then at the root directory of the 2.4.23 kernel source perform the following command to apply the patch:
patch -p0 <kernel2.4.23.patch
Note: In some old kernel sources the __init mount_root() is in fs/super.c. You need to do a similar patch to the above one in that case.
Follow the README at the root directory of the kernel source to build the new kernel.
5.2 Installing the kernel to the boot file systemCopy the newly created kernel to the boot file system on the USB disk.
mount /dev/sda1 /mnt/usb
cp <kernel_image> /mnt/usb
umount /dev/sda1
mount /dev/sda2 /mnt/usb
mknod -m 622 /mnt/usb/dev/console c 5 1
mknod -m 622 /mnt/usb/dev/tty0 c 4 0
mkdir -p /mnt/usb/sbin
mkdir -p /mnt/usb/etc
mkdir -p /mnt/usb/bin
mkdir -p /mnt/usb/lib
cp /sbin/init /mnt/usb/sbin
cp /bin/bash /mnt/usb/bin
cp -r /lib /mnt/usb
Create a /mnt/usb/etc/inittab file for the root file system on USB.
This file looks like this (in pink):
# Start inittab
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Default runlevel.
# 1 - Single user mode
#
id:1:initdefault:
# System initialization.
si::sysinit:/bin/bash
umount /dev/sda2
7.1 Boot manually
Boot from the USB disk. Perform the following commands under the grub prompt:
grub> root(hd0,0)
grub> kernel <kernel_image> root=/dev/sda2
grub> boot
7.2 Creating a GRUB menu.lst
$ cat menu.lst
root (hd0,0)
kernel <kernel_image> root=/dev/sda2
boot
$ mount /dev/sda1 /mnt/usb
$ mkdir -p /mnt/usb/grub
$ cp menu.lst /mnt/usb/grub
The USB disk is now be able to boot the Linux.
The whole image on the USB disk can be back up using the following command:
dd if=/dev/sda of=<backup_image_file> bs=512
| About this document |