[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD

时间:2023-01-26 21:57:38


(Redirected from FedoraLiveCD/USBHowTo )
Jump to: navigation , search


This page explains how to create and use Live USB media . A Live USB system stored on flash memory, sometimes called a stick , lets you boot any USB-bootable computer into a Fedora operating system environment without writing to that computer's hard disk. The Live USB stick can feature an area to store changes to the system, called a persistent overlay . It can also have a separate area to store user account information and data such as documents and downloaded files, with optional encryption for security and peace of mind. Finally, with a non-destructive installation, pre-existing files and excess storage space on the stick are accessible from the system. Essentially, you can carry your computer with you in your pocket, booting it on nearly any system you find yourself using.

 

[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD
Quick start
The process for most people is simple. Almost all USB sticks are provided by hardware manufacturers ready to use with this process. If you have any documents on your USB stick, it's not a bad idea to back them up before you start.

Then reboot your system and use your computer's built-in function to choose the USB boot device -- usually this is a special key you hold down at boot time, such as F12 . Then enjoy!

If you are into technical details or want more information, please read on.
[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD
Using UNetbootin
For information about UNetbootin, see this note on the F12 issues page. UNetbootin since version 393 is able to create Fedora Live USB sticks. If you are using an older version, you can download an upgrade from the UNetbootin site .

 

Contents

[hide ]

 

 

[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD
Creating Live CD ISO image
A Live USB system is created from the same ISO image file that is used to create Live CD/DVD media. You can download ISO images for the official Fedora release from the Fedora download site . Consult How to create and use a Live CD for more information on creating your own customized ISO image file.
[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD
Command formats
Lines beginning with "$" indicate commands you should type (do not include the $; this represents the command line prompt); subsequent lines represent typical output. You will need to run some commands as root.

System Requirements

  • A working computer running Fedora or Windows. If you are using other Linux distributions, consider using dd or UNetbootin . UNetbootin is available in the Fedora repository as well
  • A USB flash drive , also known as a USB stick, thumb drive, pen drive, or jump drive, with 1 GB or more of storage space, on a vfat file system (standard for almost all off-the-shelf USB media)

Ability to boot from USB media

Though most modern ones can, not all computers can boot from USB media, due to different BIOS settings and system capabilities. If your computer cannot do so, this procedure will not be useful. If you are not sure and don't mind downloading and installing an image on your USB drive (possibly wiping it of data), the only risk is wasting some time.

If your USB stick is not in working order, this procedure may fail. Watch for error messages during the process.

Some flash drives may not be bootable by default, even if your hardware is capable of doing so. You may need to mark the partition bootable or you may just need to reformat the flash drive. See Errors and Solutions below for more information.

Check the size of your USB stick

Many USB sticks indicate the size on the packaging or the outside of the stick.

If you don't know the size of the stick, or want to check it for data, you should be able to auto-mount the USB stick by inserting it into a USB port. You can check the contents and size using the graphical file manager. In Linux, you can also use the command line:

$ df -h

Filesystem Size Used Avail Use% Mounted on

/dev/mapper/VolGroup00-LogVol00

143G 14G 122G 10% /

/dev/sda1 99M 12M 82M 13% /boot

tmpfs 1009M 0 1009M 0% /dev/shm

/dev/sdb1 3.9G 4.0K 3.9G 1% /media/usbdisk

USB drives are usually mounted in /media. In this case, the device is /dev/sdb1, has a 3.9GB capacity and is almost empty.

Take note of "/dev/sdb1" or equivalent; you will be specifying the device name if you use the command line method.

How to Partition

[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD
CAUTION
This will erase all data on the USB drive! Please read the instructions below carefully .

If the drive has not been partitioned properly (or if you are unsure), use fdisk to repartition it.

It is also possible to do a non-destructive installation of a LiveUSB image, if you have sufficient empty space. See How to install non-destructively below.

The fdisk command must be run as root. Include only the drive name in the command, not the partition number. Be sure to select the correct disk, or you may erase important data! Check the output of "df -h" if you are unsure. For example, if your partition will be /dev/sdb1, do:

$ /sbin/fdisk /dev/sdb



If you don't have fdisk installed, run yum install util-linux-ng as root.

The following session output from fdisk shows the responses to give to the prompts. The line starting Last cylinder ... refers to the size of the flash drive, so may be different than in the example.

Command (m for help): d



Selected partition 1



Command (m for help): n


Command action

e extended

p primary partition (1-4)

p


Partition number (1-4): 1


First cylinder (1-960, default 1):


Using default value 1

Last cylinder or +size or +sizeM or +sizeK (1-960, default 960):


Using default value 960



Command (m for help): t


Selected partition 1

Hex code (type L to list codes): 6


Changed system type of partition 1 to 6 (FAT16)



Command (m for help): a

(给分区添加启动标志)

Partition number (1-4): 1




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.

How to Format

[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD
CAUTION
This will erase all data on the USB drive! Please read the instructions below carefully .

If your USB media has sufficient free space on a vfat file system already, you do not need to perform this step.

To finish, the partition must be formatted with an actual file system using mkdosfs as the root user. Unmount the device before using mkdosfs . In the below example, /dev/USBPARTITIONNAME might be, for example, /dev/sdb1. Be sure to select the correct partition; formatting destroys all data on it!

$ umount /dev/USBPARTITIONNAME

$ /sbin/mkdosfs -F 32 -n usbdisk /dev/USBPARTITIONNAME



If you don't have mkdosfs installed, run "yum install dosfstools" as root.

How to install non-destructively

Skip the repartitioning and formatting step above, and simply continue with the below steps. Please keep in mind you should have at least 1GB free. It is highly recommended to make a backup copy of the data on the USB drive before proceeding in case something goes wrong.

From a Downloaded Image

Download an ISO

(If you are using liveusb-creator - the "Graphical" method below, with a "supported" Fedora release, you can skip this step. The program will download the ISO for you.)

You can use BitTorrent or your web browser to download a bootable image, or ISO, which you will install on your USB drive.

Quick links:

You are looking for a file with "Live" in the name, usually of the form "F<version>-<architecture>-Live.iso". For example, "F12-i686-Live.iso" is the Fedora 12 release for 32-bit Pentium Pro and compatible CPUs. "F13-Alpha-x86_64-Live.iso" is the alpha pre-release version of Fedora 13 for 64-bit Intel-compatible CPUs. Be sure to choose the correct file for your architecture. 32-bit releases will generally run on 64-bit hardware, but will not be optimized.

These instructions will also work for Custom Spins of Fedora Live ISO images, including those you make yourself with Revisor (a graphical tool), or LiveCD Creator (command-line tool used by Revisor). (Pungi is a command-line tool you can use to create installable ISOs, but not Live ISOs.)

If you use a LiveUSB with data persistence, you can use the "yum update" method described below to get the latest daily Rawhide RPMs (mostly for testers and not everyday use) except for the kernel . See Releases/Rawhide for more information about daily builds.

Live ISOs are not made daily for Branched, Alpha, Beta, and Final phases, only at the Alpha, Beta, and Final milestones.

Graphical Method - Windows or Fedora

Fedora LiveUSB sticks can be created in Windows and Linux using the liveusb-creator .

For Windows using the following steps:


If you are using Fedora, you can use Add/Remove Programs and search for liveusb-creator or on the command line:

$ su -c "yum install liveusb-creator"


To start, run liveusb-creator on the command line, or on the GNOME menu, go to "Applications -> System Tools -> liveusb-creator".

Command Line Method - Linux only

In the following examples, replace "/path/to/ISO" with e.g. F12-Live-i686.iso or the full path to the ISO you downloaded, e.g. /tmp/F12-Live-i686.iso.

Replace /dev/USBPARTITIONNAME with the appropriate partition name. For example, /dev/sdb1 in the example above ("Check the size of your USB drive"). Be careful to specify the correct device, or you may lose important data!

The livecd-iso-to-disk method also works with netinst.iso and boot.iso files, even though these are not Live images.

Using dd for a direct copy

Fedora 12 and above, you can simply use dd although the specialized tools have additional features like non destructive writing and data persistence

$ dd if=F12-Live-i686.iso of=/dev/sdX bs=8M





Note that you want the device name (e.g. /dev/sdx) not the partition name (e.g. /dev/sdx1).

注意:/dev/sdX代表整个U盘,而不是某个分区!!!

Check livecd-tools

Make sure the livecd-tools RPM is installed.

$ rpm -q livecd-tools

You will see the name of the RPM and a version number if it is installed, and no output if it is not installed.

If "livecd-tools" is not installed, install it using yum.

$ su -c "yum install livecd-tools"

Run livecd-iso-to-disk script

Make sure that the USB drive is not mounted before executing the following, and give the root password when prompted.

$ su -c "livecd-iso-to-disk /path/to/ISO /dev/USBPARTITIONNAME"

Password:

Copying live image to USB stick

Updating boot config file

Installing boot loader

USB stick set up as live image!

In case it is not possible to boot from a disk created with the method shown above, you can also tell livecd to format the medium itself. Note that this method causes livecd to format the disk and thus erase all the data on it :

$ su -c "livecd-iso-to-disk --format --reset-mbr /path/to/ISO /dev/USBPARTITIONNAME"

Data Persistence

Data persistence means that your files and settings will remain even after you reboot your live system. You can perform updates just like a regular installation to your hard disk except for kernel updates which are not supported. The primary use of this feature is booting a USB stick with your live image as well as the persistent changes.

Use liveusb-creator, a graphical utility to do this easily. Liveusb-creator is available in the Fedora repository and for Windows users as well.

If you prefer the command line, you can run the following command:

$ livecd-iso-to-disk --overlay-size-mb 512 /path/to/ISO /dev/USBPARTITIONNAME

where 512 is the desired size (in megabytes) of the overlay. The livecd-iso-to-disk shell script won't accept an overlay size value greater than 2047 for VFAT, but for ext[23] filesystems it is only limited by the available space. You can find the livecd-iso-to-disk shell script in the LiveOS directory at the top-level of the CD image. Note that you'll need to have space on your USB stick for the live image plus your overlay plus any other data you want on the stick.

[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD
Limited Lifetime of Persistent Overlay
One very important note about using the "primary" persistent overlay for system changes is that due to the way it's currently implemented (as a LVM copy-on-write snapshot), every single change to it (writes AND deletes) subtracts from its free space, so it will eventually be "used up" and your USB stick will no longer boot. Because of these limitations, it is advisable to use the system-level persistence sparingly, for configuration changes and important security updates only. For a truly persistent write-many (vs write-once) overlay, use the --home-size-mb option to create a home directory filesystem image for personal files. Unlike the primary system overlay image, the home.img can be re-used and loop mounted outside of the liveusb environment.

The persistent overlay status may be queried by issuing this command on the live system:

dmsetup status

The returned value may look like this:

live-osimg.min: 0 8388608 snapshot 2352/2352 24

live-rw: 0 8388608 snapshot 42296/204800 176

where the fraction after 'snapshot' for the logical volume is that of 512-byte sectors consumed in the overlay.

From a running Live CD/DVD

If you are already running a live CD or DVD and want to convert that into a bootable USB stick, run the following command:

$ livecd-iso-to-disk /dev/live /dev/USBPARTITIONNAME

How to Boot a Live USB Drive

  • Power off the computer.
  • Plug the USB drive into a USB port.
  • Remove all other portable media, such as CD, DVD, or floppy disks.
  • Power on the computer.
  • If the computer is configured to automatically boot off of the USB drive, you will see a screen that says "Automatic boot in 10 seconds..." with a countdown.
  • If the computer starts to boot off the hard drive, you'll need to manually configure it to boot off the USB drive.
    • Wait for a safe point to reboot safely.
    • As the machine starts to reboot, watch carefully for instructions on which key to press (usually a function key or Escape) to enter the boot device selection menu, or "BIOS setup". Press and hold that key. If you miss the window of opportunity (often only a few seconds) then reboot and try again.
    • Use the BIOS setup menu to put your USB drive first in the boot sequence. It might be listed as a hard drive rather than a removable drive. Each hardware manufacturer has a slightly different method for doing so. Use caution! Your computer could become unbootable or lose functionality if you change any other settings. Though these settings can be reverted, you'll need to remember what you changed in order to do so.
    • Save the changes, exit, and the computer should boot the Live USB drive.

 

How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD

Why would I want to make a USB device installer from the DVD instead of the LiveCD?

If you are installing to a netbook, or otherwise do not have an optical drive (or burner, or media), and you want the extra flexibility of using the regular DVD installer instead of the Live image, then this method will give a useful install medium. You are then free to customize package selection, choose which filesystem you prefer for your rootfs (ext3 OR ext4, btrfs, etc), and rescue mode is available.

Preparing the USB stick

The easiest setup method is to install and use unetbootin or Fedora's own livecd-iso-to-disk script from livecd-tools. Note that the liveusb-creator GUI, however, does not support putting the DVD installer on USB.

The manual setup method follows:

First, download the iso file Fedora-12-i386-DVD.iso from a Fedora mirror. Then loop mount the iso on a local mount point such as /mnt/tmp

# mount -o loop /path-to-iso/Fedora-12-i386-DVD.iso /mnt/tmp



Now plug in the USB stick and then copy the main iso file as well as the images directory from the /mnt/tmp/ directory to the root directory of the USB stick.

# cp /path-to-iso/Fedora-12-i386-DVD.iso /media/usbdisk/

# cp -r /mnt/tmp/images /media/usbdisk/



Next download the boot.iso file from a rawhide mirror from the development/i386/os/images/ directory on the mirror and store it on your computer's hard drive.

From your running 13 system (including an 13 livecd) make sure you have the livecd-tools package installed by doing:

yum install livecd-tools



Use the "mount" command to find the USB stick (e.g., /dev/sdb1) or look at /var/log/messages to find where the stick was mounted. Next umount the USB stick either from the desktop icon or using the umount command - but keep a note of where the USB stick is attached to the filesystem, e.g., /dev/sdb1

Now as root run:

注意:1、在images目录下有个boot.iso,不用额外下载。

            2、livecd-iso-disk是个shell脚本,其内容可参考附件。

# livecd-iso-to-disk path-to/boot.iso /dev/sdb1



If the stick is not bootable, then refer to the information below to make it bootable, otherwise this command will fail.

You should now have a bootable USB stick which will run an 13 install. When you boot the stick, select a hard drive install and select the drive as /dev/sdb1 (or your USB device drive) and the path should be /

The remainder of the install should be the same as for using a DVD in an optical drive, but when you select options make sure that you select your disk partitioning carefully if you are doing custom partitioning and also make sure that the bootloader is installed on the correct drive - by default it will be installed on the USB stick so you will need to change it to the master boot record on the hard drive.

Errors and Solutions

liveusb-creator problems

Partition isn't marked bootable!

If you get the following message, you need to mark the partition bootable.

$ livecd-iso-to-disk Fedora-<release>-Live-i686.iso /dev/sdb1

Partition isn't marked bootable!

You can mark the partition as bootable with

$ /sbin/parted /dev/sdb

(parted) toggle N boot

(parted) quit

Cleaning up to exit...

To mark the partition bootable,

$ parted /dev/sdb

GNU Parted 1.8.6

Using /dev/sdb

Welcome to GNU Parted! Type 'help' to view a list of commands.

(parted) print

Model: Imation Flash Drive (scsi)

Disk /dev/sdb: 1062MB

Sector size (logical/physical): 512B/512B

Partition Table: msdos



Number Start End Size Type File system Flags

1 32.3kB 1062MB 1062MB primary fat16



(parted) toggle 1 boot

(parted) print

Model: Imation Flash Drive (scsi)

Disk /dev/sdb: 1062MB

Sector size (logical/physical): 512B/512B

Partition Table: msdos



Number Start End Size Type File system Flags

1 32.3kB 1062MB 1062MB primary fat16 boot



(parted) quit

Information: Don't forget to update /etc/fstab, if necessary.

Partitions need a filesystem label!

If you get the following message, you need to label the partition.

$ livecd-iso-to-disk Fedora-<release>-Live-i686.iso /dev/sdb1

Need to have a filesystem label or UUID for your USB device

Label can be set with /sbin/dosfslabel

Cleaning up to exit...

To label the partition.

$ dosfslabel /dev/sdb1 usbdisk

Partition has different physical/logical endings!

If you get the following message, you may need to reformat the flash drive.

$ fdisk -l /dev/sdb



Disk /dev/sdb: 2029 MB, 2029518848 bytes

129 heads, 32 sectors/track, 960 cylinders

Units = cylinders of 4128 * 512 = 2113536 bytes



Device Boot Start End Blocks Id System

/dev/sdb1 * 1 961 1981936 6 FAT16

Partition 1 has different physical/logical endings:

phys=(967, 128, 32) logical=(960, 31, 32)

MBR appears to be blank!

If your test boot reports a corrupted boot sector, or you get the following message, you need to install MBR.

$ livecd-iso-to-disk Fedora-<release>-Live-i686.iso /dev/sdb1

MBR appears to be blank.

You can add an MBR to this device with

Cleaning up to exit...


To install MBR,

$ cat /usr/share/syslinux/mbr.bin > /dev/sdb

SYSLINUX Boot Error!

If you were using the script on previous Red Hat or Fedora Release and getting following error message,

SYSLINUX 3.xx ... EBIOS Load error - Boot error

You may need to upgrade your syslinux to 3.50 or higher from Peter Anvin's SYSLINUX .

Testing Live Image on USB

You can test your Live Image on USB using QEMU as shown in the screenshot below.

[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD
[LINUX LIVE USB]How to Make a bootable USB Drive to Install Fedora instead of using a physical DVD

For example, if your USB flash drive is on /dev/sdb1, you could type following command:

$ umount /dev/sdb1

$ qemu -hda /dev/sdb -m 256 -vga std



See also

Red Hat Magazine | I am Fedora, and so can you!

References

http://fedoraproject.org/wiki/FedoraLiveCD/USBHowTo#Command_Line_Method_-_Linux_only

 

附件:livecd-iso-to-disk脚本

#!/bin/bash
# Convert a live CD iso so that it's bootable off of a USB stick
# Copyright 2007  Red Hat, Inc.
# Jeremy Katz <katzj@redhat.com>
#
# overlay/persistence enhancements by Douglas McClendon <dmc@viros.org>
# GPT+MBR hybrid enhancements by Stewart Adam <s.adam@diffingo.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


export PATH=/sbin:/usr/sbin:$PATH

usage() {
    echo "$0 [--format] [--reset-mbr] [--noverify] [--overlay-size-mb <size>] [--home-size-mb <size>] [--unencrypted-home] [--skipcopy] <isopath> <usbstick device>"
    exit 1
}

cleanup() {
    sleep 2
    [ -d "$CDMNT" ] && umount $CDMNT && rmdir $CDMNT
    [ -d "$USBMNT" ] && umount $USBMNT && rmdir $USBMNT
}

exitclean() {
    echo "Cleaning up to exit..."
    cleanup
    exit 1
}

getdisk() {
    DEV=$1

    if [[ "$DEV" =~ "/dev/loop*" ]]; then
       device="$DEV"
       return
    fi

    p=$(udevadm info -q path -n $DEV)
    if [ -e /sys/$p/device ]; then
    device=$(basename /sys/$p)
    else
    device=$(basename $(readlink -f /sys/$p/../))
    fi
    if [ ! -e /sys/block/$device -o ! -e /dev/$device ]; then
    echo "Error finding block device of $DEV.  Aborting!"
    exitclean
    fi

    device="/dev/$device"
    # FIXME: weird dev names could mess this up I guess
    p=/dev/`basename $p`
    partnum=${p##$device}
}

resetMBR() {
    if [[ "$DEV" =~ "/dev/loop*" ]]; then
       return
    fi
    getdisk $1
    # if efi, we need to use the hybrid MBR
    if [ -n "$efi" ];then
      if [ -f /usr/lib/syslinux/gptmbr.bin ]; then
        gptmbr='/usr/lib/syslinux/gptmbr.bin'
      elif [ -f /usr/share/syslinux/gptmbr.bin ]; then
        gptmbr='/usr/share/syslinux/gptmbr.bin'
      else
        echo "Could not find gptmbr.bin (syslinux)"
        exitclean
      fi
      # our magic number is LBA-2, offset 16 - (512+512+16)/$bs
      dd if=$device bs=16 skip=65 count=1 | cat $gptmbr - > $device
    else
      if [ -f /usr/lib/syslinux/mbr.bin ]; then
        cat /usr/lib/syslinux/mbr.bin > $device
      elif [ -f /usr/share/syslinux/mbr.bin ]; then
        cat /usr/share/syslinux/mbr.bin > $device
      else
        echo "Could not find mbr.bin (syslinux)"
        exitclean
      fi
    fi
}

checkMBR() {
    if [[ "$DEV" =~ "/dev/loop*" ]]; then
       return 0
    fi
    getdisk $1

    bs=$(mktemp /tmp/bs.XXXXXX)
    dd if=$device of=$bs bs=512 count=1 2>/dev/null || exit 2
   
    mbrword=$(hexdump -n 2 $bs |head -n 1|awk {'print $2;'})
    rm -f $bs
    if [ "$mbrword" = "0000" ]; then
    echo "MBR appears to be blank."
    echo "Do you want to replace the MBR on this device?"
    echo "Press Enter to continue or ctrl-c to abort"
    read
    resetMBR $1
    fi

    return 0
}

checkPartActive() {
    dev=$1
    getdisk $dev
   
    # if we're installing to whole-disk and not a partition, then we
    # don't need to worry about being active
    if [ "$dev" = "$device" ]; then
    return
    fi
    if [[ "$dev" =~ "/dev/loop*" ]]; then
        return
    fi

    if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep $dev |awk {'print $2;'})" != "*" ]; then
    echo "Partition isn't marked bootable!"
    echo "You can mark the partition as bootable with "
        echo "    # /sbin/parted $device"
    echo "    (parted) toggle N boot"
    echo "    (parted) quit"
    exitclean
    fi
}

createGPTLayout() {
    dev=$1
    getdisk $dev

    echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
    echo "Press Enter to continue or ctrl-c to abort"
    read
    umount ${device}? &> /dev/null
    /sbin/parted --script $device mklabel gpt
    partinfo=$(/sbin/parted --script -m $device "unit b print" |grep ^$device:)
    size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
    /sbin/parted --script $device unit b mkpart '"EFI System Partition"' fat32 17408 $(($size - 17408)) set 1 boot on
    USBDEV=${device}1
    # Sometimes automount can be _really_ annoying.
    echo "Waiting for devices to settle..."
    /sbin/udevadm settle
    sleep 5
    umount $USBDEV &> /dev/null
    /sbin/mkdosfs -n LIVE $USBDEV
    USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
}

createMSDOSLayout() {
    dev=$1
    getdisk $dev

    echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
    echo "Press Enter to continue or ctrl-c to abort"
    read
    umount ${device}? &> /dev/null
    /sbin/parted --script $device mklabel msdos
    partinfo=$(/sbin/parted --script -m $device "unit b print" |grep ^$device:)
    size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/B$//')
    /sbin/parted --script $device unit b mkpart primary fat32 17408 $(($size - 17408)) set 1 boot on
    USBDEV=${device}1
    # Sometimes automount can be _really_ annoying.
    echo "Waiting for devices to settle..."
    /sbin/udevadm settle
    sleep 5
    umount $USBDEV &> /dev/null
    /sbin/mkdosfs -n LIVE $USBDEV
    USBLABEL="UUID=$(/sbin/blkid -s UUID -o value $USBDEV)"
}

checkGPT() {
    dev=$1
    getdisk $dev

    if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep -c GPT)" -eq "0" ]; then
       echo "EFI boot requires a GPT partition table."
       echo "This can be done manually or you can run with --format"
       exitclean
    fi

    partinfo=$(/sbin/parted --script -m $device "print" |grep ^$partnum:)
    volname=$(echo $partinfo |cut -d : -f 6)
    flags=$(echo $partinfo |cut -d : -f 7)
    if [ "$volname" != "EFI System Partition" ]; then
    echo "Partition name must be 'EFI System Partition'"
    echo "This can be set in parted or you can run with --reset-mbr"
    exitclean
    fi
    if [ "$(echo $flags |grep -c boot)" = "0" ]; then
    echo "Partition isn't marked bootable!"
    echo "You can mark the partition as bootable with "
        echo "    # /sbin/parted $device"
    echo "    (parted) toggle N boot"
    echo "    (parted) quit"
    exitclean
    fi
}

checkFilesystem() {
    dev=$1

    USBFS=$(/sbin/blkid -s TYPE -o value $dev)
    if [ "$USBFS" != "vfat" -a "$USBFS" != "msdos" -a "$USBFS" != "ext2" -a "$USBFS" != "ext3" ]; then
    echo "USB filesystem must be vfat or ext[23]"
    exitclean
    fi

    USBLABEL=$(/sbin/blkid -s UUID -o value $dev)
    if [ -n "$USBLABEL" ]; then
    USBLABEL="UUID=$USBLABEL" ;
    else
    USBLABEL=$(/sbin/blkid -s LABEL -o value $dev)
    if [ -n "$USBLABEL" ]; then
        USBLABEL="LABEL=$USBLABEL"
    else
        echo "Need to have a filesystem label or UUID for your USB device"
        if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
        echo "Label can be set with /sbin/dosfslabel"
        elif [ "$USBFS" = "ext2" -o "$USBFS" = "ext3" ]; then
        echo "Label can be set with /sbin/e2label"
        fi
        exitclean
    fi
    fi

    if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
    mountopts="-o shortname=winnt,umask=0077"
    fi
}

checkSyslinuxVersion() {
    if [ ! -x /usr/bin/syslinux ]; then
    echo "You need to have syslinux installed to run this script"
    exit 1
    fi
    if ! syslinux 2>&1 | grep -qe -d; then
    SYSLINUXPATH=""
    elif [ -n "$multi" ]; then
    SYSLINUXPATH="$LIVEOS/syslinux"
    else
    SYSLINUXPATH="syslinux"
    fi
}

checkMounted() {
    dev=$1
    if grep -q "^$dev " /proc/mounts ; then
      echo "$dev is mounted, please unmount for safety"
      exitclean
    fi
    if grep -q "^$dev " /proc/swaps; then
      echo "$dev is in use as a swap device, please disable swap"
      exitclean
    fi
}

checkint() {
    if ! test $1 -gt 0 2>/dev/null ; then
    usage
    fi
}

if [ $(id -u) != 0 ]; then
    echo "You need to be root to run this script"
    exit 1
fi

detectisotype() {
    if [ -e $CDMNT/LiveOS/squashfs.img ]; then
        isotype=live
        return
    fi
    if [ -e $CDMNT/images/install.img ]; then
        isotype=installer
        return
    fi
    echo "ERROR: $ISO does not appear to be a Live image or DVD installer."
    exitclean
}

cryptedhome=1
keephome=1
homesizemb=0
swapsizemb=0
overlaysizemb=0
isotype=
LIVEOS=LiveOS

HOMEFILE="home.img"
while [ $# -gt 2 ]; do
    case $1 in
    --overlay-size-mb)
        checkint $2
        overlaysizemb=$2
        shift
        ;;
    --home-size-mb)
        checkint $2
            homesizemb=$2
            shift
        ;;
    --swap-size-mb)
        checkint $2
        swapsizemb=$2
        shift
        ;;
        --crypted-home)
            cryptedhome=1
        ;;
        --unencrypted-home)
            cryptedhome=""
            ;;
        --delete-home)
            keephome=""
            ;;
    --noverify)
        noverify=1
        ;;
    --reset-mbr|--resetmbr)
        resetmbr=1
        ;;
    --efi|--mactel)
        efi=1
        ;;
    --format)
        format=1
        ;;
    --skipcopy)
        skipcopy=1
        ;;
    --xo)
        xo=1
        skipcompress=1
        ;;
    --xo-no-home)
        xonohome=1
        ;;
    --compress)
        skipcompress=""
        ;;
    --skipcompress)
        skipcompress=1
        ;;
        --extra-kernel-args)
            kernelargs=$2
            shift
            ;;
        --force)
            force=1
            ;;
    --livedir)
        LIVEOS=$2
        shift
        ;;
    --multi)
        multi=1
        ;;
    *)
        echo "invalid arg -- $1"
        usage
        ;;
    esac
    shift
done

ISO=$(readlink -f "$1")
USBDEV=$(readlink -f "$2")

if [ -z "$ISO" ]; then
    usage
fi

if [ ! -b "$ISO" -a ! -f "$ISO" ]; then
    usage
fi

# FIXME: If --format is given, we shouldn't care and just use /dev/foo1
if [ -z "$USBDEV" -o ! -b "$USBDEV" ]; then
    usage
fi

if [ -z "$noverify" ]; then
    # verify the image
    echo "Verifying image..."
    checkisomd5 --verbose "$ISO"
    if [ $? -ne 0 ]; then
    echo "Are you SURE you want to continue?"
    echo "Press Enter to continue or ctrl-c to abort"
    read
    fi
fi

# do some basic sanity checks. 
checkMounted $USBDEV
if [ -n "$format" ];then
  # checks for a valid filesystem
  if [ -n "$efi" ];then
    createGPTLayout $USBDEV
  else
    createMSDOSLayout $USBDEV
  fi
fi
checkFilesystem $USBDEV
if [ -n "$efi" ]; then
  checkGPT $USBDEV
fi
checkSyslinuxVersion
# Because we can't set boot flag for EFI Protective on msdos partition tables
[ -z "$efi" ] && checkPartActive $USBDEV
[ -n "$resetmbr" ] && resetMBR $USBDEV
checkMBR $USBDEV


if [ "$overlaysizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  if [ "$overlaysizemb" -gt 2047 ]; then
    echo "Can't have an overlay of 2048MB or greater on VFAT"
    exitclean
  fi
fi

if [ "$homesizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  if [ "$homesizemb" -gt 2047 ]; then
    echo "Can't have a home overlay greater than 2048MB on VFAT"
    exitclean
  fi
fi

if [ "$swapsizemb" -gt 0 -a "$USBFS" = "vfat" ]; then
  if [ "$swapsizemb" -gt 2047 ]; then
    echo "Can't have a swap file greater than 2048MB on VFAT"
    exitclean
  fi
fi

# FIXME: would be better if we had better mountpoints
CDMNT=$(mktemp -d /media/cdtmp.XXXXXX)
mount -o loop,ro "$ISO" $CDMNT || exitclean
USBMNT=$(mktemp -d /media/usbdev.XXXXXX)
mount $mountopts $USBDEV $USBMNT || exitclean

trap exitclean SIGINT SIGTERM

detectisotype

if [ -f "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a "$homesizemb" -gt 0 ]; then
  echo "ERROR: Requested keeping existing /home and specified a size for /home"
  echo "Please either don't specify a size or specify --delete-home"
  exitclean
fi

if [ -n "$efi" -a ! -d $CDMNT/EFI/boot ]; then
  echo "ERROR: This live image does not support EFI booting"
  exitclean
fi

# let's try to make sure there's enough room on the stick
if [ -d $CDMNT/LiveOS ]; then
  check=$CDMNT/LiveOS
else
  check=$CDMNT
fi
if [ -d $USBMNT/$LIVEOS ]; then
  tbd=$(du -s -B 1M $USBMNT/$LIVEOS | awk {'print $1;'})
  [ -f $USBMNT/$LIVEOS/$HOMEFILE ] && homesz=$(du -s -B 1M $USBMNT/$LIVEOS/$HOMEFILE | awk {'print $1;'})
  [ -n "$homesz" -a -n "$keephome" ] && tbd=$(($tbd - $homesz))
else
  tbd=0
fi
livesize=$(du -s -B 1M $check | awk {'print $1;'})
if [ -n "$skipcompress" ]; then
    if [ -e $CDMNT/LiveOS/squashfs.img ]; then
    if mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT; then
        livesize=$(du -s -B 1M $CDMNT/LiveOS/ext3fs.img | awk {'print $1;'})
        umount $CDMNT
    else
        echo "WARNING: --skipcompress or --xo was specified but the currently"
        echo "running kernel can not mount the squashfs from the ISO file to extract"
        echo "it. The compressed squashfs will be copied to the USB stick."
        skipcompress=""
    fi
    fi
fi
free=$(df  -B1M $USBDEV  |tail -n 1 |awk {'print $4;'})

if [ "$isotype" = "live" ]; then
tba=$(($overlaysizemb + $homesizemb + $livesize + $swapsizemb))
if [ $tba -gt $(($free + $tbd)) ]; then
  echo "Unable to fit live image + overlay on available space on USB stick"
  echo "+ Size of live image:  $livesize"
  [ "$overlaysizemb" -gt 0 ] && echo "+ Overlay size:  $overlaysizemb"
  [ "$homesizemb" -gt 0 ] && echo "+ Home overlay size:  $homesizemb"
  [ "$swapsizemb" -gt 0 ] && echo "+ Swap overlay size:  $swapsizemb"
  echo "---------------------------"
  echo "= Requested:  $tba"
  echo "- Available:  $(($free + $tbd))"
  echo "---------------------------"
  echo "= To fit, free or decrease requested size total by:  $(($tba - $free - $tbd))"
  exitclean
fi
fi

# Verify available space for DVD installer
if [ "$isotype" = "installer" ]; then
  isosize=$(du -s -B 1M $ISO | awk {'print $1;'})
  installimgsize=$(du -s -B 1M $CDMNT/images/install.img | awk {'print $1;'})
  tbd=0
  if [ -e $USBMNT/images/install.img ]; then
    tbd=$(du -s -B 1M $USBMNT/images/install.img | awk {'print $1;'})
  fi
  if [ -e $USBMNT/$(basename $ISO) ]; then
    tbd=$(($tbd + $(du -s -B 1M $USBMNT/$(basename $ISO) | awk {'print $1;'})))
  fi
  echo "Size of DVD image: $isosize"
  echo "Size of install.img: $installimgsize"
  echo "Available space: $(($free + $tbd))"
  if [ $(($isosize + $installimgsize)) -gt $(($free + $tbd)) ]; then
    echo "ERROR: Unable to fit DVD image + install.img on available space on USB stick"
    exitclean
  fi
fi

if [ -z "$skipcopy" ] && [ "$isotype" = "live" ]; then
  if [ -d $USBMNT/$LIVEOS -a -z "$force" ]; then
      echo "Already set up as live image." 
      if [ -z "$keephome" -a -e $USBMNT/$LIVEOS/$HOMEFILE ]; then
        echo "WARNING: Persistent /home will be deleted!!!"
        echo "Press Enter to continue or ctrl-c to abort"
        read
      else
        echo "Deleting old OS in fifteen seconds..."
        sleep 15

        [ -e "$USBMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" ] && mv $USBMNT/$LIVEOS/$HOMEFILE $USBMNT/$HOMEFILE
      fi

      rm -rf $USBMNT/$LIVEOS
  fi
fi

# Bootloader is always reconfigured, so keep these out of the if skipcopy stuff.
[ ! -d $USBMNT/$SYSLINUXPATH ] && mkdir -p $USBMNT/$SYSLINUXPATH
[ -n "$efi" -a ! -d $USBMNT/EFI/boot ] && mkdir -p $USBMNT/EFI/boot

# Live image copy
if [ -z "$skipcopy" ] && [ "$isotype" = "live" ]; then
  echo "Copying live image to USB stick"
  [ ! -d $USBMNT/$LIVEOS ] && mkdir $USBMNT/$LIVEOS
  [ -n "$keephome" -a -f "$USBMNT/$HOMEFILE" ] && mv $USBMNT/$HOMEFILE $USBMNT/$LIVEOS/$HOMEFILE
  if [ -n "$skipcompress" -a -f $CDMNT/LiveOS/squashfs.img ]; then
      mount -o loop $CDMNT/LiveOS/squashfs.img $CDMNT || exitclean
      cp $CDMNT/LiveOS/ext3fs.img $USBMNT/$LIVEOS/ext3fs.img || (umount $CDMNT ; exitclean)
      umount $CDMNT
  elif [ -f $CDMNT/LiveOS/squashfs.img ]; then
      cp $CDMNT/LiveOS/squashfs.img $USBMNT/$LIVEOS/squashfs.img || exitclean
  elif [ -f $CDMNT/LiveOS/ext3fs.img ]; then
      cp $CDMNT/LiveOS/ext3fs.img $USBMNT/$LIVEOS/ext3fs.img || exitclean
  fi
  if [ -f $CDMNT/LiveOS/osmin.img ]; then
      cp $CDMNT/LiveOS/osmin.img $USBMNT/$LIVEOS/osmin.img || exitclean
  fi
fi

# DVD installer copy
if [ "$isotype" = "installer" ] && [ -z "$skipcopy" ]; then
      echo "Copying DVD image to USB stick"
      mkdir -p $USBMNT/images/
      cp $CDMNT/images/install.img $USBMNT/images/install.img || exitclean
      cp $ISO $USBMNT/
fi

cp $CDMNT/isolinux/* $USBMNT/$SYSLINUXPATH
BOOTCONFIG=$USBMNT/$SYSLINUXPATH/isolinux.cfg
# Set this to nothing so sed doesn't care
BOOTCONFIG_EFI=
if [ -n "$efi" ];then
  cp $CDMNT/EFI/boot/* $USBMNT/EFI/boot

  # this is a little ugly, but it gets the "interesting" named config file
  BOOTCONFIG_EFI=$USBMNT/EFI/boot/boot?*.conf
  rm -f $USBMNT/EFI/boot/grub.conf
fi

echo "Updating boot config file"
# adjust label and fstype
sed -i -e "s/CDLABEL=[^ ]*/$USBLABEL/" -e "s/rootfstype=[^ ]*/rootfstype=$USBFS/" $BOOTCONFIG  $BOOTCONFIG_EFI
if [ -n "$kernelargs" ]; then sed -i -e "s/liveimg/liveimg ${kernelargs}/" $BOOTCONFIG $BOOTCONFIG_EFI ; fi
if [ "$LIVEOS" != "LiveOS" ]; then sed -i -e "s;liveimg;liveimg live_dir=$LIVEOS;" $BOOTCONFIG $BOOTCONFIG_EFI ; fi

# DVD Installer
if [ "$isotype" = "installer" ]; then
  sed -i -e "s;initrd=initrd.img;initrd=initrd.img repo=hd:$USBLABEL:/;g" $BOOTCONFIG $BOOTCONFIG_EFI
  sed -i -e "s;stage2=/S*;;g" $BOOTCONFIG $BOOTCONFIG_EFI
fi

if [ "$overlaysizemb" -gt 0 ]; then
    echo "Initializing persistent overlay file"
    OVERFILE="overlay-$( /sbin/blkid -s LABEL -o value $USBDEV )-$( /sbin/blkid -s UUID -o value $USBDEV )"
    if [ "$USBFS" = "vfat" ]; then
    # vfat can't handle sparse files
    dd if=/dev/zero of=$USBMNT/$LIVEOS/$OVERFILE count=$overlaysizemb bs=1M
    else
    dd if=/dev/null of=$USBMNT/$LIVEOS/$OVERFILE count=1 bs=1M seek=$overlaysizemb
    fi
    sed -i -e "s/liveimg/liveimg overlay=${USBLABEL}/" $BOOTCONFIG $BOOTCONFIG_EFI
    sed -i -e "s// ro/ // rw/ /" $BOOTCONFIG  $BOOTCONFIG_EFI
fi

if [ "$swapsizemb" -gt 0 ]; then
    echo "Initializing swap file"
    dd if=/dev/zero of=$USBMNT/$LIVEOS/swap.img count=$swapsizemb bs=1M
    mkswap -f $USBMNT/$LIVEOS/swap.img
fi

if [ "$homesizemb" -gt 0 ]; then
    echo "Initializing persistent /home"
    homesource=/dev/zero
    [ -n "$cryptedhome" ] && homesource=/dev/urandom
    if [ "$USBFS" = "vfat" ]; then
    # vfat can't handle sparse files
    dd if=${homesource} of=$USBMNT/$LIVEOS/$HOMEFILE count=$homesizemb bs=1M
    else
    dd if=/dev/null of=$USBMNT/$LIVEOS/$HOMEFILE count=1 bs=1M seek=$homesizemb
    fi
    if [ -n "$cryptedhome" ]; then
    loop=$(losetup -f)
    losetup $loop $USBMNT/$LIVEOS/$HOMEFILE
    setupworked=1
    until [ ${setupworked} == 0 ]; do
            echo "Encrypting persistent /home"
            cryptsetup luksFormat -y -q $loop
        setupworked=$?
    done
    setupworked=1
    until [ ${setupworked} == 0 ]; do
            echo "Please enter the password again to unlock the device"
            cryptsetup luksOpen $loop EncHomeFoo
        setupworked=$?
    done
        mke2fs -j /dev/mapper/EncHomeFoo
    tune2fs -c0 -i0 -ouser_xattr,acl /dev/mapper/EncHomeFoo
    sleep 2
        cryptsetup luksClose EncHomeFoo
        losetup -d $loop
    else
        echo "Formatting unencrypted /home"
    mke2fs -F -j $USBMNT/$LIVEOS/$HOMEFILE
    tune2fs -c0 -i0 -ouser_xattr,acl $USBMNT/$LIVEOS/$HOMEFILE
    fi
fi

# create the forth files for booting on the XO if requested
# we'd do this unconditionally, but you have to have a kernel that will
# boot on the XO anyway.
if [ -n "$xo" ]; then
    echo "Setting up /boot/olpc.fth file"
    args=$(egrep "^[ ]*append" $USBMNT/$SYSLINUXPATH/isolinux.cfg |head -n1 |sed -e 's/.*initrd=[^ ]*//')
    if [ -z "$xonohome" -a ! -f $USBMNT/$LIVEOS/$HOMEFILE ]; then
    args="$args persistenthome=mtd0"
    fi
    args="$args reset_overlay"
    xosyspath=$(echo $SYSLINUXPATH | sed -e 's;/;//;')
    if [ ! -d $USBMNT/boot ]; then mkdir -p $USBMNT/boot ; fi
    cat > $USBMNT/boot/olpc.fth <<EOF
/ Boot script for USB boot
hex  rom-pa fffc7 + 4 /$number drop  h# 2e19 < [if]
  patch 2drop erase claim-params
  : high-ramdisk  ( -- )
     cv-load-ramdisk
     h# 22c +lp l@ 1+   memory-limit  umin  /ramdisk - ffff.f000 and ( new-ramdisk-adr )
     ramdisk-adr over  /ramdisk move                    ( new-ramdisk-adr )
     to ramdisk-adr
  ;
  ' high-ramdisk to load-ramdisk
[then]

: set-bootpath-dev  ( -- )
   " /chosen" find-package  if                       ( phandle )
      " bootpath" rot  get-package-property  0=  if  ( propval$ )
         get-encoded-string                          ( bootpath$ )
         [char] / left-parse-string  2nip            ( dn$ )
         dn-buf place                                ( )
      then
   then

   " /sd"  dn-buf  count  sindex  0>=   if
          " sd:"
   else
          " u:"
   then
   " BOOTPATHDEV" /$set-macro
;

set-bootpath-dev
" $args" to boot-file
" /${BOOTPATHDEV}$xosyspath/initrd0.img" expand$ to ramdisk
" /${BOOTPATHDEV}$xosyspath/vmlinuz0" expand$ to boot-device
unfreeze
boot
EOF

fi

if [ -z "$multi" ]; then
  echo "Installing boot loader"
  if [ -n "$efi" ]; then
    # replace the ia32 hack
    if [ -f "$USBMNT/EFI/boot/boot.conf" ]; then cp -f $USBMNT/EFI/boot/bootia32.conf $USBMNT/EFI/boot/boot.conf ; fi
  fi

  # this is a bit of a kludge, but syslinux doesn't guarantee the API for its com32 modules :/
  if [ -f $USBMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/share/syslinux/vesamenu.c32 ]; then
    cp /usr/share/syslinux/vesamenu.c32 $USBMNT/$SYSLINUXPATH/vesamenu.c32
  elif [ -f $USBMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/lib/syslinux/vesamenu.c32 ]; then
    cp /usr/lib/syslinux/vesamenu.c32 $USBMNT/$SYSLINUXPATH/vesamenu.c32
  elif [ -f $USBMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/share/syslinux/menu.c32 ]; then
    cp /usr/share/syslinux/menu.c32 $USBMNT/$SYSLINUXPATH/menu.c32
  elif [ -f $USBMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/lib/syslinux/menu.c32 ]; then
    cp /usr/lib/syslinux/menu.c32 $USBMNT/$SYSLINUXPATH/menu.c32
  fi

  if [ "$USBFS" = "vfat" -o "$USBFS" = "msdos" ]; then
    # syslinux expects the config to be named syslinux.cfg
    # and has to run with the file system unmounted
    mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/syslinux.cfg
    # deal with mtools complaining about ldlinux.sys
    if [ -f $USBMNT/$SYSLINUXPATH/ldlinux.sys ] ; then rm -f $USBMNT/$SYSLINUXPATH/ldlinux.sys ; fi
    cleanup
    if [ -n "$SYSLINUXPATH" ]; then
      syslinux -d $SYSLINUXPATH $USBDEV
    else
      syslinux $USBDEV
    fi
  elif [ "$USBFS" = "ext2" -o "$USBFS" = "ext3" ]; then
    # extlinux expects the config to be named extlinux.conf
    # and has to be run with the file system mounted
    mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/extlinux.conf
    extlinux -i $USBMNT/$SYSLINUXPATH
    chattr -i $USBMNT/$SYSLINUXPATH/extlinux.sys
    cleanup
  fi
else
  # we need to do some more config file tweaks for multi-image mode
  sed -i -e "s;kernel vm;kernel /$LIVEOS/syslinux/vm;" $USBMNT/$SYSLINUXPATH/isolinux.cfg
  sed -i -e "s;initrd=i;initrd=/$LIVEOS/syslinux/i;" $USBMNT/$SYSLINUXPATH/isolinux.cfg
  mv $USBMNT/$SYSLINUXPATH/isolinux.cfg $USBMNT/$SYSLINUXPATH/syslinux.cfg
  cleanup
fi

echo "USB stick set up as live image!"