Version 18.10
[livecd.git] / tools / livecd-iso-to-disk.sh
blob1a87869715aa85dc51b7769544bab56f898631aa
1 #!/bin/bash
2 # Transfer a Live image so that it's bootable off of a USB/SD device.
3 # Copyright 2007-2012 Red Hat, Inc.
5 # Jeremy Katz <katzj@redhat.com>
6 # Brian C. Lane <bcl@redhat.com>
8 # overlay/persistence enhancements by Douglas McClendon <dmc@viros.org>
9 # GPT+MBR hybrid enhancements by Stewart Adam <s.adam@diffingo.com>
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; version 2 of the License.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU Library General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program; if not, write to the Free Software
22 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 export PATH=/sbin:/usr/sbin:$PATH
27 shortusage() {
28 echo "
29 SYNTAX
31 livecd-iso-to-disk [--help] [--noverify] [--format] [--msdos] [--reset-mbr]
32 [--efi] [--skipcopy] [--force] [--xo] [--xo-no-home]
33 [--timeout <time>] [--totaltimeout <time>]
34 [--extra-kernel-args <args>] [--multi] [--livedir <dir>]
35 [--compress] [--skipcompress] [--swap-size-mb <size>]
36 [--overlay-size-mb <size>] [--home-size-mb <size>]
37 [--delete-home] [--crypted-home] [--unencrypted-home]
38 <source> <target device>
40 (Enter livecd-iso-to-disk --help on the command line for more information.)"
43 usage() {
44 echo "
46 shortusage
47 echo "
48 livecd-iso-to-disk - Transfer a LiveOS image so that it's bootable off of
49 a USB/SD device.
51 The script may be run in simplest form with just the two arguments:
53 <source>
54 This may be the filesystem path to a LiveOS .iso image file,
55 such as from a CD-ROM, DVD, or download. It could also be the
56 device node reference for the mount point of another LiveOS
57 filesystem, including the currently-running one (such as a
58 booted Live CD/DVD/USB, where /dev/live references the running
59 image device).
61 <target device>
62 This should be the device partition name for the attached,
63 target device, such as /dev/sdb1 or /dev/sdc1. (Issue the
64 df -Th command to get a listing of the mounted partitions,
65 where you can confirm the filesystem types, available space,
66 and device names.) Be careful to specify the correct device,
67 or you may overwrite important data on another disk!
69 To execute the script to completion, you will need to run it with root user
70 permissions.
71 SYSLINUX must be installed on the computer running the installation script.
73 DESCRIPTION
75 livecd-iso-to-disk installs a Live CD/DVD/USB image (LiveOS) onto a USB/SD
76 storage device (or any storage partition that will boot with a SYSLINUX
77 bootloader). The target storage device can then boot the installed
78 operating system on systems that support booting via the USB or the SD
79 interface. The script requires a LiveOS source image and a target storage
80 device. The source image may be either a LiveOS .iso file, the currently-
81 running LiveOS image, the device node reference for an attached device with
82 an installed LiveOS image, or a file backed by a block device with an
83 installed LiveOS image. If the operating system supports persistent
84 overlays for saving system changes, a pre-sized overlay may be included with
85 the installation.
87 Unless you request the --format option, the installation does not destroy
88 data outside of the LiveOS, syslinux, & EFI folders on your target device.
89 This allows one to maintain other files on the target disk outside of the
90 LiveOS filesystem.
92 LiveOS images provide embedded filesystems through the Device-mapper
93 component of the Linux kernel. The embedded filesystems exist within files
94 such as /LiveOS/squashfs.img (the default compressed storage) or
95 /LiveOS/ext3fs.img (an uncompressed version) on the primary volume partition
96 of the storage device. In use, these are read-only filesystems. Optionally,
97 one may specify a persistent LiveOS overlay to hold image-change snapshots
98 (that use write-once, difference-tracking storage) in the
99 /LiveOS/overlay-<device_id> file, which, *one should note*, always grows in
100 size due to the storage mechanism. (The fraction of allocated space that
101 has been consumed by system activity and changes may be displayed by issuing
102 the 'dmsetup status' command in a terminal session of a running LiveOS
103 image.) One way to conserve the unrecoverable, overlay file space, is to
104 specify a persistent home folder for user files, which will be saved in a
105 /LiveOS/home.img filesystem image file. This file space is encrypted by
106 default, but is not compressed. (One may bypass encryption with the
107 --unencrypted-home installation option.) Files in this home folder may be
108 erased to recover and reuse their storage space. The home.img file is also
109 convenient for backing up or swapping user account files.
111 OPTIONS
113 --help
114 Displays usage information and exits.
116 --noverify
117 Disables the image validation process that occurs before the image is
118 installed from the original Live CD .iso image. When this option is
119 specified, the image is not verified before loading onto the target
120 storage device.
122 --format
123 Formats the target device and creates an MS-DOS partition table (or GPT
124 partition table, if the --efi option is passed).
126 --msdos
127 Forces format to use msdos instead of ext4.
129 --reset-mbr
130 Sets the Master Boot Record (MBR) of the target storage device to the
131 mbr.bin file from the installation system's syslinux directory. This
132 may be helpful in recovering a damaged or corrupted device.
134 --efi
135 Creates a GUID partition table when --format is passed, and installs a
136 hybrid Extensible Firmware Interface (EFI)/MBR bootloader on the disk.
137 This is necessary for most Intel Macs.
139 --skipcopy
140 Skips the copying of the live image to the target device, bypassing the
141 actions of the --format, --overlay-size-mb, --home-size-mb, &
142 --swap-size-mb options, if present on the command line. (The --skipcopy
143 option may be used while testing the script, in order to avoid repeated
144 and lengthy copy commands, or to repair boot configuration files on a
145 previously installed device.)
147 --force
148 This option allows the installation script to bypass a delete
149 confirmation dialog in the event that a pre-existing LiveOS directory
150 is found on the target device.
152 --xo
153 Used to prepare an image for the OLPC XO-1 laptop with its compressed,
154 JFFS2 filesystem. Do not use the following options with --xo:
155 --overlay-size-mb <size>, home-size-mb <size>, --delete-home,
156 --compress
158 --xo-no-home
159 Used together with the --xo option to prepare an image for an OLPC XO
160 laptop with the home folder on an SD card instead of the internal flash
161 storage.
163 --timeout
164 Modifies the bootloader's timeout value, which indicates how long to
165 pause at the boot: prompt before booting automatically. This overrides
166 the value set during iso creation. Units are 1/10 s. The timeout is
167 canceled when any key is pressed, the assumption being that the user
168 will complete the command line. A timeout of zero will disable the
169 timeout completely.
171 --totaltimeout
172 Adds a bootloader totaltimeout, which indicates how long to wait before
173 booting automatically. This is used to force an automatic boot. This
174 timeout cannot be canceled by the user. Units are 1/10 s.
176 --extra-kernel-args <args>
177 Specifies additional kernel arguments, <args>, that will be inserted
178 into the syslinux and EFI boot configurations. Multiple arguments
179 should be specified in one string, i.e.,
180 --extra-kernel-args \"arg1 arg2 ...\"
182 --multi
183 Used when installing multiple image copies to signal configuration of
184 the boot files for the image in the --livedir <dir> parameter.
187 --livedir <dir>
188 Used with multiple image installations to designate the directory <dir>
189 for the particular image.
191 --compress (default state for the operating system files)
192 The default, compressed SquashFS filesystem image is copied on
193 installation. This option has no effect when the source filesystem is
194 already expanded.
196 --skipcompress (default option when --xo is specified)
197 Expands the source SquashFS image on installation into the read-only
198 /LiveOS/ext3fs.img filesystem image file.
200 --swap-size-mb <size>
201 Sets up a swap file of <size> mebibytes (integer values only) on the
202 target device.
204 --overlay-size-mb <size>
205 This option sets the overlay size in mebibytes (integer values only).
206 The overlay makes persistent storage available to the live operating
207 system, if the operating system supports it. The persistent LiveOS
208 overlay holds image-change snapshots (using write-once, difference-
209 tracking storage) in the /LiveOS/overlay-<device_id> file, which, *one
210 should note*, always grows in size due to the storage mechanism. (The
211 fraction of allocated space that has been consumed may be displayed by
212 issuing the 'dmsetup status' command in a terminal session of a running
213 LiveOS installation.) One way to conserve the unrecoverable, overlay
214 file space, is to specify a persistent home folder for user files, see
215 --home-size-mb below. The target storage device must have enough free
216 space for the image and the overlay. A maximum <size> of 2047 MiB is
217 permitted for vfat-formatted devices. If there is insufficient room on
218 your device, you will be given information to help in adjusting your
219 settings.
221 --home-size-mb <size>
222 Sets the home directory size in mebibytes (integer values only). A
223 persistent home directory will be made in the /LiveOS/home.img
224 filesystem image file. This file space is encrypted by default, but not
225 compressed (one may bypass encryption with the --unencrypted-home
226 installation option). Files in this home folder may be erased to
227 recover and reuse their storage space. The target storage device must
228 have enough free space for the image, any overlay, and the home
229 directory. Note that the --delete-home option must also be selected to
230 replace an existing persistent home with a new, empty one. A maximum
231 <size> of 2047 MiB is permitted for vfat-formatted devices. If there is
232 insufficient room on your device, you will be given information to help
233 in adjusting your settings.
235 --delete-home
236 To prevent unwitting deletion of user files, this option must be
237 explicitly selected when the option --home-size-mb <size> is selected
238 and there is an existing persistent home directory on the target device.
240 --crypted-home (default that only applies to new home-size-mb requests)
241 Specifies the default option to encrypt a new persistent home directory
242 if --home-size-mb <size> is specified.
244 --unencrypted-home
245 Prevents the default option to encrypt a new persistent home directory.
247 CONTRIBUTORS
249 livecd-iso-to-disk: David Zeuthen, Jeremy Katz, Douglas McClendon,
250 Chris Curran and other contributors.
251 (See the AUTHORS file in the source distribution for
252 the complete list of credits.)
254 BUGS
256 Report bugs to the mailing list
257 http://admin.fedoraproject.org/mailman/listinfo/livecd or directly to
258 Bugzilla http://bugzilla.redhat.com/bugzilla/ against the Fedora product,
259 and the livecd-tools component.
261 COPYRIGHT
263 Copyright (C) Fedora Project 2008, 2009, 2010 and various contributors.
264 This is free software. You may redistribute copies of it under the terms of
265 the GNU General Public License http://www.gnu.org/licenses/gpl.html.
266 There is NO WARRANTY, to the extent permitted by law.
268 SEE ALSO
270 livecd-creator, project website http://fedoraproject.org/wiki/FedoraLiveCD
272 exit 1
275 cleanup() {
276 sleep 2
277 [ -d "$SRCMNT" ] && umount $SRCMNT && rmdir $SRCMNT
278 [ -d "$TGTMNT" ] && umount $TGTMNT && rmdir $TGTMNT
281 exitclean() {
282 RETVAL=$?
283 if [ -d "$SRCMNT" ] || [ -d "$TGTMNT" ];
284 then
285 [ "$RETVAL" = 0 ] || echo "Cleaning up to exit..."
286 cleanup
288 exit $RETVAL
291 isdevloop() {
292 [ x"${1#/dev/loop}" != x"$1" ]
295 getdisk() {
296 DEV=$1
298 if isdevloop "$DEV"; then
299 device="$DEV"
300 return
303 p=$(udevadm info -q path -n $DEV)
304 if [ $? -gt 0 ]; then
305 echo "Error getting udev path to $DEV"
306 exitclean
308 if [ -e /sys/$p/device ]; then
309 device=$(basename /sys/$p)
310 else
311 device=$(basename $(readlink -f /sys/$p/../))
313 if [ ! -e /sys/block/$device -o ! -e /dev/$device ]; then
314 echo "Error finding block device of $DEV. Aborting!"
315 exitclean
318 device="/dev/$device"
319 # FIXME: weird dev names could mess this up I guess
320 p=/dev/$(basename $p)
321 partnum=${p##$device}
324 resetMBR() {
325 if isdevloop "$DEV"; then
326 return
328 getdisk $1
329 # if efi, we need to use the hybrid MBR
330 if [ -n "$efi" ]; then
331 if [ -f /usr/lib/syslinux/gptmbr.bin ]; then
332 cat /usr/lib/syslinux/gptmbr.bin > $device
333 elif [ -f /usr/share/syslinux/gptmbr.bin ]; then
334 cat /usr/share/syslinux/gptmbr.bin > $device
335 else
336 echo "Could not find gptmbr.bin (syslinux)"
337 exitclean
339 # Make it bootable on EFI and BIOS
340 parted -s $device set $partnum legacy_boot on
341 else
342 if [ -f /usr/lib/syslinux/mbr.bin ]; then
343 cat /usr/lib/syslinux/mbr.bin > $device
344 elif [ -f /usr/share/syslinux/mbr.bin ]; then
345 cat /usr/share/syslinux/mbr.bin > $device
346 else
347 echo "Could not find mbr.bin (syslinux)"
348 exitclean
353 checkMBR() {
354 if isdevloop "$DEV"; then
355 return 0
357 getdisk $1
359 bs=$(mktemp /tmp/bs.XXXXXX)
360 dd if=$device of=$bs bs=512 count=1 2>/dev/null || exit 2
362 mbrword=$(hexdump -n 2 $bs |head -n 1|awk {'print $2;'})
363 rm -f $bs
364 if [ "$mbrword" = "0000" ]; then
365 if [ -z "$format" ]; then
366 echo "MBR appears to be blank."
367 echo "Press Enter to replace the MBR and continue or ctrl-c to abort"
368 read
370 resetMBR $1
373 return 0
376 checkPartActive() {
377 dev=$1
378 getdisk $dev
380 # if we're installing to whole-disk and not a partition, then we
381 # don't need to worry about being active
382 if [ "$dev" = "$device" ]; then
383 return
385 if isdevloop "$DEV"; then
386 return
389 if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep -m1 $dev |awk {'print $2;'})" != "*" ]; then
390 echo "Partition isn't marked bootable!"
391 echo "You can mark the partition as bootable with "
392 echo " # /sbin/parted $device"
393 echo " (parted) toggle N boot"
394 echo " (parted) quit"
395 exitclean
399 checkLVM() {
400 dev=$1
402 if [ -x /sbin/pvs -a \
403 "$(/sbin/pvs -o vg_name --noheadings $dev* 2>/dev/null || :)" ]; then
404 echo "Device, $dev, contains a volume group and cannot be formated!"
405 echo "You can remove the volume group using vgremove."
406 exitclean
408 return 0
411 createGPTLayout() {
412 dev=$1
413 getdisk $dev
415 echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
416 echo "Press Enter to continue or ctrl-c to abort"
417 read
418 umount ${device}* &> /dev/null || :
419 wipefs -a ${device}
420 /sbin/parted --script $device mklabel gpt
421 partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit MB print" |grep ^$device:)
422 dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
423 p1_size=$(($dev_size - 3))
425 if [ $p1_size -le 0 ]; then
426 echo "Your device isn't big enough to hold $SRC"
427 echo "It is $(($p1_size * -1)) MB too small"
428 exitclean
430 p1_start=1
431 p1_end=$(($p1_size + 1))
432 /sbin/parted -s $device u MB mkpart '"EFI System Partition"' fat32 $p1_start $p1_end set 1 boot on
433 # Sometimes automount can be _really_ annoying.
434 echo "Waiting for devices to settle..."
435 /sbin/udevadm settle
436 sleep 5
437 TGTDEV=${device}1
438 umount $TGTDEV &> /dev/null || :
439 /sbin/mkdosfs -n LIVE $TGTDEV
440 TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
443 createMSDOSLayout() {
444 dev=$1
445 getdisk $dev
447 echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
448 echo "Press Enter to continue or ctrl-c to abort"
449 read
450 umount ${device}* &> /dev/null || :
451 wipefs -a ${device}
452 /sbin/parted --script $device mklabel msdos
453 partinfo=$(LC_ALL=C /sbin/parted --script -m $device "unit MB print" |grep ^$device:)
454 dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
455 p1_size=$(($dev_size - 3))
457 if [ $p1_size -le 0 ]; then
458 echo "Your device isn't big enough to hold $SRC"
459 echo "It is $(($p1_size * -1)) MB too small"
460 exitclean
462 p1_start=1
463 p1_end=$(($p1_size + 1))
464 /sbin/parted -s $device u MB mkpart primary fat32 $p1_start $p1_end set 1 boot on
465 # Sometimes automount can be _really_ annoying.
466 echo "Waiting for devices to settle..."
467 /sbin/udevadm settle
468 sleep 5
469 if ! isdevloop "$DEV"; then
470 TGTDEV=${device}1
471 else
472 TGTDEV=${device}
474 umount $TGTDEV &> /dev/null || :
475 /sbin/mkdosfs -n LIVE $TGTDEV
476 TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
479 createEXTFSLayout() {
480 dev=$1
481 getdisk $dev
483 echo "WARNING: THIS WILL DESTROY ANY DATA ON $device!!!"
484 echo "Press Enter to continue or ctrl-c to abort"
485 read
486 umount ${device}* &> /dev/null || :
487 wipefs -a ${device}
488 /sbin/parted -s $device mklabel msdos
489 partinfo=$(LC_ALL=C /sbin/parted -s -m $device "u MB print" |grep ^$device:)
490 dev_size=$(echo $partinfo |cut -d : -f 2 |sed -e 's/MB$//')
491 p1_size=$(($dev_size - 3))
493 if [ $p1_size -le 0 ]; then
494 echo "Your device isn't big enough to hold $SRC"
495 echo "It is $(($p1_size * -1)) MB too small"
496 exitclean
498 p1_start=1
499 p1_end=$(($p1_size + 1))
500 /sbin/parted -s $device u MB mkpart primary ext2 $p1_start $p1_end set 1 boot on
501 # Sometimes automount can be _really_ annoying.
502 echo "Waiting for devices to settle..."
503 /sbin/udevadm settle
504 sleep 5
505 TGTDEV=${device}1
506 umount $TGTDEV &> /dev/null || :
508 # Check extlinux version
509 if extlinux -v 2>&1 | grep -q 'extlinux 3'; then
510 mkfs=/sbin/mkfs.ext3
511 else
512 mkfs=/sbin/mkfs.ext4
514 $mkfs -L LIVE $TGTDEV
515 TGTLABEL="UUID=$(/sbin/blkid -s UUID -o value $TGTDEV)"
518 checkGPT() {
519 dev=$1
520 getdisk $dev
522 if [ "$(/sbin/fdisk -l $device 2>/dev/null |grep -c GPT)" -eq "0" ]; then
523 echo "EFI boot requires a GPT partition table."
524 echo "This can be done manually or you can run with --format"
525 exitclean
528 partinfo=$(LC_ALL=C /sbin/parted --script -m $device "print" |grep ^$partnum:)
529 volname=$(echo $partinfo |cut -d : -f 6)
530 flags=$(echo $partinfo |cut -d : -f 7)
531 if [ "$volname" != "EFI System Partition" ]; then
532 echo "Partition name must be 'EFI System Partition'"
533 echo "This can be set in parted or you can run with --reset-mbr"
534 exitclean
536 if [ "$(echo $flags |grep -c boot)" = "0" ]; then
537 echo "Partition isn't marked bootable!"
538 echo "You can mark the partition as bootable with "
539 echo " # /sbin/parted $device"
540 echo " (parted) toggle N boot"
541 echo " (parted) quit"
542 exitclean
546 checkFilesystem() {
547 dev=$1
549 TGTFS=$(/sbin/blkid -s TYPE -o value $dev || :)
550 if [ "$TGTFS" != "vfat" ] && [ "$TGTFS" != "msdos" ]; then
551 if [ "$TGTFS" != "ext2" ] && [ "$TGTFS" != "ext3" ] && [ "$TGTFS" != "ext4" ] && [ "$TGTFS" != "btrfs" ]; then
552 echo "Target filesystem ($dev:$TGTFS) must be vfat, ext[234] or btrfs"
553 exitclean
557 TGTLABEL=$(/sbin/blkid -s LABEL -o value $dev)
558 if [ "$TGTLABEL" != "LIVE" ]; then
559 if [ "$TGTFS" = "vfat" -o "$TGTFS" = "msdos" ]; then
560 /sbin/dosfslabel $dev LIVE
561 if [ $? -gt 0 ]; then
562 echo "dosfslabel failed on $dev, device not setup"
563 exitclean
565 elif [ "$TGTFS" = "ext2" -o "$TGTFS" = "ext3" -o "$TGTFS" = "ext4" ]; then
566 /sbin/e2label $dev LIVE
567 if [ $? -gt 0 ]; then
568 echo "e2label failed on $dev, device not setup"
569 exitclean
571 else
572 echo "Unknown filesystem type. Try setting its label to LIVE and re-running"
573 exitclean
577 # Use UUID if available
578 TGTUUID=$(/sbin/blkid -s UUID -o value $dev)
579 if [ -n "$TGTUUID" ]; then
580 TGTLABEL="UUID=$TGTUUID"
581 else
582 TGTLABEL="LABEL=LIVE"
585 if [ "$TGTFS" = "vfat" -o "$TGTFS" = "msdos" ]; then
586 mountopts="-o shortname=winnt,umask=0077"
590 checkSyslinuxVersion() {
591 if [ ! -x /usr/bin/syslinux ]; then
592 echo "You need to have syslinux installed to run this script"
593 exit 1
595 check=($(syslinux --version 2>&1)) || :
596 if [[ 'syslinux' != $check ]]; then
597 SYSLINUXPATH=""
598 elif [ -n "$multi" ]; then
599 SYSLINUXPATH="$LIVEOS/syslinux"
600 else
601 SYSLINUXPATH="syslinux"
605 checkMounted() {
606 dev=$1
607 if grep -q "^$dev " /proc/mounts ; then
608 echo "$dev is mounted, please unmount for safety"
609 exitclean
611 if grep -q "^$dev " /proc/swaps; then
612 echo "$dev is in use as a swap device, please disable swap"
613 exitclean
617 checkint() {
618 if ! test $1 -gt 0 2>/dev/null ; then
619 shortusage
620 exit 1
624 if [ $(id -u) != 0 ]; then
625 echo "You need to be root to run this script"
626 exit 1
629 detectsrctype() {
630 if [[ -e "$SRCMNT/Packages" ]]; then
631 echo "/Packages found, will copy source packages to target"
632 packages=1
634 if [[ -e "$SRCMNT/LiveOS/squashfs.img" ]]; then
635 # LiveOS style boot image
636 srctype=live
637 return
639 if [ -e $SRCMNT/images/install.img -o -e $SRCMNT/isolinux/initrd.img ]; then
640 if [ -n "$packages" ]; then
641 srctype=installer
642 else
643 srctype=netinst
645 imgtype=install
646 if [ ! -e $SRCMNT/images/install.img ]; then
647 echo "$SRC uses initrd.img w/o install.img"
648 imgtype=initrd
650 return
652 echo "ERROR: $SRC does not appear to be a Live image or DVD installer."
653 exitclean
656 cp_p() {
657 strace -q -ewrite cp -- "${1}" "${2}" 2>&1 \
658 | awk '{
659 count += $NF
660 if (count % 10 == 0) {
661 percent = count / total_size * 100
662 printf "%3d%% [", percent
663 for (i=0;i<=percent;i++)
664 printf "="
665 printf ">"
666 for (i=percent;i<100;i++)
667 printf " "
668 printf "]\r"
671 END { print "" }' total_size=$(stat -c '%s' "${1}") count=0
674 copyFile() {
675 if [ -x /usr/bin/rsync ]; then
676 rsync --inplace -P "$1" "$2"
677 return
679 if [ -x /usr/bin/gvfs-copy ]; then
680 gvfs-copy -p "$1" "$2"
681 return
683 if [ -x /usr/bin/strace -a -x /bin/awk ]; then
684 cp_p "$1" "$2"
685 return
687 cp "$1" "$2"
690 set -e
691 set -o pipefail
692 trap exitclean EXIT
693 shopt -s extglob
695 cryptedhome=1
696 keephome=1
697 homesizemb=0
698 swapsizemb=0
699 overlaysizemb=0
700 srctype=
701 imgtype=
702 packages=
703 LIVEOS=LiveOS
704 HOMEFILE="home.img"
706 if [[ "$*" =~ "--help" ]]; then
707 usage
709 while [ $# -gt 2 ]; do
710 case $1 in
711 --help)
712 usage
714 --noverify)
715 noverify=1
717 --format)
718 format=1
720 --msdos)
721 usemsdos=1
723 --reset-mbr|--resetmbr)
724 resetmbr=1
726 --efi|--mactel)
727 efi=1
729 --skipcopy)
730 skipcopy=1
732 --force)
733 force=1
735 --xo)
736 xo=1
737 skipcompress=1
739 --xo-no-home)
740 xonohome=1
742 --timeout)
743 checkint $2
744 timeout=$2
745 shift
747 --totaltimeout)
748 checkint $2
749 totaltimeout=$2
750 shift
752 --extra-kernel-args)
753 kernelargs=$2
754 shift
756 --multi)
757 multi=1
759 --livedir)
760 LIVEOS=$2
761 shift
763 --compress)
764 skipcompress=""
766 --skipcompress)
767 skipcompress=1
769 --swap-size-mb)
770 checkint $2
771 swapsizemb=$2
772 shift
774 --overlay-size-mb)
775 checkint $2
776 overlaysizemb=$2
777 shift
779 --home-size-mb)
780 checkint $2
781 homesizemb=$2
782 shift
784 --crypted-home)
785 cryptedhome=1
787 --unencrypted-home)
788 cryptedhome=""
790 --delete-home)
791 keephome=""
794 echo "invalid arg -- $1"
795 shortusage
796 exit 1
798 esac
799 shift
800 done
802 SRC=$(readlink -f "$1")
803 TGTDEV=$(readlink -f "$2")
805 if [ -z "$SRC" ]; then
806 echo "Missing source"
807 shortusage
808 exit 1
811 if [ ! -b "$SRC" -a ! -f "$SRC" ]; then
812 echo "$SRC is not a file or block device"
813 shortusage
814 exit 1
817 if [ -z "$TGTDEV" ]; then
818 echo "Missing target device"
819 shortusage
820 exit 1
823 if [ ! -b "$TGTDEV" ]; then
824 echo "$TGTDEV is not a block device"
825 shortusage
826 exit 1
829 if [ -z "$noverify" ]; then
830 # verify the image
831 echo "Verifying image..."
832 if ! checkisomd5 --verbose "$SRC"; then
833 echo "Are you SURE you want to continue?"
834 echo "Press Enter to continue or ctrl-c to abort"
835 read
839 # do some basic sanity checks.
840 checkMounted $TGTDEV
842 # FIXME: would be better if we had better mountpoints
843 SRCMNT=$(mktemp -d /media/srctmp.XXXXXX)
844 if [ -b "$SRC" ]; then
845 mount -o ro "$SRC" $SRCMNT || exitclean
846 elif [ -f "$SRC" ]; then
847 mount -o loop,ro "$SRC" $SRCMNT || exitclean
848 else
849 echo "$SRC is not a file or block device."
850 exitclean
852 # Figure out what needs to be done based on the source image
853 detectsrctype
855 # Format the device
856 if [ -n "$format" -a -z "$skipcopy" ]; then
857 checkLVM $TGTDEV
859 if [ -n "$efi" ]; then
860 createGPTLayout $TGTDEV
861 elif [ -n "$usemsdos" -o ! -x /sbin/extlinux ]; then
862 createMSDOSLayout $TGTDEV
863 else
864 createEXTFSLayout $TGTDEV
868 checkFilesystem $TGTDEV
869 if [ -n "$efi" ]; then
870 checkGPT $TGTDEV
873 checkSyslinuxVersion
874 # Because we can't set boot flag for EFI Protective on msdos partition tables
875 [ -z "$efi" ] && checkPartActive $TGTDEV
876 [ -n "$resetmbr" ] && resetMBR $TGTDEV
877 checkMBR $TGTDEV
880 if [ "$overlaysizemb" -gt 0 ]; then
881 if [ "$TGTFS" = "vfat" -a "$overlaysizemb" -gt 2047 ]; then
882 echo "Can't have an overlay of 2048MB or greater on VFAT"
883 exitclean
885 LABEL=$(/sbin/blkid -s LABEL -o value $TGTDEV)
886 if [[ "$LABEL" =~ ( ) ]]; then
887 echo "The LABEL($LABEL) on $TGTDEV has spaces in it, which do not work with the overlay"
888 echo "You can re-format or use dosfslabel/e2fslabel to change it"
889 exitclean
893 if [ "$homesizemb" -gt 0 -a "$TGTFS" = "vfat" ]; then
894 if [ "$homesizemb" -gt 2047 ]; then
895 echo "Can't have a home overlay greater than 2048MB on VFAT"
896 exitclean
900 if [ "$swapsizemb" -gt 0 -a "$TGTFS" = "vfat" ]; then
901 if [ "$swapsizemb" -gt 2047 ]; then
902 echo "Can't have a swap file greater than 2048MB on VFAT"
903 exitclean
907 TGTMNT=$(mktemp -d /media/tgttmp.XXXXXX)
908 mount $mountopts $TGTDEV $TGTMNT || exitclean
910 trap exitclean SIGINT SIGTERM
912 if [ -f "$TGTMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" -a "$homesizemb" -gt 0 ]; then
913 echo "ERROR: Requested keeping existing /home and specified a size for /home"
914 echo "Please either don't specify a size or specify --delete-home"
915 exitclean
918 if [ -n "$efi" ]; then
919 if [ -d $SRCMNT/EFI/BOOT ]; then
920 EFI_BOOT="/EFI/BOOT"
921 elif [ -d $SRCMNT/EFI/boot ]; then
922 EFI_BOOT="/EFI/boot"
923 else
924 echo "ERROR: This live image does not support EFI booting"
925 exitclean
929 # let's try to make sure there's enough room on the target device
930 if [[ -d $TGTMNT/$LIVEOS ]]; then
931 tbd=($(du -B 1M $TGTMNT/$LIVEOS))
932 if [[ -s $TGTMNT/$LIVEOS/$HOMEFILE ]] && [[ -n $keephome ]]; then
933 homesize=($(du -B 1M $TGTMNT/$LIVEOS/$HOMEFILE))
934 tbd=$((tbd - homesize))
936 else
937 tbd=0
940 if [[ live == $srctype ]]; then
941 targets="$TGTMNT/$SYSLINUXPATH"
942 [[ -n $efi ]] && targets+=" $TGTMNT$EFI_BOOT"
943 [[ -n $xo ]] && targets+=" $TGTMNT/boot/olpc.fth"
944 duTable=($(du -c -B 1M $targets 2> /dev/null || :))
945 tbd=$((tbd + ${duTable[*]: -2:1}))
948 if [[ -n $skipcompress ]] && [[ -s $SRCMNT/LiveOS/squashfs.img ]]; then
949 if mount -o loop $SRCMNT/LiveOS/squashfs.img $SRCMNT; then
950 livesize=($(du -B 1M --apparent-size $SRCMNT/LiveOS/ext3fs.img))
951 umount $SRCMNT
952 if ((livesize > 2048)) && [[ vfat == $TGTFS ]]; then
953 echo "
954 An uncompressed image size greater than 2048 MB is not suitable
955 for a VFAT-formatted device. The compressed SquashFS will be
956 copied to the target device.
958 skipcompress=""
959 livesize=0
961 else
962 echo "WARNING: --skipcompress or --xo was specified but the
963 currently-running kernel can not mount the SquashFS from the source
964 file to extract it. Instead, the compressed SquashFS will be copied
965 to the target device."
966 skipcompress=""
969 if [[ live == $srctype ]]; then
970 thisScriptpath=$(readlink -f "$0")
971 sources="$SRCMNT/LiveOS/ext3fs.img $SRCMNT/LiveOS/osmin.img"
972 [[ -z $skipcompress ]] && sources+=" $SRCMNT/LiveOS/squashfs.img"
973 sources+=" $SRCMNT/isolinux $SRCMNT/syslinux"
974 [[ -n $efi ]] && sources+=" $SRCMNT$EFI_BOOT"
975 [[ -n $xo ]] && sources+=" $SRCMNT/boot/olpc.fth"
976 duTable=($(du -c -B 1M "$thisScriptpath" $sources 2> /dev/null || :))
977 livesize=$((livesize + ${duTable[*]: -2:1}))
980 freespace=($(df -B 1M --total $TGTDEV))
981 freespace=${freespace[*]: -2:1}
983 if [[ live == $srctype ]]; then
984 tba=$((overlaysizemb + homesizemb + livesize + swapsizemb))
985 if ((tba > freespace + tbd)); then
986 needed=$((tba - freespace - tbd))
987 printf "\n The live image + overlay, home, & swap space, if requested,
988 \r will NOT fit in the space available on the target device.\n
989 \r + Size of live image: %10s MiB\n" $livesize
990 (($overlaysizemb > 0)) && \
991 printf " + Overlay size: %16s\n" $overlaysizemb
992 (($homesizemb > 0)) && \
993 printf " + Home directory size: %9s\n" $homesizemb
994 (($swapsizemb > 0)) && \
995 printf " + Swap overlay size: %11s\n" $swapsizemb
996 printf " = Total requested space: %6s MiB\n" $tba
997 printf " - Space available: %12s\n" $((freespace + tbd))
998 printf " ==============================\n"
999 printf " Space needed: %15s MiB\n\n" $needed
1000 printf " To fit the installation on this device,
1001 \r free space on the target, or decrease the
1002 \r requested size total by: %6s MiB\n\n" $needed
1003 exitclean
1007 # Verify available space for DVD installer
1008 if [ "$srctype" = "installer" ]; then
1009 if [ "$imgtype" = "install" ]; then
1010 imgpath=images/install.img
1011 else
1012 imgpath=isolinux/initrd.img
1014 installimgsize=$(du -s -B 1M $SRCMNT/$imgpath | awk {'print $1;'})
1016 tbd=0
1017 if [ -e $TGTMNT/$imgpath ]; then
1018 tbd=$(du -s -B 1M $TGTMNT/$imgpath | awk {'print $1;'})
1020 if [ -e "$TGTMNT/$(basename "$SRC")" ]; then
1021 tbd=$(($tbd + $(du -s -B 1M "$TGTMNT/$(basename "$SRC")" | awk {'print $1;'})))
1023 echo "Size of $imgpath: $installimgsize"
1024 echo "Available space: $((freespace + tbd))"
1025 if (( installimgsize > ((freespace + tbd)) )); then
1026 echo "ERROR: Unable to fit DVD image + install.img on available space on the target device."
1027 exitclean
1031 if [ -z "$skipcopy" ] && [ "$srctype" = "live" ]; then
1032 if [ -d $TGTMNT/$LIVEOS -a -z "$force" ]; then
1033 echo "Already set up as live image."
1034 if [ -z "$keephome" -a -e $TGTMNT/$LIVEOS/$HOMEFILE ]; then
1035 echo "WARNING: Persistent /home will be deleted!!!"
1036 echo "Press Enter to continue or ctrl-c to abort"
1037 read
1038 else
1039 echo "Deleting old OS in fifteen seconds..."
1040 sleep 15
1042 [ -e "$TGTMNT/$LIVEOS/$HOMEFILE" -a -n "$keephome" ] && mv $TGTMNT/$LIVEOS/$HOMEFILE $TGTMNT/$HOMEFILE
1045 rm -rf $TGTMNT/$LIVEOS
1049 # Bootloader is always reconfigured, so keep these out of the if skipcopy stuff.
1050 [ ! -d $TGTMNT/$SYSLINUXPATH ] && mkdir -p $TGTMNT/$SYSLINUXPATH
1051 [ -n "$efi" -a ! -d $TGTMNT$EFI_BOOT ] && mkdir -p $TGTMNT$EFI_BOOT
1053 # Live image copy
1054 if [ "$srctype" = "live" -a -z "$skipcopy" ]; then
1055 echo "Copying live image to target device."
1056 [ ! -d $TGTMNT/$LIVEOS ] && mkdir $TGTMNT/$LIVEOS
1057 [ -n "$keephome" -a -f "$TGTMNT/$HOMEFILE" ] && mv $TGTMNT/$HOMEFILE $TGTMNT/$LIVEOS/$HOMEFILE
1058 if [ -n "$skipcompress" -a -f $SRCMNT/LiveOS/squashfs.img ]; then
1059 mount -o loop $SRCMNT/LiveOS/squashfs.img $SRCMNT || exitclean
1060 copyFile $SRCMNT/LiveOS/ext3fs.img $TGTMNT/$LIVEOS/ext3fs.img || {
1061 umount $SRCMNT ; exitclean ; }
1062 umount $SRCMNT
1063 elif [ -f $SRCMNT/LiveOS/squashfs.img ]; then
1064 copyFile $SRCMNT/LiveOS/squashfs.img $TGTMNT/$LIVEOS/squashfs.img || exitclean
1065 elif [ -f $SRCMNT/LiveOS/ext3fs.img ]; then
1066 copyFile $SRCMNT/LiveOS/ext3fs.img $TGTMNT/$LIVEOS/ext3fs.img || exitclean
1068 if [ -f $SRCMNT/LiveOS/osmin.img ]; then
1069 copyFile $SRCMNT/LiveOS/osmin.img $TGTMNT/$LIVEOS/osmin.img || exitclean
1071 sync
1074 # Adjust syslinux sources for replication of installed images
1075 # between filesystem types.
1076 if [[ -d $SRCMNT/isolinux/ ]]; then
1077 cp $SRCMNT/isolinux/* $TGTMNT/$SYSLINUXPATH
1078 elif [[ -d $SRCMNT/syslinux/ ]]; then
1079 cp $SRCMNT/syslinux/* $TGTMNT/$SYSLINUXPATH
1080 if [[ -f $SRCMNT/syslinux/extlinux.conf ]]; then
1081 mv $TGTMNT/$SYSLINUXPATH/extlinux.conf \
1082 $TGTMNT/$SYSLINUXPATH/isolinux.cfg
1083 elif [[ -f $SRCMNT/syslinux/syslinux.cfg ]]; then
1084 mv $TGTMNT/$SYSLINUXPATH/syslinux.cfg $TGTMNT/$SYSLINUXPATH/isolinux.cfg
1087 BOOTCONFIG=$TGTMNT/$SYSLINUXPATH/isolinux.cfg
1088 # Set this to nothing so sed doesn't care
1089 BOOTCONFIG_EFI=
1090 if [ -n "$efi" ]; then
1091 echo "Setting up $EFI_BOOT"
1092 cp -r $SRCMNT$EFI_BOOT/* $TGTMNT$EFI_BOOT
1094 # The GRUB EFI config file can be one of:
1095 # boot?*.conf
1096 # BOOT?*.conf
1097 # grub.cfg
1098 if [ -e $TGTMNT$EFI_BOOT/grub.cfg ]; then
1099 BOOTCONFIG_EFI=$TGTMNT$EFI_BOOT/grub.cfg
1100 elif [ -e $TGTMNT$EFI_BOOT/+(BOOT|boot)?*.conf ]; then
1101 BOOTCONFIG_EFI=$TGTMNT$EFI_BOOT/+(BOOT|boot)?*.conf
1102 else
1103 echo "Unable to find EFI config file."
1104 exitclean
1106 rm -f $TGTMNT$EFI_BOOT/grub.conf
1108 # On some images (RHEL) the BOOT*.efi file isn't in $EFI_BOOT, but is in
1109 # the eltorito image, so try to extract it if it is missing
1111 # test for presence of *.efi grub binary
1112 if [ ! -f $TGTMNT$EFI_BOOT/+(BOOT|boot)?*.efi ]; then
1113 if [ ! -x /usr/bin/dumpet ]; then
1114 echo "No /usr/bin/dumpet tool found. EFI image will not boot."
1115 echo "Source media is missing grub binary in /EFI/BOOT/*efi"
1116 exitclean
1117 else
1118 # dump the eltorito image with dumpet, output is $SRC.1
1119 dumpet -i "$SRC" -d
1120 EFIMNT=$(mktemp -d /media/srctmp.XXXXXX)
1121 mount -o loop "$SRC".1 $EFIMNT
1123 if [ -f $EFIMNT$EFI_BOOT/+(BOOT|boot)?*.efi ]; then
1124 cp $EFIMNT$EFI_BOOT/+(BOOT|boot)?*.efi $TGTMNT$EFI_BOOT
1125 else
1126 echo "No BOOT*.efi found in eltorito image. EFI will not boot"
1127 umount $EFIMNT
1128 rm "$SRC".1
1129 exitclean
1131 umount $EFIMNT
1132 rm "$SRC".1
1137 # DVD installer copy
1138 if [ -z "$skipcopy" -a \( "$srctype" = "installer" -o "$srctype" = "netinst" \) ]; then
1139 echo "Copying DVD image to target device."
1140 mkdir -p $TGTMNT/images/
1141 if [ "$imgtype" = "install" ]; then
1142 for img in install.img updates.img product.img; do
1143 if [ -e $SRCMNT/images/$img ]; then
1144 copyFile $SRCMNT/images/$img $TGTMNT/images/$img || exitclean
1146 done
1150 # Copy packages over.
1151 # Before Fedora17 we could copy the .iso and setup a repo=
1152 # F17 and later look for repodata on the source media.
1153 # The presence of packages and LiveOS indicates F17 or later.
1154 if [ -n "$packages" -a -z "$skipcopy" ]; then
1155 if [ "$srctype" != "live" ]; then
1156 echo "Copying $SRC to device"
1157 copyFile "$SRC" "$TGTMNT/"
1159 # Setup a repo= to point to the .iso
1160 sed -i -e "s;initrd.img;initrd.img repo=hd:$TGTLABEL:/;g" $BOOTCONFIG
1161 if [ -n "$efi" ]; then
1162 sed -i -e "s;vmlinuz;vmlinuz repo=hd:$TGTLABEL:/;g" $BOOTCONFIG_EFI
1164 else
1165 echo "Copying package data from $SRC to device"
1166 rsync --inplace -rLDP --exclude EFI/ --exclude images/ --exclude isolinux/ \
1167 --exclude TRANS.TBL --exclude LiveOS/ "$SRCMNT/" "$TGTMNT/"
1169 echo "Waiting for device to finish writing"
1170 sync
1173 if [ "$srctype" = "live" ]; then
1174 # Copy this installer script.
1175 cp -fT "$thisScriptpath" $TGTMNT/$LIVEOS/livecd-iso-to-disk
1176 chmod +x $TGTMNT/$LIVEOS/livecd-iso-to-disk &> /dev/null || :
1178 # When the source is an installed Live USB/SD image, restore the boot config
1179 # file to a base state before updating.
1180 if [[ -d $SRCMNT/syslinux/ ]]; then
1181 echo "Preparing boot config file."
1182 sed -i -e "s/root=live:[^ ]*/root=live:CDLABEL=name/"\
1183 -e "s/\(r*d*.*live.*ima*ge*\) .* quiet/\1 quiet/"\
1184 $BOOTCONFIG $BOOTCONFIG_EFI
1185 sed -i -e "s/^timeout.*$/timeout\ 100/"\
1186 -e "/^totaltimeout.*$/d" $BOOTCONFIG
1191 echo "Updating boot config file"
1192 # adjust label and fstype
1193 sed -i -e "s/CDLABEL=[^ ]*/$TGTLABEL/" -e "s/rootfstype=[^ ]*/rootfstype=$TGTFS/" -e "s/LABEL=[^ ]*/$TGTLABEL/" $BOOTCONFIG $BOOTCONFIG_EFI
1194 if [ -n "$kernelargs" ]; then
1195 sed -i -e "s;initrd.\?\.img;& ${kernelargs};" $BOOTCONFIG
1196 if [ -n "$efi" ]; then
1197 sed -i -e "s;vmlinuz.\?;& ${kernelargs} ;" $BOOTCONFIG_EFI
1200 if [ "$LIVEOS" != "LiveOS" ]; then
1201 sed -i -e "s;r*d*.*live.*ima*ge*;& live_dir=$LIVEOS;"\
1202 $BOOTCONFIG $BOOTCONFIG_EFI
1205 # EFI images are in $SYSLINUXPATH now
1206 if [ -n "$efi" ]; then
1207 sed -i -e "s;/isolinux/;/$SYSLINUXPATH/;g" $BOOTCONFIG_EFI
1208 sed -i -e "s;/images/pxeboot/;/$SYSLINUXPATH/;g" $BOOTCONFIG_EFI
1209 sed -i -e "s;findiso;;g" $BOOTCONFIG_EFI
1212 # DVD Installer for netinst
1213 if [ "$srctype" != "live" ]; then
1214 if [ "$imgtype" = "install" ]; then
1215 sed -i -e "s;initrd.img;initrd.img stage2=hd:$TGTLABEL:/images/install.img;g" $BOOTCONFIG
1216 if [ -n "$efi" ]; then
1217 sed -i -e "s;vmlinuz;vmlinuz stage2=hd:$TGTLABEL:/images/install.img;g" $BOOTCONFIG_EFI
1219 else
1220 # The initrd has everything, so no stage2
1221 sed -i -e "s;stage2=\S*;;g" $BOOTCONFIG $BOOTCONFIG_EFI
1225 # Adjust the boot timeouts
1226 if [ -n "$timeout" ]; then
1227 sed -i -e "s/^timeout.*$/timeout\ $timeout/" $BOOTCONFIG
1229 if [ -n "$totaltimeout" ]; then
1230 sed -i -e "/^timeout.*$/a\totaltimeout\ $totaltimeout" $BOOTCONFIG
1233 if [ "$overlaysizemb" -gt 0 ]; then
1234 echo "Initializing persistent overlay file"
1235 OVERFILE="overlay-$( /sbin/blkid -s LABEL -o value $TGTDEV )-$( /sbin/blkid -s UUID -o value $TGTDEV )"
1236 if [ -z "$skipcopy" ]; then
1237 if [ "$TGTFS" = "vfat" ]; then
1238 # vfat can't handle sparse files
1239 dd if=/dev/zero of=$TGTMNT/$LIVEOS/$OVERFILE count=$overlaysizemb bs=1M
1240 else
1241 dd if=/dev/null of=$TGTMNT/$LIVEOS/$OVERFILE count=1 bs=1M seek=$overlaysizemb
1244 sed -i -e "s/r*d*.*live.*ima*ge*/& overlay=${TGTLABEL}/"\
1245 $BOOTCONFIG $BOOTCONFIG_EFI
1246 sed -i -e "s/\ ro\ /\ rw\ /" $BOOTCONFIG $BOOTCONFIG_EFI
1249 if [ "$swapsizemb" -gt 0 -a -z "$skipcopy" ]; then
1250 echo "Initializing swap file"
1251 dd if=/dev/zero of=$TGTMNT/$LIVEOS/swap.img count=$swapsizemb bs=1M
1252 mkswap -f $TGTMNT/$LIVEOS/swap.img
1255 if [ "$homesizemb" -gt 0 -a -z "$skipcopy" ]; then
1256 echo "Initializing persistent /home"
1257 homesource=/dev/zero
1258 [ -n "$cryptedhome" ] && homesource=/dev/urandom
1259 if [ "$TGTFS" = "vfat" ]; then
1260 # vfat can't handle sparse files
1261 dd if=${homesource} of=$TGTMNT/$LIVEOS/$HOMEFILE count=$homesizemb bs=1M
1262 else
1263 dd if=/dev/null of=$TGTMNT/$LIVEOS/$HOMEFILE count=1 bs=1M seek=$homesizemb
1265 if [ -n "$cryptedhome" ]; then
1266 loop=$(losetup -f)
1267 losetup $loop $TGTMNT/$LIVEOS/$HOMEFILE
1269 echo "Encrypting persistent /home"
1270 while ! cryptsetup luksFormat -y -q $loop; do :; done;
1272 echo "Please enter the password again to unlock the device"
1273 while ! cryptsetup luksOpen $loop EncHomeFoo; do :; done;
1275 mkfs.ext4 -j /dev/mapper/EncHomeFoo
1276 tune2fs -c0 -i0 -ouser_xattr,acl /dev/mapper/EncHomeFoo
1277 sleep 2
1278 cryptsetup luksClose EncHomeFoo
1279 losetup -d $loop
1280 else
1281 echo "Formatting unencrypted /home"
1282 mkfs.ext4 -F -j $TGTMNT/$LIVEOS/$HOMEFILE
1283 tune2fs -c0 -i0 -ouser_xattr,acl $TGTMNT/$LIVEOS/$HOMEFILE
1287 # create the forth files for booting on the XO if requested
1288 # we'd do this unconditionally, but you have to have a kernel that will
1289 # boot on the XO anyway.
1290 if [ -n "$xo" ]; then
1291 echo "Setting up /boot/olpc.fth file"
1292 args=$(grep "^ *append" $TGTMNT/$SYSLINUXPATH/isolinux.cfg |head -n1 |sed -e 's/.*initrd=[^ ]*//')
1293 if [ -z "$xonohome" -a ! -f $TGTMNT/$LIVEOS/$HOMEFILE ]; then
1294 args="$args persistenthome=mtd0"
1296 args="$args reset_overlay"
1297 xosyspath=$(echo $SYSLINUXPATH | sed -e 's;/;\\;')
1298 if [ ! -d $TGTMNT/boot ]; then
1299 mkdir -p $TGTMNT/boot
1301 cat > $TGTMNT/boot/olpc.fth <<EOF
1302 \ Boot script for USB boot
1303 hex rom-pa fffc7 + 4 \$number drop h# 2e19 < [if]
1304 patch 2drop erase claim-params
1305 : high-ramdisk ( -- )
1306 cv-load-ramdisk
1307 h# 22c +lp l@ 1+ memory-limit umin /ramdisk - ffff.f000 and ( new-ramdisk-adr )
1308 ramdisk-adr over /ramdisk move ( new-ramdisk-adr )
1309 to ramdisk-adr
1311 ' high-ramdisk to load-ramdisk
1312 [then]
1314 : set-bootpath-dev ( -- )
1315 " /chosen" find-package if ( phandle )
1316 " bootpath" rot get-package-property 0= if ( propval$ )
1317 get-encoded-string ( bootpath$ )
1318 [char] \ left-parse-string 2nip ( dn$ )
1319 dn-buf place ( )
1320 then
1321 then
1323 " /sd" dn-buf count sindex 0>= if
1324 " sd:"
1325 else
1326 " u:"
1327 then
1328 " BOOTPATHDEV" \$set-macro
1331 set-bootpath-dev
1332 " $args" to boot-file
1333 " \${BOOTPATHDEV}$xosyspath\initrd0.img" expand$ to ramdisk
1334 " \${BOOTPATHDEV}$xosyspath\vmlinuz0" expand$ to boot-device
1335 unfreeze
1336 boot
1341 if [ -z "$multi" ]; then
1342 echo "Installing boot loader"
1343 if [ -n "$efi" ]; then
1344 # replace the ia32 hack
1345 if [ -f "$TGTMNT$EFI_BOOT/BOOT.conf" ]; then
1346 cp -f $TGTMNT$EFI_BOOT/BOOTia32.conf $TGTMNT$EFI_BOOT/BOOT.conf
1350 # this is a bit of a kludge, but syslinux doesn't guarantee the API for its com32 modules :/
1351 if [ -f $TGTMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/share/syslinux/vesamenu.c32 ]; then
1352 cp /usr/share/syslinux/vesamenu.c32 $TGTMNT/$SYSLINUXPATH/vesamenu.c32
1353 elif [ -f $TGTMNT/$SYSLINUXPATH/vesamenu.c32 -a -f /usr/lib/syslinux/vesamenu.c32 ]; then
1354 cp /usr/lib/syslinux/vesamenu.c32 $TGTMNT/$SYSLINUXPATH/vesamenu.c32
1355 elif [ -f $TGTMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/share/syslinux/menu.c32 ]; then
1356 cp /usr/share/syslinux/menu.c32 $TGTMNT/$SYSLINUXPATH/menu.c32
1357 elif [ -f $TGTMNT/$SYSLINUXPATH/menu.c32 -a -f /usr/lib/syslinux/menu.c32 ]; then
1358 cp /usr/lib/syslinux/menu.c32 $TGTMNT/$SYSLINUXPATH/menu.c32
1361 if [ "$TGTFS" == "vfat" -o "$TGTFS" == "msdos" ]; then
1362 # syslinux expects the config to be named syslinux.cfg
1363 # and has to run with the file system unmounted
1364 mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg $TGTMNT/$SYSLINUXPATH/syslinux.cfg
1365 # deal with mtools complaining about ldlinux.sys
1366 if [ -f $TGTMNT/$SYSLINUXPATH/ldlinux.sys ]; then
1367 rm -f $TGTMNT/$SYSLINUXPATH/ldlinux.sys
1369 cleanup
1370 if [ -n "$SYSLINUXPATH" ]; then
1371 syslinux -d $SYSLINUXPATH $TGTDEV
1372 else
1373 syslinux $TGTDEV
1375 elif [ "$TGTFS" == "ext2" -o "$TGTFS" == "ext3" -o "$TGTFS" == "ext4" -o "$TGTFS" == "btrfs" ]; then
1376 # extlinux expects the config to be named extlinux.conf
1377 # and has to be run with the file system mounted
1378 mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg $TGTMNT/$SYSLINUXPATH/extlinux.conf
1379 extlinux -i $TGTMNT/$SYSLINUXPATH
1380 # Starting with syslinux 4 ldlinux.sys is used on all file systems.
1381 if [ -f "$TGTMNT/$SYSLINUXPATH/extlinux.sys" ]; then
1382 chattr -i $TGTMNT/$SYSLINUXPATH/extlinux.sys
1383 elif [ -f "$TGTMNT/$SYSLINUXPATH/ldlinux.sys" ]; then
1384 chattr -i $TGTMNT/$SYSLINUXPATH/ldlinux.sys
1386 cleanup
1388 else
1389 # we need to do some more config file tweaks for multi-image mode
1390 sed -i -e "s;kernel vm;kernel /$LIVEOS/syslinux/vm;" $TGTMNT/$SYSLINUXPATH/isolinux.cfg
1391 sed -i -e "s;initrd=i;initrd=/$LIVEOS/syslinux/i;" $TGTMNT/$SYSLINUXPATH/isolinux.cfg
1392 mv $TGTMNT/$SYSLINUXPATH/isolinux.cfg $TGTMNT/$SYSLINUXPATH/syslinux.cfg
1393 cleanup
1396 echo "Target device is now set up with a Live image!"