Skip to content

Instantly share code, notes, and snippets.

@il-katta
Created August 6, 2012 16:53
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save il-katta/3276545 to your computer and use it in GitHub Desktop.
Boot Fedora Live from ISO file using grub2
#!/bin/sh
#
# fedora-fromiso - Patch the ramdisk of Fedora to allow booting from
# ISO image
#
# Copyright (C) 2012 Mansour <mansour@oxplot.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Example:
#
# Let's say Fedora ISO file is located at ~/fedora.iso
# Then the following will generate a patched ramdisk which we will use
# later to boot from ISO (run as root or sudo):
#
# $ ./fedora-fromiso ~/fedora.iso ~/initrd-fromiso
#
# Let's also assume the following layout of your final boot media:
#
# /
# /fedora.iso
# /initrd-fromiso (generated by this script earlier)
#
# Then the following grub2 menu entry will boot DSL from the ISO file:
#
# menuentry "Fedora Live" {
# loopback loop /fedora.iso
# linux (loop)/EFI/boot/vmlinuz0 root=live:/fedora.iso rootfstype=auto ro liveimg quiet rhgb rd.luks=0 rd.md=0
# initrd /initrd-fromiso
# }
#
# fork by il-Katta <ilkatta88@gmail.com>
#
# Parse command line arguments
ISOPATH="$1"
OUTPATH="$2"
if [ -z "$ISOPATH" ]; then
echo "Usage $0: <iso-path> [<out>]"
exit 1
fi
# Mount ISO and extract initrd
ISOMNT=$(mktemp -d /tmp/tmpXXXXXX)
if mount -t iso9660 -o ro,loop "$ISOPATH" "$ISOMNT"
then
INITRDPATH=
TMPHOLD=$(mktemp -d /tmp/tmpXXXXXX)
if [ -e "$ISOMNT"/EFI/boot/initrd0.img ] ; then
INITRDPATH="/EFI/boot"
gzip -d < "$ISOMNT"/EFI/boot/initrd0.img > "$TMPHOLD"/initrd
else
if [ -e "$ISOMNT"/isolinux/initrd0.img ] ; then
INITRDPATH="/isolinux"
gzip -d < "$ISOMNT"/isolinux/initrd0.img > "$TMPHOLD"/initrd
else
echo "ERROR!! file initrd0.img not found"
umount "$ISOMNT"
exit 1
fi
fi
umount "$ISOMNT"
INITDIR=$(mktemp -d /tmp/tmpXXXXXX)
(cd $INITDIR; cpio -id < "$TMPHOLD"/initrd)
# Patch relevant files to handle live:/*.iso boot parameter
patch -d "$INITDIR" -p1 <<"EOF"
diff -Naur a/init b/init
--- a/init 2012-03-20 16:30:32.028407329 +1100
+++ b/init 2012-03-20 06:44:45.471723446 +1100
@@ -439,6 +439,11 @@
mount --bind /run/initramfs "$NEWRUN"
fi
+# move isodevice mount to new spot
+
+mkdir -p "$NEWROOT/isodevice"
+mount --move /isodevice "$NEWROOT/isodevice"
+
wait_for_loginit
# remove helper symlink
diff -Naur a/lib/dracut/hooks/pre-udev/30dmsquash-liveiso-genrules.sh b/lib/dracut/hooks/pre-udev/30dmsquash-liveiso-genrules.sh
--- a/lib/dracut/hooks/pre-udev/30dmsquash-liveiso-genrules.sh 2012-03-20 16:30:32.072406888 +1100
+++ b/lib/dracut/hooks/pre-udev/30dmsquash-liveiso-genrules.sh 2012-03-20 02:00:36.163756463 +1100
@@ -3,7 +3,7 @@
# ex: ts=8 sw=4 sts=4 et filetype=sh
if [ "${root%%:*}" = "liveiso" ]; then
{
- printf 'KERNEL=="loop0", RUN+="/sbin/initqueue --settled --onetime --unique /sbin/dmsquash-live-root `/sbin/losetup -f --show %s`"\n' \
+ printf 'KERNEL=="loop0", RUN+="/sbin/initqueue --settled --onetime --unique /sbin/dmsquash-live-root `/sbin/liveiso-find %s`"\n' \
${root#liveiso:}
} >> /etc/udev/rules.d/99-liveiso-mount.rules
echo '[ -e /dev/root ]' > $hookdir/initqueue/finished/dmsquash.sh
diff -Naur a/sbin/liveiso-find b/sbin/liveiso-find
--- a/sbin/liveiso-find 1970-01-01 10:00:00.000000000 +1000
+++ b/sbin/liveiso-find 2012-03-20 06:35:30.634222494 +1100
@@ -0,0 +1,24 @@
+#!/bin/sh
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+
+[ -z "$1" ] && exit 1
+isopath="$1"
+
+# try all the block devices under /dev and attempt to mount them
+
+mkdir -p /isodevice
+ls -l /dev/ | grep '^b' | grep -o '[a-z0-9-]\+$' | grep -v loop | while read device; do
+ device_fs=`blkid -s TYPE -o value "/dev/$device"`
+ [ -z "$device_fs" ] && continue
+ if mount -t "$device_fs" -o ro "/dev/$device" /isodevice; then
+ if [ -f "/isodevice$isopath" ]; then
+ losetup /dev/loop5 "/isodevice$isopath"
+ echo /dev/loop5
+ exit 0
+ else
+ umount /isodevice
+ fi
+ fi
+done
+rmdir /isodevice
EOF
chmod +x "$INITDIR/sbin/liveiso-find"
test -z "$OUTPATH" && OUTPATH="initrd-fromiso"
(
cd "$INITDIR";
echo './init
./sbin/liveiso-find
./lib/dracut/hooks/pre-udev/30dmsquash-liveiso-genrules.sh' |
cpio -o -H newc -A -F "$TMPHOLD"/initrd
)
gzip -9 < "$TMPHOLD"/initrd > "$OUTPATH"
rm -Rf "$INITDIR"
rm "$TMPHOLD"/initrd
rmdir "$TMPHOLD"
cat <<MEOF
add:
menuentry "Fedora Live ( $(basename $ISOPATH) )" {
loopback loop /$(basename $ISOPATH)
linux (loop)${INITRDPATH}/vmlinuz0 root=live:/$(basename $ISOPATH) rootfstype=auto ro liveimg quiet rhgb rd.luks=0 rd.md=0
initrd /$(basename $OUTPATH)
}
to your grub.cfg
MEOF
fi
rmdir "$ISOMNT"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment