[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Improve EFI grub-install to handle non-Apple systems
From: |
Vladimir 'φ-coder/phcoder' Serbinenko |
Subject: |
Re: [PATCH] Improve EFI grub-install to handle non-Apple systems |
Date: |
Mon, 12 Jul 2010 23:40:36 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100620 Icedove/3.0.5 |
On 07/12/2010 01:52 PM, Colin Watson wrote:
> At the moment, the EFI grub-install script only handles Apple Mac
> systems. This patch adds support for systems that conform to the UEFI
> specification, while retaining support for Apple systems.
>
>
Apple systems seem to support generic way too. So if this way is
properly tested on different Apple systems we should switch to generic
way altogether.
> I couldn't find anything approaching a standard for where the EFI System
> Partition should be mounted, so I chose to look for it in /boot/efi,
> since I don't like creating new top-level directories. If there's a
> different convention then I'd be happy to add support for it.
>
>
Where to mount X or Y depends on distribution. I'm happy to support
whatever you feel is right. This will probably set a precedent and other
distros will follow.
> Vladimir asked whether I could merge util/i386/efi/grub-install.in into
> util/grub-install.in at the same time. This is of course desirable but
> I haven't got round to it yet, and I didn't want to stall this patch
> indefinitely until I find time for that.
>
> 2010-07-12 Colin Watson <address@hidden>
>
> * util/i386/efi/grub-install.in: Add support for systems that
> conform to the UEFI specification, as well as Apple systems.
> Currently looks for the EFI System Partition on /boot/efi.
>
> === modified file 'util/i386/efi/grub-install.in'
> --- util/i386/efi/grub-install.in 2010-07-04 12:23:55 +0000
> +++ util/i386/efi/grub-install.in 2010-07-12 11:43:20 +0000
> @@ -24,6 +24,7 @@ address@hidden@
> address@hidden@
> address@hidden@
> address@hidden@
> address@hidden@
> address@hidden@
> address@hidden@
> address@hidden@
> @@ -43,10 +44,14 @@ rootdir=
> grub_prefix=`echo /boot/grub | sed ${transform}`
> modules=
>
> +efibootmgr=`which efibootmgr 2>/dev/null || true`
> +
> no_floppy=
> force_lba=
> recheck=no
> +removable=no
> debug=no
> +efi_quiet=
>
> # Usage: usage
> # Print the usage.
> @@ -65,6 +70,7 @@ Install GRUB on your EFI partition.
> --grub-probe=FILE use FILE as grub-probe
> --no-floppy do not probe any floppy drive
> --recheck probe a device map even if it already exists
> + --removable the installation device is removable
>
> $self copies GRUB images into the DIR/boot directory specified by
> --root-directory.
> @@ -127,9 +133,14 @@ do
> no_floppy="--no-floppy" ;;
> --recheck)
> recheck=yes ;;
> + --removable)
> + removable=yes ;;
> # This is an undocumented feature...
> --debug)
> debug=yes ;;
> + # Intentionally undocumented; for compatibility only.
> + -f | --force)
> + ;;
> *)
> echo "Unrecognized option \`$option'" 1>&2
> usage
> @@ -138,9 +149,13 @@ do
> esac
> done
>
> +# for make_system_path_relative_to_its_root()
> +. ${libdir}/grub/grub-mkconfig_lib
> +
> # If the debugging feature is enabled, print commands.
> if test $debug = yes; then
> set -x
> + efi_quiet=-q
> fi
>
> # Initialize these directories here, since ROOTDIR was initialized.
> @@ -177,6 +192,106 @@ else
> exit 1
> fi
>
> +# Get GRUB_DISTRIBUTOR.
> +if test -f ${sysconfdir}/default/grub ; then
> + . ${sysconfdir}/default/grub
> +fi
> +
> +# Find the EFI System Partition.
> +efidir=
> +if test -d ${bootdir}/efi; then
> + install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe
> --target=device --device-map=/dev/stdin ${bootdir}/efi`
> + # Is it a mount point?
> + if test "x$install_device" != "x`$grub_mkdevicemap
> --device-map=/dev/stdout | $grub_probe --target=device
> --device-map=/dev/stdin ${bootdir}`"; then
> + efidir=${bootdir}/efi
> + fi
> +elif test -n "$rootdir" && test "x$rootdir" != "x/"; then
> + # The EFI System Partition may have been given directly using
> + # --root-directory.
> + install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe
> --target=device --device-map=/dev/stdin ${rootdir}`
> + # Is it a mount point?
> + if test "x$install_device" != "x`$grub_mkdevicemap
> --device-map=/dev/stdout | $grub_probe --target=device
> --device-map=/dev/stdin ${rootdir}/..`"; then
> + efidir=${rootdir}
> + fi
> +fi
> +
>
This seems to change the meaning of --root-directory. Perhaps another
option would be better?
> +if test -n "$efidir"; then
> + efi_fs=`$grub_probe --target=fs --device-map=${device_map} ${efidir}`
> + if test "x$efi_fs" = xfat; then :; else
> + echo "${efidir} doesn't look like an EFI partition." 1>&2
> + efidir=
> + fi
> +fi
> +
> +if test -n "$efidir"; then
> + # The EFI specification requires that an EFI System Partition must
> + # contain an "EFI" subdirectory, and that OS loaders are stored in
> + # subdirectories below EFI. Vendors are expected to pick names that do
> + # not collide with other vendors. To minimise collisions, we use the
> + # name of our distributor if possible.
>
I'm not sure how well this is implemented in a real world. We may need
to change that to
efi_distributor=BOOT
If real implementations don't work as well as expected
> + if test $removable = yes; then
> + # The specification makes stricter requirements of removable
> + # devices, in order that only one image can be automatically loaded
> + # from them. The image must always reside under /EFI/BOOT, and it
> + # must have a specific file name depending on the architecture.
> + efi_distributor=BOOT
> + case "$target_cpu" in
> + i386)
> + efi_file=BOOTIA32.EFI
> + ;;
> + x86-64)
> + efi_file=BOOTX64.EFI
> + ;;
> + # GRUB does not yet support these architectures, but they're defined
> + # by the specification so we include them here to ease future
> + # expansion.
> + ia64)
> + efi_file=BOOTIA64.EFI
> + ;;
> + arm)
> + efi_file=BOOTARM.EFI
> + ;;
> + esac
> + else
> + efi_distributor="$(echo "$GRUB_DISTRIBUTOR" | tr '[A-Z]' '[a-z]' | cut
> -d' ' -f1)"
>
Perhaps we need a check that name contains no non-ASCII characters. EFI
is supposed to support unicode but some parts of its spec contradict
Unicode.
> +# Try to make this image bootable using the EFI Boot Manager, if available.
> +if test "$removable" = no && test -n "$efi_distributor" && \
> + test -n "$efibootmgr"; then
> + # On Linux, we need the efivars kernel modules.
> + case "$host_os" in
> + linux*)
> + modprobe -q efivars 2>/dev/null || true
> + ;;
> + esac
> +
>
What about using efi_distributor=boot if efivars fails to load? Many
people have a mismatchin Linux and EFI and so use "noefi" on command
line. Or "noefi" is there for some other reason.
> + # Delete old entries from the same distributor.
> + for bootnum in `efibootmgr | grep '^Boot[0-9]' | \
> + fgrep " $efi_distributor" | cut -b5-8`; do
> + efibootmgr $efi_quiet -b "$bootnum" -B
> + done
> +
>
This would conflict with installing both ia32 and x64 because second
install will erase first one.
Sane way may be to use efibootmgr only if installed version matches
current EFI.
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
signature.asc
Description: OpenPGP digital signature