# # mk-images.efi # # Copyright (C) 2007 Red Hat, Inc. All rights reserved. # # 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; either version 2 of the License, or # (at your option) any later version. # # 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # makeefibootdisk() { partimg=$1 && shift target=$1 && shift if [ ! -f $1 ]; then return fi local partsize=$(/bin/ls -l $partimg | awk '{ print $5; }') local disksize=$((17408 + $partsize + 17408)) disksize=$(($disksize + $(($disksize % 512)))) local diskimg=$(mktemp /tmp/efidisk.img.XXXXXX) dd if=/dev/zero of=$diskimg count=1 bs=$disksize MAKEDEV /dev/loop local loop=$(losetup -v -f $diskimg | awk '{ print $4 }') echo "loop is $loop" ls -l $loop dmsetup create efiboot$$ --table "0 $(($disksize / 512)) linear $loop 0" dmsetup mknodes efiboot$$ echo "efiboot$$ should exist" ls -l /dev/mapper/efiboot$$* parted --script /dev/mapper/efiboot$$ mklabel gpt unit b mkpart '"EFI System Partition"' fat32 17408 $((17408 + $partsize)) set 1 boot on dmsetup mknodes efiboot$$p1 || : echo "efiboot$$p1 should exist" ls -l /dev/mapper/efiboot$$* dmsetup ls dmsetup table dd if=$partimg of=/dev/mapper/efiboot$$p1 echo "dd-ing $partimg to /dev/mapper/efiboot$$p1" # the next two lines seem to depend on the exact version of parted :/ dmsetup remove -f /dev/mapper/efiboot$$p1 || : dmsetup remove -f /dev/mapper/efiboot$$ losetup -d $loop mv -v $diskimg $target chmod a+r $target } #makeefibootimage required for EFI bootloader dosfs image makeefibootimage() { echo "in makeefibootimage: makeefibootimage $@" MBD_FILENAME="" KERNELFILE="" INITRDFILE="" grubpkg="" MBD_TMPIMAGE=${TMPDIR:-/tmp}/makebootdisk.image.$$ MBD_BOOTTREE=${TMPDIR:-/tmp}/makebootdisk.tree.$$ MBD_BOOTTREE_TMP=$MBD_BOOTTREE'_tmp' while [ x$(echo $1 | cut -c1-2) = x"--" ]; do if [ $1 = "--kernel" ]; then KERNELFILE=$2 shift; shift continue elif [ $1 = "--kernelpath" ]; then KERNELPATH=$2 shift; shift continue elif [ $1 = "--initrd" ]; then INITRDFILE=$2 shift; shift continue elif [ $1 = "--initrdpath" ]; then INITRDPATH=$2 shift; shift continue elif [ $1 = "--imagename" ]; then MBD_FILENAME=$IMAGEPATH/$2 shift; shift continue elif [ $1 = "--grubpkg" ]; then grubpkg=$2 echo "grubpkg=$grubpkg" shift; shift continue fi echo "Unknown option passed to makebootdisk: \"$1\"" exit 1 done if [ -z "$MBD_FILENAME" ]; then echo "No imagename passed" exit 1 fi MBD_FSIMAGE="$INITRDFILE" mkdir -p $MBD_BOOTTREE mkdir -p $MBD_BOOTTREE_TMP rm -rf $MBD_BOOTTREE_TMP mkdir -p $MBD_TMPIMAGE # provided by the mk-image.$ARCH file prepareEfiImage left=$(df $MBD_BOOTTREE | tail -n1) left=$(echo $left | awk '{print $4'}) umount $MBD_BOOTTREE if [ -n "$EXTRAKERNELPATH" ]; then mkdir -p `dirname $EXTRAKERNELPATH` cp -f $KERNELROOT/$KERNELDIR/${KERNELNAME}-* $EXTRAKERNELPATH fi mkdir -p `dirname $MBD_FILENAME` rm -rf $MBD_TMPIMAGE $MBD_MNTPOINT $MBD_BOOTTREE if [ -z "$INITRDFILE" -a -n "$MBD_FSIMAGE" ]; then rm -f $MBD_FSIMAGE fi chmod a+r $MBD_FILENAME echo "Wrote $MBD_FILENAME (${left}k free)" } # prepare and build an efiboot.img. prepareEfiImage() { echo "in prepareEfiImage" prepareEfiTree || return 1 # dynamically calculate the size of the dosfs BOOTDISKSIZE=$(du -kcs $MBD_BOOTTREE_TMP | tail -n1 | awk '{print $1}') BOOTDISKSIZE=$(expr $BOOTDISKSIZE + 100) echo "The size of the efiboot.img dosfs is ${BOOTDISKSIZE}k" mkdosfs -n ANACONDA -C $MBD_FILENAME $BOOTDISKSIZE >/dev/null mount -o loop,shortname=winnt,umask=0077 -t vfat $MBD_FILENAME $MBD_BOOTTREE cp -R $MBD_BOOTTREE_TMP/* $MBD_BOOTTREE } # prepare a directory with the kernel, initrd, and various message files # used to populate the efi boot image prepareEfiTree() { echo "in prepareEfiTree" mkdir -p $MBD_BOOTTREE_TMP/EFI/BOOT cp -av $BOOTDISKDIR/*.conf $MBD_BOOTTREE_TMP/EFI/BOOT/ [ -n "$KERNELFILE" ] && cp -av $KERNELFILE $MBD_BOOTTREE_TMP/EFI/BOOT/vmlinuz [ -n "$INITRDFILE" ] && cp -av $INITRDFILE $MBD_BOOTTREE_TMP/EFI/BOOT/initrd.img [ -z "$KERNELPATH" ] && KERNELPATH="/EFI/BOOT/vmlinuz" [ -z "$INITRDPATH" ] && INITRDPATH="/EFI/BOOT/initrd.img" SPLASHPATH="/EFI/BOOT/splash.xpm.gz" sed -e "s/@PRODUCT@/$PRODUCT/g" \ -e "s/@VERSION@/$VERSION/g" \ -e "s,@KERNELPATH@,$KERNELPATH,g" \ -e "s,@INITRDPATH@,$INITRDPATH,g" \ -e "s,@SPLASHPATH@,$SPLASHPATH,g" \ -i $MBD_BOOTTREE_TMP/EFI/BOOT/grub.conf ydcmd="yumdownloader -c $yumconf $grubpkg" echo "(grubpkg) $ydcmd" $ydcmd rpm_verify $grubpkg.rpm || exit 1 rpm2cpio $grubpkg.rpm | (cd $KERNELROOT; cpio --quiet -iumd) cp -av $KERNELROOT/boot/efi/EFI/redhat/grub.efi $MBD_BOOTTREE_TMP/EFI/BOOT/grub.efi # The first generation Mactel machines get the bootloader name wrong # as per the spec. Awesome, guys. if [ "$efiarch" == "ia32" ]; then cp -av $MBD_BOOTTREE_TMP/EFI/BOOT/grub.efi $MBD_BOOTTREE_TMP/EFI/BOOT/BOOT.efi cp -av $MBD_BOOTTREE_TMP/EFI/BOOT/grub.conf $MBD_BOOTTREE_TMP/EFI/BOOT/BOOT.conf fi local tmpefiarch=${efiarch} case ${efiarch} in x64) tmpefiarch="X64" ;; ia32) tmpefiarch="IA32" ;; esac mv -v $MBD_BOOTTREE_TMP/EFI/BOOT/grub.efi $MBD_BOOTTREE_TMP/EFI/BOOT/BOOT${tmpefiarch}.efi mv -v $MBD_BOOTTREE_TMP/EFI/BOOT/grub.conf $MBD_BOOTTREE_TMP/EFI/BOOT/BOOT${tmpefiarch}.conf artpkg=$(repoquery --qf "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}" -c $yumconf --whatprovides ${brandpkgname}-logos | grep -v generic-logos | head -1) if [ -z "$artpkg" ]; then artpkg="generic-logos" fi ydcmd="yumdownloader -c ${yumconf} ${artpkg}" echo "(artpkg) $ydcmd" $ydcmd rpm_verify ${artpkg}.rpm || exit 1 rpm2cpio ${artpkg}.rpm | (cd $KERNELROOT; cpio --quiet -iumd) cp -av $KERNELROOT/boot/grub/splash.xpm.gz $MBD_BOOTTREE_TMP/$SPLASHPATH # if we don't have a kernel or initrd, we're making a CD image and we need # to mirror EFI/ to the cd. if [ -z "$KERNELFILE" -a -z "$INITRDFILE" ]; then cp -av $MBD_BOOTTREE_TMP/EFI/ $TOPDESTPATH/EFI/ rm -f $TOPDESTPATH/EFI/BOOT/*.efi fi } makeEfiImages() { echo "in makeEfiImages" yumconf="$1" echo "Making EFI images ($PWD)" if [ "$kernelvers" != "$kernelxen" ]; then local grubarch=${efiarch} case ${efiarch} in ia32) grubarch=i?86 ;; x64) grubarch=x86_64 ;; esac grubpkg=$(repoquery --qf "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}" -c $yumconf grub.$grubarch) if [ -z "$grubpkg" ]; then echo "cannot find package grub.$grubarch" >&2 return 1 fi echo "Building efiboot.img for ${efiarch}/$KERNELARCH at $TOPDESTPATH/images/efiboot.img" echo "grubpkg: ${grubpkg}" makeefibootimage \ --imagename efiboot.img \ --kernel $TOPDESTPATH/images/pxeboot/vmlinuz \ --initrd $TOPDESTPATH/images/pxeboot/initrd.img \ --grubpkg ${grubpkg} local ret=$? if [ $ret -ne 0 ]; then echo "makeefibootimage (1) failed" >&2 return $ret fi makeefibootdisk $TOPDESTPATH/images/efiboot.img $TOPDESTPATH/images/efidisk.img local ret=$? [ $ret -eq 0 ] || return $ret rm -vf $TOPDESTPATH/images/efiboot.img # make a boot image with just boot*.efi in it... makeefibootimage \ --imagename efiboot.img \ --kernelpath /images/pxeboot/vmlinuz \ --initrdpath /images/pxeboot/initrd.img \ --grubpkg ${grubpkg} local ret=$? if [ $ret -ne 0 ]; then echo "makeefibootimage (2) failed" >&2 fi return $ret fi return 0 }