#!/bin/bash # # 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 target=$2 local partsize=$(ls -l $1 | 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 local loop=$(losetup -v -f $diskimg | awk '{ print $4 }') dmsetup create efiboot$$ --table "0 $(($disksize / 512)) linear $loop 0" parted --script /dev/mapper/efiboot$$ mklabel gpt unit b mkpart '"EFI System Partition"' fat32 17408 $((17408 + $partsize)) set 1 boot on dd if=$partimg of=/dev/mapper/efiboot$$p1 dmsetup remove /dev/mapper/efiboot$$p1 dmsetup remove /dev/mapper/efiboot$$ losetup -d $loop mv -v $diskimg $target chmod a+r $target } #makeefibootimage required for EFI bootloader dosfs image 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 = "--initrd" ]; then INITRDFILE=$2 shift; shift continue elif [ $1 = "--imagename" ]; then MBD_FILENAME=$IMAGEPATH/$2 shift; shift continue elif [ $1 = "--grubpkg" ]; then grubpkg=$2 shift; shift continue fi echo "Unknown option passed to makebootdisk" exit 1 done if [ -z "$MBD_FILENAME" ]; then echo "No imagename passed" exit 1 fi if [ -z "$KERNELFILE" ]; then echo "No kernel file passed" exit 1 fi if [ -z "$INITRDFILE" ]; then echo "No initrd file 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" ]; 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() { 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" 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() { mkdir -p $MBD_BOOTTREE_TMP/EFI/boot cp -a $BOOTDISKDIR/* $MBD_BOOTTREE_TMP/EFI/boot/ cp $INITRDFILE $MBD_BOOTTREE_TMP/EFI/boot/initrd.img cp $KERNELFILE $MBD_BOOTTREE_TMP/EFI/boot/vmlinuz sed -i "s/@PRODUCT@/$PRODUCT/g" $MBD_BOOTTREE_TMP/EFI/boot/grub.conf sed -i "s/@VERSION@/$VERSION/g" $MBD_BOOTTREE_TMP/EFI/boot/grub.conf yumdownloader -c $yumconf $grubpkg rpm2cpio $grubpkg.rpm | (cd $KERNELROOT; cpio --quiet -iumd) cp $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 $MBD_BOOTTREE_TMP/EFI/boot/grub.efi $MBD_BOOTTREE_TMP/EFI/boot/boot.efi cp $MBD_BOOTTREE_TMP/EFI/boot/grub.conf $MBD_BOOTTREE_TMP/EFI/boot/boot.conf fi mv $MBD_BOOTTREE_TMP/EFI/boot/grub.efi $MBD_BOOTTREE_TMP/EFI/boot/boot${efiarch}.efi mv $MBD_BOOTTREE_TMP/EFI/boot/grub.conf $MBD_BOOTTREE_TMP/EFI/boot/boot${efiarch}.conf artpkg=$(repoquery --qf "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}" -c $yumconf fedora-logos) yumdownloader -c $yumconf $artpkg rpm2cpio $artpkg.rpm | (cd $KERNELROOT; cpio --quiet -iumd) cp $KERNELROOT/boot/grub/splash.xpm.gz $MBD_BOOTTREE_TMP/EFI/boot/splash.xpm.gz } makeEfiImages() { yumconf="$1" if [ "$kerneltag" != "xen" ]; then local grubarch=${efiarch} case ${efiarch} in ia32) grubarch=i386 ;; 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" makeefibootimage \ --imagename pxeboot/efiboot.img \ --kernel $TOPDESTPATH/images/pxeboot/vmlinuz \ --initrd $TOPDESTPATH/images/pxeboot/initrd.img \ --grubpkg ${grubpkg} local ret=$? [ $ret -eq 0 ] || return $ret makeefibootdisk $TOPDESTPATH/images/pxeboot/efiboot.img $TOPDESTPATH/images/efidisk.img return $? fi return 1 }