2 # Transfer a Live image so that it's bootable off of a USB/SD device.
3 # Copyright 2007 Red Hat, Inc.
4 # Jeremy Katz <katzj@redhat.com>
6 # overlay/persistence enhancements by Douglas McClendon <dmc@viros.org>
7 # GPT+MBR hybrid enhancements by Stewart Adam <s.adam@diffingo.com>
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; version 2 of the License.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Library General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 export PATH
=/sbin
:/usr
/sbin
:$PATH
29 livecd-iso-to-disk [--help] [--noverify] [--format] [--msdos] [--reset-mbr]
30 [--efi] [--skipcopy] [--force] [--xo] [--xo-no-home]
31 [--timeout <time>] [--totaltimeout <time>]
32 [--extra-kernel-args <args>] [--multi] [--livedir <dir>]
33 [--compress] [--skipcompress] [--swap-size-mb <size>]
34 [--overlay-size-mb <size>] [--home-size-mb <size>]
35 [--delete-home] [--crypted-home] [--unencrypted-home]
36 <source> <target device>
38 (Enter livecd-iso-to-disk --help on the command line for more information.)"
46 livecd-iso-to-disk - Transfer a LiveOS image so that it's bootable off of
49 The script may be run in simplest form with just the two arguments:
52 This may be the filesystem path to a LiveOS .iso image file,
53 such as from a CD-ROM, DVD, or download. It could also be the
54 device node reference for the mount point of another LiveOS
55 filesystem, including the currently-running one (such as a
56 booted Live CD/DVD/USB, where /dev/live references the running
60 This should be the device partition name for the attached,
61 target device, such as /dev/sdb1 or /dev/sdc1. (Issue the
62 df -Th command to get a listing of the mounted partitions,
63 where you can confirm the filesystem types, available space,
64 and device names.) Be careful to specify the correct device,
65 or you may overwrite important data on another disk!
67 To execute the script to completion, you will need to run it with root user
69 SYSLINUX must be installed on the computer running the installation script.
73 livecd-iso-to-disk installs a Live CD/DVD/USB image (LiveOS) onto a USB/SD
74 storage device (or any storage partition that will boot with a SYSLINUX
75 bootloader). The target storage device can then boot the installed
76 operating system on systems that support booting via the USB or the SD
77 interface. The script requires a LiveOS source image and a target storage
78 device. The source image may be either a LiveOS .iso file, the currently-
79 running LiveOS image, the device node reference for an attached device with
80 an installed LiveOS image, or a file backed by a block device with an
81 installed LiveOS image. If the operating system supports persistent
82 overlays for saving system changes, a pre-sized overlay may be included with
85 Unless you request the --format option, the installation does not destroy
86 data outside of the LiveOS, syslinux, & EFI folders on your target device.
87 This allows one to maintain other files on the target disk outside of the
90 LiveOS images provide embedded filesystems through the Device-mapper
91 component of the Linux kernel. The embedded filesystems exist within files
92 such as /LiveOS/squashfs.img (the default compressed storage) or
93 /LiveOS/ext3fs.img (an uncompressed version) on the primary volume partition
94 of the storage device. In use, these are read-only filesystems. Optionally,
95 one may specify a persistent LiveOS overlay to hold image-change snapshots
96 (that use write-once, difference-tracking storage) in the
97 /LiveOS/overlay-<device_id> file, which, *one should note*, always grows in
98 size due to the storage mechanism. (The fraction of allocated space that
99 has been consumed by system activity and changes may be displayed by issuing
100 the 'dmsetup status' command in a terminal session of a running LiveOS
101 image.) One way to conserve the unrecoverable, overlay file space, is to
102 specify a persistent home folder for user files, which will be saved in a
103 /LiveOS/home.img filesystem image file. This file space is encrypted by
104 default, but is not compressed. (One may bypass encryption with the
105 --unencrypted-home installation option.) Files in this home folder may be
106 erased to recover and reuse their storage space. The home.img file is also
107 convenient for backing up or swapping user account files.
112 Displays usage information and exits.
115 Disables the image validation process that occurs before the image is
116 installed from the original Live CD .iso image. When this option is
117 specified, the image is not verified before loading onto the target
121 Formats the target device and creates an MS-DOS partition table (or GPT
122 partition table, if the --efi option is passed).
125 Forces format to use msdos instead of ext4.
128 Sets the Master Boot Record (MBR) of the target storage device to the
129 mbr.bin file from the installation system's syslinux directory. This
130 may be helpful in recovering a damaged or corrupted device.
133 Creates a GUID partition table when --format is passed, and installs a
134 hybrid Extensible Firmware Interface (EFI)/MBR bootloader on the disk.
135 This is necessary for most Intel Macs.
138 Skips the copying of the live image to the target device, bypassing the
139 actions of the --format, --overlay-size-mb, --home-size-mb, &
140 --swap-size-mb options, if present on the command line. (The --skipcopy
141 option may be used while testing the script, in order to avoid repeated
142 and lengthy copy commands, or to repair boot configuration files on a
143 previously installed device.)
146 This option allows the installation script to bypass a delete
147 confirmation dialog in the event that a pre-existing LiveOS directory
148 is found on the target device.
151 Used to prepare an image for the OLPC XO-1 laptop with its compressed,
152 JFFS2 filesystem. Do not use the following options with --xo:
153 --overlay-size-mb <size>, home-size-mb <size>, --delete-home,
157 Used together with the --xo option to prepare an image for an OLPC XO
158 laptop with the home folder on an SD card instead of the internal flash
162 Modifies the bootloader's timeout value, which indicates how long to
163 pause at the boot: prompt before booting automatically. This overrides
164 the value set during iso creation. Units are 1/10 s. The timeout is
165 canceled when any key is pressed, the assumption being that the user
166 will complete the command line. A timeout of zero will disable the
170 Adds a bootloader totaltimeout, which indicates how long to wait before
171 booting automatically. This is used to force an automatic boot. This
172 timeout cannot be canceled by the user. Units are 1/10 s.
174 --extra-kernel-args <args>
175 Specifies additional kernel arguments, <args>, that will be inserted
176 into the syslinux and EFI boot configurations. Multiple arguments
177 should be specified in one string, i.e.,
178 --extra-kernel-args \"arg1 arg2 ...\"
181 Used when installing multiple image copies to signal configuration of
182 the boot files for the image in the --livedir <dir> parameter.
186 Used with multiple image installations to designate the directory <dir>
187 for the particular image.
189 --compress (default state for the operating system files)
190 The default, compressed SquashFS filesystem image is copied on
191 installation. This option has no effect when the source filesystem is
194 --skipcompress (default option when --xo is specified)
195 Expands the source SquashFS image on installation into the read-only
196 /LiveOS/ext3fs.img filesystem image file.
198 --swap-size-mb <size>
199 Sets up a swap file of <size> mebibytes (integer values only) on the
202 --overlay-size-mb <size>
203 This option sets the overlay size in mebibytes (integer values only).
204 The overlay makes persistent storage available to the live operating
205 system, if the operating system supports it. The persistent LiveOS
206 overlay holds image-change snapshots (using write-once, difference-
207 tracking storage) in the /LiveOS/overlay-<device_id> file, which, *one
208 should note*, always grows in size due to the storage mechanism. (The
209 fraction of allocated space that has been consumed may be displayed by
210 issuing the 'dmsetup status' command in a terminal session of a running
211 LiveOS installation.) One way to conserve the unrecoverable, overlay
212 file space, is to specify a persistent home folder for user files, see
213 --home-size-mb below. The target storage device must have enough free
214 space for the image and the overlay. A maximum <size> of 2047 MiB is
215 permitted for vfat-formatted devices. If there is insufficient room on
216 your device, you will be given information to help in adjusting your
219 --home-size-mb <size>
220 Sets the home directory size in mebibytes (integer values only). A
221 persistent home directory will be made in the /LiveOS/home.img
222 filesystem image file. This file space is encrypted by default, but not
223 compressed (one may bypass encryption with the --unencrypted-home
224 installation option). Files in this home folder may be erased to
225 recover and reuse their storage space. The target storage device must
226 have enough free space for the image, any overlay, and the home
227 directory. Note that the --delete-home option must also be selected to
228 replace an existing persistent home with a new, empty one. A maximum
229 <size> of 2047 MiB is permitted for vfat-formatted devices. If there is
230 insufficient room on your device, you will be given information to help
231 in adjusting your settings.
234 To prevent unwitting deletion of user files, this option must be
235 explicitly selected when the option --home-size-mb <size> is selected
236 and there is an existing persistent home directory on the target device.
238 --crypted-home (default that only applies to new home-size-mb requests)
239 Specifies the default option to encrypt a new persistent home directory
240 if --home-size-mb <size> is specified.
243 Prevents the default option to encrypt a new persistent home directory.
247 livecd-iso-to-disk: David Zeuthen, Jeremy Katz, Douglas McClendon,
248 Chris Curran and other contributors.
249 (See the AUTHORS file in the source distribution for
250 the complete list of credits.)
254 Report bugs to the mailing list
255 http://admin.fedoraproject.org/mailman/listinfo/livecd or directly to
256 Bugzilla http://bugzilla.redhat.com/bugzilla/ against the Fedora product,
257 and the livecd-tools component.
261 Copyright (C) Fedora Project 2008, 2009, 2010 and various contributors.
262 This is free software. You may redistribute copies of it under the terms of
263 the GNU General Public License http://www.gnu.org/licenses/gpl.html.
264 There is NO WARRANTY, to the extent permitted by law.
268 livecd-creator, project website http://fedoraproject.org/wiki/FedoraLiveCD
275 [ -d "$SRCMNT" ] && umount
$SRCMNT && rmdir $SRCMNT
276 [ -d "$TGTMNT" ] && umount
$TGTMNT && rmdir $TGTMNT
281 if [ -d "$SRCMNT" ] ||
[ -d "$TGTMNT" ];
283 [ "$RETVAL" = 0 ] ||
echo "Cleaning up to exit..."
290 [ x
"${1#/dev/loop}" != x
"$1" ]
296 if isdevloop
"$DEV"; then
301 p
=$
(udevadm info
-q path
-n $DEV)
302 if [ $?
-gt 0 ]; then
303 echo "Error getting udev path to $DEV"
306 if [ -e /sys
/$p/device
]; then
307 device
=$
(basename /sys
/$p)
309 device
=$
(basename $
(readlink
-f /sys
/$p/..
/))
311 if [ ! -e /sys
/block
/$device -o ! -e /dev
/$device ]; then
312 echo "Error finding block device of $DEV. Aborting!"
316 device
="/dev/$device"
317 # FIXME: weird dev names could mess this up I guess
318 p
=/dev
/$
(basename $p)
319 partnum
=${p##$device}
324 pa
=$
( < /proc
/partitions
)
330 if isdevloop
"$DEV"; then
334 # if efi, we need to use the hybrid MBR
335 if [ -n "$efi" ]; then
336 if [ -f /usr
/lib
/syslinux
/gptmbr.bin
]; then
337 cat /usr
/lib
/syslinux
/gptmbr.bin
> $device
338 elif [ -f /usr
/share
/syslinux
/gptmbr.bin
]; then
339 cat /usr
/share
/syslinux
/gptmbr.bin
> $device
341 echo "Could not find gptmbr.bin (syslinux)"
345 if [ -f /usr
/lib
/syslinux
/mbr.bin
]; then
346 cat /usr
/lib
/syslinux
/mbr.bin
> $device
347 elif [ -f /usr
/share
/syslinux
/mbr.bin
]; then
348 cat /usr
/share
/syslinux
/mbr.bin
> $device
350 echo "Could not find mbr.bin (syslinux)"
357 if isdevloop
"$DEV"; then
362 bs
=$
(mktemp
/tmp
/bs.XXXXXX
)
363 dd if=$device of
=$bs bs
=512 count
=1 2>/dev
/null ||
exit 2
365 mbrword
=$
(hexdump -n 2 $bs |
head -n 1|
awk {'print $2;'})
367 if [ "$mbrword" = "0000" ]; then
368 echo "MBR appears to be blank."
369 echo "Do you want to replace the MBR on this device?"
370 echo "Press Enter to continue or ctrl-c to abort"
382 # if we're installing to whole-disk and not a partition, then we
383 # don't need to worry about being active
384 if [ "$dev" = "$device" ]; then
387 if isdevloop
"$DEV"; then
391 if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep $dev |awk {'print $2;'})" != "*" ]; then
392 echo "Partition isn't marked bootable!"
393 echo "You can mark the partition as bootable with "
394 echo " # /sbin/parted $device"
395 echo " (parted) toggle N boot"
396 echo " (parted) quit"
404 if [ -x /sbin
/pvs
-a \
405 "$(/sbin/pvs -o vg_name --noheadings $dev* 2>/dev/null || :)" ]; then
406 echo "Device, $dev, contains a volume group and cannot be formated!"
407 echo "You can remove the volume group using vgremove."
417 echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
418 echo "Press Enter to continue or ctrl-c to abort"
420 umount
${device}* &> /dev
/null ||
:
421 /sbin
/parted
--script $device mklabel gpt
422 partinfo
=$
(LC_ALL
=C
/sbin
/parted
--script -m $device "unit b print" |
grep ^
$device:)
423 size
=$
(echo $partinfo |cut
-d : -f 2 |
sed -e 's/B$//')
424 /sbin
/parted
--script $device unit b mkpart
'"EFI System Partition"' fat32
1048576 $
(($size - 1048576)) set 1 boot on
425 # Sometimes automount can be _really_ annoying.
426 echo "Waiting for devices to settle..."
429 getpartition
${device#/dev/}
430 TGTDEV
=${device}${partnum}
431 umount
$TGTDEV &> /dev
/null ||
:
432 /sbin
/mkdosfs
-n LIVE
$TGTDEV
433 TGTLABEL
="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
436 createMSDOSLayout
() {
440 echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
441 echo "Press Enter to continue or ctrl-c to abort"
443 umount
${device}* &> /dev
/null ||
:
444 /sbin
/parted
--script $device mklabel msdos
445 partinfo
=$
(LC_ALL
=C
/sbin
/parted
--script -m $device "unit b print" |
grep ^
$device:)
446 size
=$
(echo $partinfo |cut
-d : -f 2 |
sed -e 's/B$//')
447 /sbin
/parted
--script $device unit b mkpart primary fat32
1048576 $
(($size - 1048576)) set 1 boot on
448 # Sometimes automount can be _really_ annoying.
449 echo "Waiting for devices to settle..."
452 if ! isdevloop
"$DEV"; then
453 getpartition
${device#/dev/}
454 TGTDEV
=${device}${partnum}
458 umount
$TGTDEV &> /dev
/null ||
:
459 /sbin
/mkdosfs
-n LIVE
$TGTDEV
460 TGTLABEL
="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
463 createEXTFSLayout
() {
467 echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
468 echo "Press Enter to continue or ctrl-c to abort"
470 umount
${device}* &> /dev
/null ||
:
471 /sbin
/parted
--script $device mklabel msdos
472 partinfo
=$
(LC_ALL
=C
/sbin
/parted
--script -m $device "unit b print" |
grep ^
$device:)
473 size
=$
(echo $partinfo |cut
-d : -f 2 |
sed -e 's/B$//')
474 /sbin
/parted
--script $device unit b mkpart primary ext2
1048576 $
(($size - 1048576)) set 1 boot on
475 # Sometimes automount can be _really_ annoying.
476 echo "Waiting for devices to settle..."
479 getpartition
${device#/dev/}
480 TGTDEV
=${device}${partnum}
481 umount
$TGTDEV &> /dev
/null ||
:
483 # Check extlinux version
484 if extlinux
-v 2>&1 |
grep -q 'extlinux 3'; then
485 /sbin
/mkfs.ext3
-L LIVE
$TGTDEV
487 /sbin
/mkfs.ext4
-L LIVE
$TGTDEV
489 TGTLABEL
="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
496 if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep -c GPT)" -eq "0" ]; then
497 echo "EFI boot requires a GPT partition table."
498 echo "This can be done manually or you can run with --format"
502 partinfo
=$
(LC_ALL
=C
/sbin
/parted
--script -m $device "print" |
grep ^
$partnum:)
503 volname
=$
(echo $partinfo |cut
-d : -f 6)
504 flags
=$
(echo $partinfo |cut
-d : -f 7)
505 if [ "$volname" != "EFI System Partition" ]; then
506 echo "Partition name must be 'EFI System Partition'"
507 echo "This can be set in parted or you can run with --reset-mbr"
510 if [ "$(echo $flags |grep -c boot)" = "0" ]; then
511 echo "Partition isn't marked bootable!"
512 echo "You can mark the partition as bootable with "
513 echo " # /sbin/parted $device"
514 echo " (parted) toggle N boot"
515 echo " (parted) quit"
523 TGTFS
=$
(/sbin
/blkid
-s TYPE
-o value
$dev ||
:)
524 if [ "$TGTFS" != "vfat" ] && [ "$TGTFS" != "msdos" ]; then
525 if [ "$TGTFS" != "ext2" ] && [ "$TGTFS" != "ext3" ] && [ "$TGTFS" != "ext4" ] && [ "$TGTFS" != "btrfs" ]; then
526 echo "Target filesystem must be vfat, ext[234] or btrfs"
532 TGTLABEL
=$
(/sbin
/blkid
-s UUID
-o value
$dev)
533 if [ -n "$TGTLABEL" ]; then
534 TGTLABEL
="UUID=$TGTLABEL"
536 TGTLABEL
=$
(/sbin
/blkid
-s LABEL
-o value
$dev)
537 if [ -n "$TGTLABEL" ]; then
538 TGTLABEL
="LABEL=$TGTLABEL"
540 echo "Need to have a filesystem label or UUID for your target device"
541 if [ "$TGTFS" = "vfat" -o "$TGTFS" = "msdos" ]; then
542 echo "Label can be set with /sbin/dosfslabel"
543 elif [ "$TGTFS" = "ext2" -o "$TGTFS" = "ext3" -o "$TGTFS" = "ext4" ]; then
544 echo "Label can be set with /sbin/e2label"
545 elif [ "$TGTFS" = "btrfs" ]; then
546 echo "Eventually you'll be able to use /sbin/btrfs filesystem label to add a label."
552 if [ "$TGTFS" = "vfat" -o "$TGTFS" = "msdos" ]; then
553 mountopts
="-o shortname=winnt,umask=0077"
557 checkSyslinuxVersion
() {
558 if [ ! -x /usr
/bin
/syslinux
]; then
559 echo "You need to have syslinux installed to run this script"
562 check
=($
(syslinux
--version 2>&1)) ||
:
563 if [[ 'syslinux' == $check ]]; then
565 elif [ -n "$multi" ]; then
566 SYSLINUXPATH
="$LIVEOS/syslinux"
568 SYSLINUXPATH
="syslinux"
574 if grep -q "^$dev " /proc
/mounts
; then
575 echo "$dev is mounted, please unmount for safety"
578 if grep -q "^$dev " /proc
/swaps
; then
579 echo "$dev is in use as a swap device, please disable swap"
585 if ! test $1 -gt 0 2>/dev
/null
; then
591 if [ $
(id
-u) != 0 ]; then
592 echo "You need to be root to run this script"
597 if [[ -e $SRCMNT/LiveOS
/squashfs.img
]]; then
601 if [ -e $SRCMNT/images
/install.img
-o $SRCMNT/isolinux
/initrd.img
]; then
603 if [ -e $SRCMNT/Packages
]; then
608 if [ ! -e $SRCMNT/images
/install.img
]; then
609 echo "$SRC uses initrd.img w/o install.img"
614 echo "ERROR: $SRC does not appear to be a Live image or DVD installer."
619 strace
-q -ewrite cp -- "${1}" "${2}" 2>&1 \
622 if (count % 10 == 0) {
623 percent = count / total_size * 100
624 printf "%3d%% [", percent
625 for (i=0;i<=percent;i++)
628 for (i=percent;i<100;i++)
633 END { print "" }' total_size
=$
(stat
-c '%s' "${1}") count
=0
637 if [ -x /usr
/bin
/gvfs-copy
]; then
638 gvfs-copy
-p "$1" "$2"
641 if [ -x /usr
/bin
/strace
-a -x /bin
/awk ]; then
663 if [[ "$*" =~
"--help" ]]; then
666 while [ $# -gt 2 ]; do
680 --reset-mbr|
--resetmbr)
751 echo "invalid arg -- $1"
759 SRC
=$
(readlink
-f "$1")
760 TGTDEV
=$
(readlink
-f "$2")
762 if [ -z "$SRC" ]; then
763 echo "Missing source"
768 if [ ! -b "$SRC" -a ! -f "$SRC" ]; then
769 echo "$SRC is not a file or block device"
774 if [ -z "$TGTDEV" ]; then
775 echo "Missing target device"
780 if [ ! -b "$TGTDEV" ]; then
781 echo "$TGTDEV is not a block device"
786 if [ -z "$noverify" ]; then
788 echo "Verifying image..."
789 if ! checkisomd5
--verbose "$SRC"; then
790 echo "Are you SURE you want to continue?"
791 echo "Press Enter to continue or ctrl-c to abort"
796 # do some basic sanity checks.
800 if [ -n "$format" -a -z "$skipcopy" ]; then
803 if [ -n "$efi" ]; then
804 createGPTLayout
$TGTDEV
805 elif [ -n "$usemsdos" -o ! -x /sbin
/extlinux
]; then
806 createMSDOSLayout
$TGTDEV
808 createEXTFSLayout
$TGTDEV
812 checkFilesystem
$TGTDEV
813 if [ -n "$efi" ]; then
818 # Because we can't set boot flag for EFI Protective on msdos partition tables
819 [ -z "$efi" ] && checkPartActive
$TGTDEV
820 [ -n "$resetmbr" ] && resetMBR
$TGTDEV
824 if [ "$overlaysizemb" -gt 0 -a "$TGTFS" = "vfat" ]; then
825 if [ "$overlaysizemb" -gt 2047 ]; then
826 echo "Can't have an overlay of 2048MB or greater on VFAT"
831 if [ "$homesizemb" -gt 0 -a "$TGTFS" = "vfat" ]; then
832 if [ "$homesizemb" -gt 2047 ]; then
833 echo "Can't have a home overlay greater than 2048MB on VFAT"
838 if [ "$swapsizemb" -gt 0 -a "$TGTFS" = "vfat" ]; then
839 if [ "$swapsizemb" -gt 2047 ]; then
840 echo "Can't have a swap file greater than 2048MB on VFAT"
845 # FIXME: would be better if we had better mountpoints
846 SRCMNT
=$
(mktemp
-d /media
/srctmp.XXXXXX
)
848 mount
-o ro
"$SRC" $SRCMNT || exitclean
849 elif [ -f $SRC ]; then
850 mount
-o loop
,ro
"$SRC" $SRCMNT || exitclean
852 echo "$SRC is not a file or block device."
855 TGTMNT
=$
(mktemp
-d /media
/tgttmp.XXXXXX
)
856 mount
$mountopts $TGTDEV $TGTMNT || exitclean
858 trap exitclean SIGINT SIGTERM
862 if [ -f "$TGTMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a "$homesizemb" -gt 0 ]; then
863 echo "ERROR: Requested keeping existing /home and specified a size for /home"
864 echo "Please either don't specify a size or specify --delete-home"
868 if [ -n "$efi" ]; then
869 if [ -d $SRCMNT/EFI
/BOOT
]; then
871 elif [ -d $SRCMNT/EFI
/boot
]; then
874 echo "ERROR: This live image does not support EFI booting"
879 # let's try to make sure there's enough room on the target device
880 if [[ -d $TGTMNT/$LIVEOS ]]; then
881 tbd
=($
(du
-B 1M
$TGTMNT/$LIVEOS))
882 if [[ -s $TGTMNT/$LIVEOS/$HOMEFILE ]] && [[ -n $keephome ]]; then
883 homesize
=($
(du
-B 1M
$TGTMNT/$LIVEOS/$HOMEFILE))
890 if [[ live
== $srctype ]]; then
891 targets
="$TGTMNT/$SYSLINUXPATH"
892 [[ -n $efi ]] && targets
+=" $TGTMNT$EFI_BOOT"
893 [[ -n $xo ]] && targets
+=" $TGTMNT/BOOT/olpc.fth"
894 duTable
=($
(du
-c -B 1M
$targets 2> /dev
/null ||
:))
895 ((tbd
+= ${duTable[*]: -2:1}))
898 if [[ -n $skipcompress ]] && [[ -s $SRCMNT/LiveOS
/squashfs.img
]]; then
899 if mount
-o loop
$SRCMNT/LiveOS
/squashfs.img
$SRCMNT; then
900 livesize
=($
(du
-B 1M
--apparent-size $SRCMNT/LiveOS
/ext3fs.img
))
902 if ((livesize
> 2048)) && [[ vfat
== $TGTFS ]]; then
904 An uncompressed image size greater than 2048 MB is not suitable
905 for a VFAT-formatted device. The compressed SquashFS will be
906 copied to the target device.
912 echo "WARNING: --skipcompress or --xo was specified but the
913 currently-running kernel can not mount the SquashFS from the source
914 file to extract it. Instead, the compressed SquashFS will be copied
915 to the target device."
919 if [[ live
== $srctype ]]; then
920 thisScriptpath
=$
(readlink
-f "$0")
921 sources
="$SRCMNT/LiveOS/ext3fs.img $SRCMNT/LiveOS/osmin.img"
922 [[ -z $skipcompress ]] && sources
+=" $SRCMNT/LiveOS/squashfs.img"
923 sources
+=" $SRCMNT/isolinux $SRCMNT/syslinux"
924 [[ -n $efi ]] && sources
+=" $SRCMNT$EFI_BOOT"
925 [[ -n $xo ]] && sources
+=" $SRCMNT/BOOT/olpc.fth"
926 duTable
=($
(du
-c -B 1M
"$thisScriptpath" $sources 2> /dev
/null ||
:))
927 ((livesize
+= ${duTable[*]: -2:1}))
930 freespace
=($
(df
-B 1M
--total $TGTDEV))
931 freespace
=${freespace[*]: -2:1}
933 if [[ live
== $srctype ]]; then
934 tba
=$
((overlaysizemb
+ homesizemb
+ livesize
+ swapsizemb
))
935 if ((tba
> freespace
+ tbd
)); then
936 needed
=$
((tba
- freespace
- tbd
))
937 printf "\n The live image + overlay, home, & swap space, if requested,
938 \r will NOT fit in the space available on the target device.\n
939 \r + Size of live image: %10s MiB\n" $livesize
940 (($overlaysizemb > 0)) && \
941 printf " + Overlay size: %16s\n" $overlaysizemb
942 (($homesizemb > 0)) && \
943 printf " + Home directory size: %9s\n" $homesizemb
944 (($swapsizemb > 0)) && \
945 printf " + Swap overlay size: %11s\n" $swapsizemb
946 printf " = Total requested space: %6s MiB\n" $tba
947 printf " - Space available: %12s\n" $
((freespace
+ tbd
))
948 printf " ==============================\n"
949 printf " Space needed: %15s MiB\n\n" $needed
950 printf " To fit the installation on this device,
951 \r free space on the target, or decrease the
952 \r requested size total by: %6s MiB\n\n" $needed
957 # Verify available space for DVD installer
958 if [ "$srctype" = "installer" ]; then
959 if [ -z "$skipcopy" ]; then
960 srcsize
=$
(du
-s -B 1M
$SRC |
awk {'print $1;'})
964 if [ "$imgtype" = "install" ]; then
965 imgpath
=images
/install.img
967 imgpath
=isolinux
/initrd.img
969 installimgsize
=$
(du
-s -B 1M
$SRCMNT/$imgpath |
awk {'print $1;'})
972 if [ -e $TGTMNT/$imgpath ]; then
973 tbd
=$
(du
-s -B 1M
$TGTMNT/$imgpath |
awk {'print $1;'})
975 if [ -e $TGTMNT/$
(basename $SRC) ]; then
976 tbd
=$
(($tbd + $
(du
-s -B 1M
$TGTMNT/$
(basename $SRC) |
awk {'print $1;'})))
978 echo "Size of DVD image: $srcsize"
979 echo "Size of $imgpath: $installimgsize"
980 echo "Available space: $((freespace + tbd))"
981 if (( ((srcsize
+ installimgsize
)) > ((freespace
+ tbd
)) )); then
982 echo "ERROR: Unable to fit DVD image + install.img on available space on the target device."
987 if [ -z "$skipcopy" ] && [ "$srctype" = "live" ]; then
988 if [ -d $TGTMNT/$LIVEOS -a -z "$force" ]; then
989 echo "Already set up as live image."
990 if [ -z "$keephome" -a -e $TGTMNT/$LIVEOS/$HOMEFILE ]; then
991 echo "WARNING: Persistent /home will be deleted!!!"
992 echo "Press Enter to continue or ctrl-c to abort"
995 echo "Deleting old OS in fifteen seconds..."
998 [ -e "$TGTMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" ] && mv $TGTMNT/$LIVEOS/$HOMEFILE $TGTMNT/$HOMEFILE
1001 rm -rf $TGTMNT/$LIVEOS
1005 # Bootloader is always reconfigured, so keep these out of the if skipcopy stuff.
1006 [ ! -d $TGTMNT/$SYSLINUXPATH ] && mkdir
-p $TGTMNT/$SYSLINUXPATH
1007 [ -n "$efi" -a ! -d $TGTMNT$EFI_BOOT ] && mkdir
-p $TGTMNT$EFI_BOOT
1010 if [ "$srctype" = "live" -a -z "$skipcopy" ]; then
1011 echo "Copying live image to target device."
1012 [ ! -d $TGTMNT/$LIVEOS ] && mkdir
$TGTMNT/$LIVEOS
1013 [ -n "$keephome" -a -f "$TGTMNT/$HOMEFILE" ] && mv $TGTMNT/$HOMEFILE $TGTMNT/$LIVEOS/$HOMEFILE
1014 if [ -n "$skipcompress" -a -f $SRCMNT/LiveOS
/squashfs.img
]; then
1015 mount
-o loop
$SRCMNT/LiveOS
/squashfs.img
$SRCMNT || exitclean
1016 copyFile
$SRCMNT/LiveOS
/ext3fs.img
$TGTMNT/$LIVEOS/ext3fs.img ||
{
1017 umount
$SRCMNT ; exitclean
; }
1019 elif [ -f $SRCMNT/LiveOS
/squashfs.img
]; then
1020 copyFile
$SRCMNT/LiveOS
/squashfs.img
$TGTMNT/$LIVEOS/squashfs.img || exitclean
1021 elif [ -f $SRCMNT/LiveOS
/ext3fs.img
]; then
1022 copyFile
$SRCMNT/LiveOS
/ext3fs.img
$TGTMNT/$LIVEOS/ext3fs.img || exitclean
1024 if [ -f $SRCMNT/LiveOS
/osmin.img
]; then
1025 copyFile
$SRCMNT/LiveOS
/osmin.img
$TGTMNT/$LIVEOS/osmin.img || exitclean
1030 # DVD installer copy
1031 if [ \
( "$srctype" = "installer" -o "$srctype" = "netinst" \
) ]; then
1032 echo "Copying DVD image to target device."
1033 mkdir
-p $TGTMNT/images
/
1034 if [ "$imgtype" = "install" ]; then
1035 copyFile
$SRCMNT/images
/install.img
$TGTMNT/images
/install.img || exitclean
1037 if [ "$srctype" = "installer" -a -z "$skipcopy" ]; then
1043 # Adjust syslinux sources for replication of installed images
1044 # between filesystem types.
1045 if [[ -d $SRCMNT/isolinux
/ ]]; then
1046 cp $SRCMNT/isolinux
/* $TGTMNT/$SYSLINUXPATH
1047 elif [[ -d $SRCMNT/syslinux
/ ]]; then
1048 cp $SRCMNT/syslinux
/* $TGTMNT/$SYSLINUXPATH
1049 if [[ -f $SRCMNT/syslinux
/extlinux.conf
]]; then
1050 mv $TGTMNT/$SYSLINUXPATH/extlinux.conf \
1051 $TGTMNT/$SYSLINUXPATH/isolinux.cfg
1052 elif [[ -f $SRCMNT/syslinux
/syslinux.cfg
]]; then
1053 mv $TGTMNT/$SYSLINUXPATH/syslinux.cfg
$TGTMNT/$SYSLINUXPATH/isolinux.cfg
1056 BOOTCONFIG
=$TGTMNT/$SYSLINUXPATH/isolinux.cfg
1057 # Set this to nothing so sed doesn't care
1059 if [ -n "$efi" ]; then
1060 cp $SRCMNT$EFI_BOOT/* $TGTMNT$EFI_BOOT
1063 # There is a problem here. On older LiveCD's the files are boot?*.conf
1064 # They really should be renamed to BOOT?*.conf
1066 # this is a little ugly, but it gets the "interesting" named config file
1067 BOOTCONFIG_EFI
=$TGTMNT$EFI_BOOT/+(BOOT|boot
)?
*.conf
1068 rm -f $TGTMNT$EFI_BOOT/grub.conf
1070 # On some images (RHEL) the BOOT*.efi file isn't in $EFI_BOOT, but is in
1071 # the eltorito image, so try to extract it if it is missing
1073 # test for presence of *.efi grub binary
1074 if [ ! -f $TGTMNT$EFI_BOOT/+(BOOT|boot
)?
*.efi
]; then
1075 if [ ! -x /usr
/bin
/dumpet
]; then
1076 echo "No /usr/bin/dumpet tool found. EFI image will not boot."
1077 echo "Source media is missing grub binary in /EFI/BOOT/*efi"
1080 # dump the eltorito image with dumpet, output is $SRC.1
1082 EFIMNT
=$
(mktemp
-d /media
/srctmp.XXXXXX
)
1083 mount
-o loop
$SRC.1 $EFIMNT
1085 if [ -f $EFIMNT$EFI_BOOT/+(BOOT|boot
)?
*.efi
]; then
1086 cp $EFIMNT$EFI_BOOT/+(BOOT|boot
)?
*.efi
$TGTMNT$EFI_BOOT
1088 echo "No BOOT*.efi found in eltorito image. EFI will not boot"
1099 if [[ live
== $srctype ]]; then
1100 # Copy this installer script.
1101 cp -fT "$thisScriptpath" $TGTMNT/$LIVEOS/livecd-iso-to-disk
1102 chmod +x
$TGTMNT/$LIVEOS/livecd-iso-to-disk
&> /dev
/null ||
:
1104 # When the source is an installed Live USB/SD image, restore the boot config
1105 # file to a base state before updating.
1106 if [[ -d $SRCMNT/syslinux
/ ]]; then
1107 echo "Preparing boot config file."
1108 sed -i -e "s/root=live:[^ ]*/root=live:CDLABEL=name/"\
1109 -e "s/liveimg .* quiet/liveimg quiet/"\
1110 $BOOTCONFIG $BOOTCONFIG_EFI
1111 sed -i -e "s/^timeout.*$/timeout\ 100/"\
1112 -e "/^totaltimeout.*$/d" $BOOTCONFIG
1115 echo "Updating boot config file"
1116 # adjust label and fstype
1117 if [ -n "$LANG" ]; then
1118 kernelargs
="$kernelargs LANG=$LANG"
1120 sed -i -e "s/CDLABEL=[^ ]*/$TGTLABEL/" -e "s/rootfstype=[^ ]*/rootfstype=$TGTFS/" -e "s/LABEL=[^ ]*/$TGTLABEL/" $BOOTCONFIG $BOOTCONFIG_EFI
1121 if [ -n "$kernelargs" ]; then
1122 sed -i -e "s/liveimg/liveimg ${kernelargs}/" $BOOTCONFIG $BOOTCONFIG_EFI
1124 if [ "$LIVEOS" != "LiveOS" ]; then
1125 sed -i -e "s;liveimg;liveimg live_dir=$LIVEOS;" $BOOTCONFIG $BOOTCONFIG_EFI
1129 if [ "$srctype" = "installer" ]; then
1130 sed -i -e "s;initrd=initrd.img;initrd=initrd.img ${LANG:+LANG=$LANG} repo=hd:$TGTLABEL:/;g" $BOOTCONFIG
1131 sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG
1132 if [ -n "$efi" ]; then
1133 # Images are in / now
1134 sed -i -e "s;images/pxeboot/;;g" -e "s;vmlinuz;vmlinuz ${LANG:+LANG=$LANG} repo=hd:$TGTLABEL:/;g" $BOOTCONFIG_EFI
1138 # DVD Installer for netinst
1139 if [ "$srctype" = "netinst" ]; then
1140 if [ "$imgtype" = "install" ]; then
1141 sed -i -e "s;stage2=\S*;stage2=hd:$TGTLABEL:/images/install.img;g" $BOOTCONFIG
1143 # The initrd has everything, so no stage2
1144 sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG
1146 if [ -n "$efi" ]; then
1147 # Images are in / now
1148 sed -ie "s;images/pxeboot/;;g" $BOOTCONFIG_EFI
1153 # Adjust the boot timeouts
1154 if [ -n "$timeout" ]; then
1155 sed -i -e "s/^timeout.*$/timeout\ $timeout/" $BOOTCONFIG
1157 if [ -n "$totaltimeout" ]; then
1158 sed -i -e "/^timeout.*$/a\totaltimeout\ $totaltimeout" $BOOTCONFIG
1161 # Use repo if the .iso has the repository on it, otherwise use stage2 which
1162 # will default to using the network mirror
1163 if [ -e "$SRCMNT/.discinfo" ]; then
1169 if [ "$overlaysizemb" -gt 0 ]; then
1170 echo "Initializing persistent overlay file"
1171 OVERFILE
="overlay-$( /sbin/blkid -s LABEL -o value $TGTDEV )-$( /sbin/blkid -s UUID -o value $TGTDEV )"
1172 if [ -z "$skipcopy" ]; then
1173 if [ "$TGTFS" = "vfat" ]; then
1174 # vfat can't handle sparse files
1175 dd if=/dev
/zero of
=$TGTMNT/$LIVEOS/$OVERFILE count
=$overlaysizemb bs
=1M
1177 dd if=/dev
/null of
=$TGTMNT/$LIVEOS/$OVERFILE count
=1 bs
=1M seek
=$overlaysizemb
1180 sed -i -e "s/liveimg/liveimg overlay=${TGTLABEL}/" $BOOTCONFIG $BOOTCONFIG_EFI
1181 sed -i -e "s/\ ro\ /\ rw\ /" $BOOTCONFIG $BOOTCONFIG_EFI
1184 if [ "$swapsizemb" -gt 0 -a -z "$skipcopy" ]; then
1185 echo "Initializing swap file"
1186 dd if=/dev
/zero of
=$TGTMNT/$LIVEOS/swap.img count
=$swapsizemb bs
=1M
1187 mkswap
-f $TGTMNT/$LIVEOS/swap.img
1190 if [ "$homesizemb" -gt 0 -a -z "$skipcopy" ]; then
1191 echo "Initializing persistent /home"
1192 homesource
=/dev
/zero
1193 [ -n "$cryptedhome" ] && homesource
=/dev
/urandom
1194 if [ "$TGTFS" = "vfat" ]; then
1195 # vfat can't handle sparse files
1196 dd if=${homesource} of
=$TGTMNT/$LIVEOS/$HOMEFILE count
=$homesizemb bs
=1M
1198 dd if=/dev
/null of
=$TGTMNT/$LIVEOS/$HOMEFILE count
=1 bs
=1M seek
=$homesizemb
1200 if [ -n "$cryptedhome" ]; then
1202 losetup
$loop $TGTMNT/$LIVEOS/$HOMEFILE
1204 echo "Encrypting persistent /home"
1205 while ! cryptsetup luksFormat
-y -q $loop; do :; done;
1207 echo "Please enter the password again to unlock the device"
1208 while ! cryptsetup luksOpen
$loop EncHomeFoo
; do :; done;
1210 mkfs.ext4
-j /dev
/mapper
/EncHomeFoo
1211 tune2fs
-c0 -i0 -ouser_xattr,acl
/dev
/mapper
/EncHomeFoo
1213 cryptsetup luksClose EncHomeFoo
1216 echo "Formatting unencrypted /home"
1217 mkfs.ext4
-F -j $TGTMNT/$LIVEOS/$HOMEFILE
1218 tune2fs
-c0 -i0 -ouser_xattr,acl
$TGTMNT/$LIVEOS/$HOMEFILE
1222 # create the forth files for booting on the XO if requested
1223 # we'd do this unconditionally, but you have to have a kernel that will
1224 # boot on the XO anyway.
1225 if [ -n "$xo" ]; then
1226 echo "Setting up /boot/olpc.fth file"
1227 args
=$
(grep "^ *append" $TGTMNT/$SYSLINUXPATH/isolinux.cfg |
head -n1 |
sed -e 's/.*initrd=[^ ]*//')
1228 if [ -z "$xonohome" -a ! -f $TGTMNT/$LIVEOS/$HOMEFILE ]; then
1229 args
="$args persistenthome=mtd0"
1231 args
="$args reset_overlay"
1232 xosyspath
=$
(echo $SYSLINUXPATH |
sed -e 's;/;\\;')
1233 if [ ! -d $TGTMNT/boot
]; then
1234 mkdir
-p $TGTMNT/boot
1236 cat > $TGTMNT/boot
/olpc.fth
<<EOF
1237 \ Boot script for USB boot
1238 hex rom-pa fffc7 + 4 \$number drop h# 2e19 < [if]
1239 patch 2drop erase claim-params
1240 : high-ramdisk ( -- )
1242 h# 22c +lp l@ 1+ memory-limit umin /ramdisk - ffff.f000 and ( new-ramdisk-adr )
1243 ramdisk-adr over /ramdisk move ( new-ramdisk-adr )
1246 ' high-ramdisk to load-ramdisk
1249 : set-bootpath-dev ( -- )
1250 " /chosen" find-package if ( phandle )
1251 " bootpath" rot get-package-property 0= if ( propval$ )
1252 get-encoded-string ( bootpath$ )
1253 [char] \ left-parse-string 2nip ( dn$ )
1258 " /sd" dn-buf count sindex 0>= if
1263 " BOOTPATHDEV" \$set-macro
1267 " $args" to boot-file
1268 " \${BOOTPATHDEV}$xosyspath\initrd0.img" expand$ to ramdisk
1269 " \${BOOTPATHDEV}$xosyspath\vmlinuz0" expand$ to boot-device
1276 if [ -z "$multi" ]; then
1277 echo "Installing boot loader"
1278 if [ -n "$efi" ]; then
1279 # replace the ia32 hack
1280 if [ -f "$TGTMNT$EFI_BOOT/boot.conf" ]; then
1281 cp -f $TGTMNT$EFI_BOOT/BOOTia32.conf
$TGTMNT$EFI_BOOT/BOOT.conf
1285 # this is a bit of a kludge, but syslinux doesn't guarantee the API for its com32 modules :/
1286 if [ -f $TGTMNT/$SYSLINUXPATH/vesamenu.c32
-a -f /usr
/share
/syslinux
/vesamenu.c32
]; then
1287 cp /usr
/share
/syslinux
/vesamenu.c32
$TGTMNT/$SYSLINUXPATH/vesamenu.c32
1288 elif [ -f $TGTMNT/$SYSLINUXPATH/vesamenu.c32
-a -f /usr
/lib
/syslinux
/vesamenu.c32
]; then
1289 cp /usr
/lib
/syslinux
/vesamenu.c32
$TGTMNT/$SYSLINUXPATH/vesamenu.c32
1290 elif [ -f $TGTMNT/$SYSLINUXPATH/menu.c32
-a -f /usr
/share
/syslinux
/menu.c32
]; then
1291 cp /usr
/share
/syslinux
/menu.c32
$TGTMNT/$SYSLINUXPATH/menu.c32
1292 elif [ -f $TGTMNT/$SYSLINUXPATH/menu.c32
-a -f /usr
/lib
/syslinux
/menu.c32
]; then
1293 cp /usr
/lib
/syslinux
/menu.c32
$TGTMNT/$SYSLINUXPATH/menu.c32
1296 if [ "$TGTFS" == "vfat" -o "$TGTFS" == "msdos" ]; then
1297 # syslinux expects the config to be named syslinux.cfg
1298 # and has to run with the file system unmounted
1299 mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg
$TGTMNT/$SYSLINUXPATH/syslinux.cfg
1300 # deal with mtools complaining about ldlinux.sys
1301 if [ -f $TGTMNT/$SYSLINUXPATH/ldlinux.sys
]; then
1302 rm -f $TGTMNT/$SYSLINUXPATH/ldlinux.sys
1305 if [ -n "$SYSLINUXPATH" ]; then
1306 syslinux
-d $SYSLINUXPATH $TGTDEV
1310 elif [ "$TGTFS" == "ext2" -o "$TGTFS" == "ext3" -o "$TGTFS" == "ext4" -o "$TGTFS" == "btrfs" ]; then
1311 # extlinux expects the config to be named extlinux.conf
1312 # and has to be run with the file system mounted
1313 mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg
$TGTMNT/$SYSLINUXPATH/extlinux.conf
1314 extlinux
-i $TGTMNT/$SYSLINUXPATH
1315 # Starting with syslinux 4 ldlinux.sys is used on all file systems.
1316 if [ -f "$TGTMNT/$SYSLINUXPATH/extlinux.sys" ]; then
1317 chattr -i $TGTMNT/$SYSLINUXPATH/extlinux.sys
1318 elif [ -f "$TGTMNT/$SYSLINUXPATH/ldlinux.sys" ]; then
1319 chattr -i $TGTMNT/$SYSLINUXPATH/ldlinux.sys
1324 # we need to do some more config file tweaks for multi-image mode
1325 sed -i -e "s;kernel vm;kernel /$LIVEOS/syslinux/vm;" $TGTMNT/$SYSLINUXPATH/isolinux.cfg
1326 sed -i -e "s;initrd=i;initrd=/$LIVEOS/syslinux/i;" $TGTMNT/$SYSLINUXPATH/isolinux.cfg
1327 mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg
$TGTMNT/$SYSLINUXPATH/syslinux.cfg
1331 echo "Target device is now set up with a Live image!"