grub-devel
[Top][All Lists]
Advanced

[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


Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]