[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Fixing #698914 for wheezy (grub booting Windows 8 via UEFI)



Hi folks,

I opened #698914 a while back, concerned about the lack of support in
grub and os-prober for detecting Windows 8 on UEFI systems so that
working boot entries would be added automatically at installation
time. At the time, I did not consider the issue RC. However,
discussion yesterday with Wolodja Wentland suggests that this is
becoming a more common problem than I feared, and users are tripping
over this and asking for support on #debian and elsewhere. I'm
thinking that this bug should therefore be considered RC for the
Wheezy r0 release at this point.

He pointed me at an existing set of patches from the folks at
openSUSE, which I've adapted very slightly and tested out:

 * Using an existing installation
 * Using a locally-built CD to test the os-prober udeb

and all works fine, fixing the bug nicely. I would like to upload (and
get unblocks for) new grub2 and os-prober packages - see debdiffs of
changes attached. The changes are quite small and targeted, only
affecting code paths for EFI systems.

What do you think?

-- 
Steve McIntyre, Cambridge, UK.                                steve@einval.com
You raise the blade, you make the change... You re-arrange me 'til I'm sane...
diff -Nru os-prober-1.57/debian/changelog os-prober-1.58/debian/changelog
--- os-prober-1.57/debian/changelog	2012-12-22 11:54:54.000000000 +0000
+++ os-prober-1.58/debian/changelog	2013-04-25 15:30:14.000000000 +0100
@@ -1,3 +1,13 @@
+os-prober (1.58) unstable; urgency=low
+
+  [ Steve McIntyre ]
+  * add UEFI support, patch from Andrey Borzenkov:
+    + skip legacy MS loader detection on UEFI platform
+    + add framework for searching EFI System Partition
+    + add scripts that detect Microsoft bootloader and ELILO.
+
+ -- Steve McIntyre <93sam@debian.org>  Thu, 25 Apr 2013 00:55:53 +0100
+
 os-prober (1.57) unstable; urgency=low
 
   [ Christian Perrier ]
diff -Nru os-prober-1.57/os-probes/mounted/x86/05efi os-prober-1.58/os-probes/mounted/x86/05efi
--- os-prober-1.57/os-probes/mounted/x86/05efi	1970-01-01 01:00:00.000000000 +0100
+++ os-prober-1.58/os-probes/mounted/x86/05efi	2013-04-25 15:30:14.000000000 +0100
@@ -0,0 +1,70 @@
+#!/bin/sh
+# Detects all Microsoft OSes on a collection of partitions.
+
+. /usr/share/os-prober/common.sh
+
+partition="$1"
+mpoint="$2"
+type="$3"
+
+# This file is for UEFI platform only
+if [ ! -d /sys/firmware/efi ]; then
+	debug "Not on UEFI platform"
+	exit 1
+fi
+
+# Weed out stuff that doesn't apply to us
+case "$type" in
+	vfat) debug "$1 is a FAT32 partition" ;;
+	msdos) debug "$1 is a FAT16 partition" ;;
+	*) debug "$1 is $type partition: exiting"; exit 1 ;;
+esac
+
+if type udevadm > /dev/null 2>&1; then
+	udevinfo () {
+		udevadm info "$@"
+	}
+fi
+
+if type udevinfo > /dev/null 2>&1; then
+	# Skip virtual devices
+	if udevinfo -q path -n $partition | grep -q /virtual/; then
+		debug "$1 is virtual device: exiting"
+		exit 1
+	fi
+
+	eval "$(udevinfo -q property -n "$partition" | grep -E '^ID_PART_ENTRY_(TYPE|SCHEME)=')"
+	debug "$partition partition scheme is $ID_PART_ENTRY_SCHEME"
+	debug "$partition partition type is $ID_PART_ENTRY_TYPE"
+
+	if [ -z "$ID_PART_ENTRY_TYPE" -o -z "$ID_PART_ENTRY_SCHEME" -o \
+		\( "$ID_PART_ENTRY_SCHEME" != gpt -a "$ID_PART_ENTRY_SCHEME" != msdos \) -o \
+		\( "$ID_PART_ENTRY_SCHEME" = gpt -a "$ID_PART_ENTRY_TYPE" != c12a7328-f81f-11d2-ba4b-00a0c93ec93b \) -o \
+		\( "$ID_PART_ENTRY_SCHEME" = msdos -a "$ID_PART_ENTRY_TYPE" != 0xef \) ]; then
+		debug "$partition is not a ESP partition: exiting"
+		exit 1
+	fi
+else
+	debug "udevinfo and udevadm missing - cannot check partition type"
+fi
+
+efi=$(item_in_dir efi "$mpoint")
+if [ -z "$efi" ]; then
+	debug "$mpoint does not have /EFI directory: exiting"
+	exit 1
+fi
+
+ret=1
+for test in /usr/lib/os-probes/mounted/efi/*; do
+	debug "running subtest $test"
+	if [ -f "$test" ] && [ -x "$test" ]; then
+		entry=$("$test" "$mpoint/$efi")
+		if [ -n "$entry" ]; then
+			debug "bootloader $entry found by subtest $test"
+			ret=0
+			result "${partition}@/$efi/${entry}:efi"
+		fi
+	fi
+done
+
+exit $ret
diff -Nru os-prober-1.57/os-probes/mounted/x86/20microsoft os-prober-1.58/os-probes/mounted/x86/20microsoft
--- os-prober-1.57/os-probes/mounted/x86/20microsoft	2012-04-06 02:01:39.000000000 +0100
+++ os-prober-1.58/os-probes/mounted/x86/20microsoft	2013-04-25 15:30:14.000000000 +0100
@@ -7,6 +7,12 @@
 mpoint="$2"
 type="$3"
 
+# This script looks for legacy BIOS bootloaders only. Skip if running UEFI
+if [ -d /sys/firmware/efi ]; then
+	debug "Skipping legacy bootloaders on UEFI system"
+	exit 1
+fi
+
 # Weed out stuff that doesn't apply to us
 case "$type" in
 	ntfs|ntfs-3g) debug "$1 is a NTFS partition" ;;
diff -Nru os-prober-1.57/os-probes/mounted/x86/efi/10elilo os-prober-1.58/os-probes/mounted/x86/efi/10elilo
--- os-prober-1.57/os-probes/mounted/x86/efi/10elilo	1970-01-01 01:00:00.000000000 +0100
+++ os-prober-1.58/os-probes/mounted/x86/efi/10elilo	2013-04-25 15:30:14.000000000 +0100
@@ -0,0 +1,24 @@
+#!/bin/sh
+# Detects ELILO bootloader on a EFI System Partition
+
+. /usr/share/os-prober/common.sh
+
+efi="$1"
+
+found=
+
+elilo=`find $1 -name "elilo.efi"`
+if [ -n "$elilo" ]; then
+	bdir=`dirname $elilo`
+	bdir=`basename $bdir`
+	long="ELILO Boot Manager"
+	short="ELILO"
+	path=${bdir}/elilo.efi
+	found=true
+fi  
+
+if [ -n "$found" ]; then
+	label="$(count_next_label "$short")"
+	result "${path}:${long}:${label}"
+fi
+exit 0
diff -Nru os-prober-1.57/os-probes/mounted/x86/efi/20microsoft os-prober-1.58/os-probes/mounted/x86/efi/20microsoft
--- os-prober-1.57/os-probes/mounted/x86/efi/20microsoft	1970-01-01 01:00:00.000000000 +0100
+++ os-prober-1.58/os-probes/mounted/x86/efi/20microsoft	2013-04-25 15:30:14.000000000 +0100
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Detects Microsoft bootloader on a EFI System Partition
+
+. /usr/share/os-prober/common.sh
+
+efi="$1"
+
+found=
+for microsoft in $(item_in_dir microsoft "$efi"); do
+	for boot in $(item_in_dir boot "$efi/$microsoft"); do
+		bcd=$(item_in_dir bcd "$efi/$microsoft/$boot")
+		bootmgfw=$(item_in_dir bootmgfw.efi "$efi/$microsoft/$boot")
+		if [ -n "$bcd" -a -n "$bootmgfw" ]; then
+			long="Windows Boot Manager"
+			short=Windows
+			path="$microsoft/$boot/$bootmgfw"
+			found=true
+			break
+		fi
+	done
+done
+
+
+if [ -n "$found" ]; then
+	label="$(count_next_label "$short")"
+	result "${path}:${long}:${label}"
+fi
+exit 0
diff -u grub2-1.99/debian/changelog grub2-1.99/debian/changelog
--- grub2-1.99/debian/changelog
+++ grub2-1.99/debian/changelog
@@ -1,3 +1,11 @@
+grub2 (1.99-27.1) unstable; urgency=low
+
+  * NMU
+  * Add entries for Windows Boot Manager found via UEFI in
+    os-prober. Closes: #698914
+
+ -- Steve McIntyre <93sam@debian.org>  Thu, 25 Apr 2013 00:17:53 +0100
+
 grub2 (1.99-27) unstable; urgency=low
 
   * Amend gfxpayload_keep_default.patch to no longer remove the call to
diff -u grub2-1.99/debian/patches/series grub2-1.99/debian/patches/series
--- grub2-1.99/debian/patches/series
+++ grub2-1.99/debian/patches/series
@@ -48,0 +49 @@
+os_prober_efi.patch
only in patch2:
unchanged:
--- grub2-1.99.orig/debian/patches/os_prober_efi.patch
+++ grub2-1.99/debian/patches/os_prober_efi.patch
@@ -0,0 +1,22 @@
+--- a/util/grub.d/30_os-prober.in	2013-04-25 00:47:18.896418866 +0100
++++ b/util/grub.d/30_os-prober.in	2013-04-25 00:48:33.876420645 +0100
+@@ -125,6 +125,19 @@
+ }
+ EOF
+     ;;
++    efi)
++      EFIPATH=${DEVICE#*@}
++      DEVICE=${DEVICE%@*}
++      cat << EOF
++menuentry "${LONGNAME} (UEFI on ${DEVICE})" --class windows --class os {
++EOF
++      save_default_entry | sed -e "s/^/\t/"
++      prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
++      cat <<EOF
++	chainloader ${EFIPATH}
++}
++EOF
++    ;;
+     linux)
+       LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
+       prepare_boot_cache=

Reply to: