Installing Grub2 with updateGrub2

I’m not completely done with this script, but I decided to start a new thread and post the code now - since I did already mention it a couple times in other posts and in the findgrub thread. What’s still missing is a function to add chainload entries for other Legacy Grub and Grub2 bootloaders on legacy MBR and UEFI systems. updateGrub2 is primarily intended to install Grub2 on UEFI systems (with GUID partitioning scheme), in order to multiboot openSUSE on UEFI systems. I’m working on an explicit tutorial - targeted at UEFI systems.

Here the latest code (1.1 beta). Comments and bug reports are welcome.


#! /bin/bash
#
#: Title       : updateGrub2
#: Date Created: Sat Jan 14 22:34:57 PST 2012
#: Last Edit   : Thu Jan 19 04:29:31 PST 2012
#: Author      : Agnelo de la Crotche (please_try_again)
#: Version     : 1.1 - beta
#: Description : install grub2, grub2-efi and refresh Grub2 menu
#: Requires    : os-prober
#: Usage       : updategrub2
#
# -----------------------------------------------

# variables you may modify. 

grub_timeout=60

# check the VESA resolutions available to your graphics card with hwinfo --framebuffer
# before changing this value. If you don't specify a video mode here, 'auto' will be used
# - it is often the the best choice. 

#grub_gfx=800x600x16
#grub_gfx=1024x768x16
#grub_gfx=128x1024x16

# menu colors

COLOR_NORMAL="black"
COLOR_HIGHLIGHT="white"

# To use your own background image, put its path in the variable grub_bg
# and uncomment the line below 
# grub_bg=/usr/local/share/images/stellarcart.png

# You shouldn't need to change these values
unifont_url=http://unifoundry.com
unifont=unifont-5.1.20080820.bdf.gz

# -----------------------------------------------

# Do not modify the variables below!!!

# current version
version="1.0"
prg=$(basename $0)
declare -l	NOCONFIRM INSTALL DISPLAYONLY BLID USEBG noconfirm autoimport gdev distcode
GSIGN="020"
GRID="grubx64.efi"
USEBG=yes
G=$(tput setaf 2)
B=$(tput bold)
N=$(tput sgr0)

# Exit if we are not root
 $(id -u) -gt 0 ] && exec echo "You need to run this script as root"

# This script only works in openSUSE and Fedora
which lsb_release &> /dev/null || exec cat << EOFLSB
Please install Linux Standard Base Release Tools
using this command: 

- under openSUSE:
  zypper in lsb_release
- under Fedora:
  yum install redhat-lsb  

EOFLSB
eval $(lsb_release -ircs | awk '{ sub(/SUSE LINUX/,"openSUSE", $0) ; printf "dist=%s;distver=%s;distcode=%s;", $1, $2, $3 }')
BLID=$dist
 "$BLID" == "opensuse" -o "$BLID" == "fedora" ] || exec echo "This script only supports openSUSE and Fedora."


# Default distro background image
opensuse_bg=/usr/share/backgrounds/upwind/morning-1280x1024.jpg
fedora_bg=/usr/share/backgrounds/$distcode/default/standard/${distcode}.png
dist_bg=${BLID}_bg ; dist_bg=${!dist_bg} 
 "$grub_bg" ] &&  -f "$grub_bg" ] && dist_bg=$grub_bg
 -f $dist_bg ] && grub_bg=$dist_bg || unset USEBG

rootdev=$(cat /etc/mtab | awk '/^\/dev/ { if ( $2 == "/" ) print $1 }')
eval $(udevadm info --query=all --name=$rootdev | awk '/UDISKS_PARTITION_SCHEME/ { print $2 }')

opensuse_noconfirm="--non-interactive"
fedora_noconfirm="--assumeyes"
dist_noconfirm=${BLID}_noconfirm ; dist_noconfirm=${!dist_noconfirm}

function install_osprober {
	case $dist in
	openSUSE) 
		PTA_repo="http://download.opensuse.org/repositories/home:/please_try_again/${dist}_${distver}/"
		zypper lr -u | grep -q ${PTA_repo} || zypper ar $PTA_repo PTA
		zypper -n $autoimport refresh -r PTA
		zypper $noconfirm in -r PTA os-prober
	;;
	Fedora)
		yum $noconfirm install os-prober	
	;;
	esac
}

function install_pkg {
	case $dist in
	openSUSE) 
		zypper $noconfirm install $grub
	;;
	Fedora)
		rpm -qa | grep -q "grub-efi" && yum $noconfirm remove grub-efi
		yum $noconfirm install $grub $grub2
	;;
	esac
}

function install_grub {
	if  "$EFI" ] ; then
		 -f /boot/$ESP/$GRID ] || $ginstall --bootloader-id=$BLID --no-floppy
	else
		eval $(udevadm info --query=property --name=$gdev | awk '/DEVTYPE/ { print }')
		case $DEVTYPE in
		disk)
			declare -l YESNO
			read -n 1 -s -p "Are you sure that you want to install Grub2 in MBR of $gdev? [yn] " YESNO
			 "$YESNO" == "y" ] && $ginstall $gdev
		;;
		partition)
			 "$($gprobe -d $gdev)" == "ext2" ] || exec echo "Destination is not an ext4 or ext3 partition" 
			$ginstall --force $gdev
		;;
		esac
	fi
}

function grub_font {

	case $BLID in
	opensuse)
		zypper $noconfirm in gnu-unifont
		grub2-mkfont -o $gdir/unicode.pf2 /usr/share/fonts/uni/unifont.pcf.gz
	;;
	fedora)
		cd /tmp
		 -f $unifont ] || wget ${unifont_url}/${unifont}
		 -f $unifont ] || return
		gunzip $unifont
		grub2-mkfont -o $gdir/unicode.pf2 $(basename $unifont .gz)
	;;
	esac	
}


function gfx_menu {
 -f $gdir/unicode.pf2 ] || grub_font

if  "$USEBG" == "yes" ] ; then
	splashsrc=$grub_bg ; splash=splash.${splashsrc##*.}
	 -f $gdir/$splash ] || cp $grub_bg $gdir/$splash
fi

if  ! -f /etc/default/grub.orig -a -f /etc/default/grub  ] ; then
	echo "- patching /etc/default/grub ..."
	grub_timeout=${grub_timeout:-10}
	cp /etc/default/grub{,.orig}
	grub_gfx=${grub_gfx:-auto}
	grep -q "GRUB_GFXMODE" /etc/default/grub || echo "#GRUB_GFXMODE=640x480" >> /etc/default/grub
	cat << EOFGRUBDEFAULT | sed -i -f - /etc/default/grub
s|GRUB_TIMEOUT=.*|GRUB_TIMEOUT=$grub_timeout|
s|#GRUB_GFXMODE=640x480|GRUB_GFXMODE=$grub_gfx|
/GRUB_GFXMODE/ a\
GRUB_GFXPAYLOAD_LINUX=keep
EOFGRUBDEFAULT
if  -f $gdir/$splash ] ; then
	cat << EOFGRUBDEFAULT2 | sed -i -f - /etc/default/grub
/GRUB_GFXMODE/ a\
GRUB_BACKGROUND=$gdir/$splash
EOFGRUBDEFAULT2
fi
fi

if  ! -f /etc/grub.d/05_menu_color ] ; then
	cat > /etc/grub.d/05_menu_color << EOF05MENUCOLOR
#!/bin/sh -e
set -e

prefix=/usr
exec_prefix=/usr
libdir=/usr/lib

. \${libdir}/grub/grub-mkconfig_lib

COLOR_NORMAL="$COLOR_NORMAL/black"
COLOR_HIGHLIGHT="$COLOR_HIGHLIGHT/black"

if  "\${GRUB_TERMINAL_OUTPUT}" = "gfxterm" ] ; then
        cat <<EOF
set color_normal=\${COLOR_NORMAL}
set color_highlight=\${COLOR_HIGHLIGHT}
EOF
else
  cat << EOF
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
EOF
fi
EOF05MENUCOLOR
chmod 0755 /etc/grub.d/05_menu_color
fi

}

function chainload_windows {
 -f  /boot/efi/EFI/Microsoft/Boot/bootmgfw.efi ] || return
WINID=$($gprobe --target=fs_uuid /boot/efi/EFI/Microsoft/Boot/bootmgfw.efi)
grep -q $WINID /etc/grub.d/40_custom && return
echo "chainloading Windows..."
cat >> /etc/grub.d/40_custom << EOFWINCHAINLOAD
menuentry "Microsoft Windows x86_64 UEFI-GPT" {
    insmod part_gpt
    insmod fat
    insmod search_fs_uuid
    insmod chain
    search --fs-uuid --no-floppy --set=root $WINID
    chainloader (\${root})/efi/Microsoft/Boot/bootmgfw.efi
}

EOFWINCHAINLOAD
}

function update_menu {
	 "$mkconfig" ] || exec echo "grub2 not found"
	if  "$DISPLAYONLY" ] ; then
		echo "Scanning..."
		$mkconfig
	else
		if  -d $gdir ] ; then
			 -d /boot/$ESP ] && chainload_windows 
			$mkconfig -o $gmenu
			 -d /boot/$ESP ] && cp $gmenu /boot/${ESP}/ 
		else
	  	    echo "Boot directory $gdir not found"
		fi
	fi	
}


function restore_elilo {
 $(efibootmgr | grep -c -i $BLID) -gt 1 ] && return

eliloPath=$(find /boot/efi -name "elilo.efi")
dev=$(grub2-probe -t device $eliloPath)
disk=${dev:0:8} ; part=${dev:8} 
eliloBldr=$(echo $eliloPath | sed 's|/boot/efi||;s|/|\\\\|g') 
efibootmgr --create --gpt --disk $disk --part $part --write-signature --label  "$DIST (elilo)" --loader "$eliloBldr"
}


function syntax {
cat << EOFHELP

$prg $version  - Grub2 install and boot menu update.

${G}Syntax:${N}  
  ${B}updateGrub2  options ]${N}

${G}Options:${N} 
    ${B}-n --noconfirm${N}           Installs packages and imports keys without asking for confirmation.
    ${B}-i --install [device]${N}    Installs Grub2 on UEFI systems.
                             On BIOS systems you have to specify a device. This option is ignored if
                             the root partition already contains Grub2 signature. Otherwise you will
                             be able to install Grub2 bootloader in any partition, including the MBR. 
                             Use this option with care! 
    ${B}-d --display${N}             Refreshes and prints the boot menu to standard output.
    ${B}-h --help${N}                Displays this help.

                             Without options, updateGrub2 scans for other OSes (provided os-prober is  
                             installed) and refreshes the boot entries in grub.cfg. The first time it
                             is run, it also modifies default settings, adds a script to /etc/grub.d, 
                             builds a missing font which prevents graphic mode from working, lets you
                             set a background image or uses the system default one.
EOFHELP
exit
}


# -------------------------------------------------

args=`getopt -q -u -o hndi:: -l help,noconfirm,display,install:: -- "$@"`
set -- $args

for i; do
	case "$i" in
	-n|--noconfirm) noconfirm="${dist_noconfirm}" ; autoimport="--gpg-auto-import-keys" ; shift ;;
	-i|--install) INSTALL=yes ; shift ;;
	-d|--display) DISPLAYONLY=yes ; shift ;;
	-h|--help) syntax ; shift ;;
	--) shift ; break ;;
	esac
done

gdev=$1 ; shift

case $UDISKS_PARTITION_SCHEME in
mbr)
EFI=""
ESP=""
grub2=""
 "$(hexdump -v -s 128 -n  2 -e '/1 "%x"' $rootdev)" == "$GSIGN" ] && unset INSTALL
if  "$INSTALL" == "yes" ] ; then
	 "$gdev" ] || exec echo "Option --install requires an argument"
	 -b  $gdev ] || exec echo "Destination is not a block device"
fi
;;
gpt)
EFI="-efi"
ESP="/efi/EFI/$BLID"
DIST="$dist $distver"
grub2="grub2"
;;
esac

grub="grub2$EFI"
mkconfig="${grub}-mkconfig"
ginstall="${grub}-install"
gprobe="${grub}-probe"
gdir="/boot/${grub}"
gmenu="$gdir/grub.cfg"

if  "$INSTALL" == "yes" ] ; then
	which os-prober &>/dev/null || install_osprober
	rpm -qa | grep -q $grub || install_pkg
	 "$INSTALL" ] && install_grub
fi

gfx_menu
update_menu

This script is intended for openSUSE UEFI and MBR systems, as well as Fedora UEFI systems (Fedora 16 installs Grub2 by default on Legacy BIOS systems).

updateGrub2 will also build the missing pf2 font which prevents Grub2 from entering graphic mode. You can set your own backgound image in the variable grub_bg and uncomment this variable. updateGrub2 WON’T install the bootloader if it finds a Grub2 signature in the boot sector of your root partition. So the option “-i” will be ignored in this case. Otherwise you have to specify the partition where you want to install the bootloader. It can be any primary or logical (linux) partition but not the extended one!.

Examples:


updateGrub2 -i /dev/sda    # install Grub2 in the MBR of the first HDD
updateGrub2 -i /dev/sda6   # install Grub2 in the bootsector of sda6

Installing grub2 in a partition boot sector has been discouraged since the beginning by Grub2 developers (read Grub2 documentation). It would require the use of the --force option (the script takes care ot that). Since version 1.99, Grub2 uses a compressed core - that made it tricky for findgrub to get the partition where it is installed on disk.
**
You’re using this script with option “-i” at your own risk! Don’t play with this script if you don’t have another way to boot your system, such as Legacy Grub installed in another partition and the possibility to boot from it if things go wrong.**

James,
Did you know that you can enable EFI in VirtualBox? I haven’t tried. I wrote my script on real hardware. But if you create a vm with EFI enable and install openSUSE, it should create a GUID partition table (same for Windows 7) and install elilo as boot manager. Then you can use updateGrub2 to install Grub2 and have plenty to learn and experiment with GPT…

#! /bin/bash
#
#: Title       : updateGrub2
#: Date Created: Sat Jan 14 22:34:57 PST 2012
#: Last Edit   : Fri Jan 20 06:04:37 PST 2012
#: Author      : Agnelo de la Crotche (please_try_again)
#: Version     : 1.2 - beta
#: Description : install grub2, grub2-efi and refresh Grub2 menu
#: Requires    : os-prober
#: Usage       : updategrub2
#
# -----------------------------------------------

# variables you may modify. 

grub_timeout=60

# check the VESA resolutions available to your graphics card with hwinfo --framebuffer
# before changing this value. If you don't specify a video mode here, 'auto' will be used
# - it is often the the best choice. 

#grub_gfx=800x600x16
#grub_gfx=1024x768x16
#grub_gfx=128x1024x16

# menu colors

COLOR_NORMAL="black"
COLOR_HIGHLIGHT="white"

# To use your own background image, put its path in the variable grub_bg
# and uncomment the line below 
# grub_bg=/usr/local/share/images/stellarcart.png

# You shouldn't need to change these values
unifont_url=http://unifoundry.com
unifont=unifont-5.1.20080820.bdf.gz

# -----------------------------------------------

# Do not modify the variables below!!!

# current version
version="1.0"
prg=$(basename $0)
declare -l	NOCONFIRM INSTALL DISPLAYONLY BLID USEBG noconfirm autoimport gdev distcode
GSIGN="020"
GRID="grubx64.efi"
W7ID="bootmgfw.efi"
USEBG=yes
G=$(tput setaf 2)
B=$(tput bold)
N=$(tput sgr0)

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Grub Bootsector ID at offset 0x80,81

BSaa75="Legacy Grub"
BS5272="Legacy Grub"
BS48b4="Grub 1.96"
BS488="Grub2 s core.img"
BS7c3c="Grub 1.98"
BS020="Grub 1.99"
BS8053="Lilo"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# Exit if we are not root
[ $(id -u) -gt 0 ] && exec echo "You need to run this script as root"

# This script only works in openSUSE and Fedora
which lsb_release &> /dev/null || exec cat << EOFLSB
Please install Linux Standard Base Release Tools
using this command: 

- under openSUSE:
  zypper in lsb_release
- under Fedora:
  yum install redhat-lsb  

EOFLSB
eval $(lsb_release -ircs | awk '{ sub(/SUSE LINUX/,"openSUSE", $0) ; printf "dist=%s;distver=%s;distcode=%s;", $1, $2, $3 }')
BLID=$dist
[ "$BLID" == "opensuse" -o "$BLID" == "fedora" ] || exec echo "This script only supports openSUSE and Fedora."


# Default distro background image
opensuse_bg=/usr/share/backgrounds/upwind/morning-1280x1024.jpg
fedora_bg=/usr/share/backgrounds/$distcode/default/standard/${distcode}.png
dist_bg=${BLID}_bg ; dist_bg=${!dist_bg} 
[ "$grub_bg" ] && [ -f "$grub_bg" ] && dist_bg=$grub_bg
[ -f $dist_bg ] && grub_bg=$dist_bg || unset USEBG

rootdev=$(cat /etc/mtab | awk '/^\/dev/ { if ( $2 == "/" ) print $1 }')
eval $(udevadm info --query=all --name=$rootdev | awk '/UDISKS_PARTITION_SCHEME/ { print $2 }')

opensuse_noconfirm="--non-interactive"
fedora_noconfirm="--assumeyes"
dist_noconfirm=${BLID}_noconfirm ; dist_noconfirm=${!dist_noconfirm}

function install_osprober {
	case $dist in
	openSUSE) 
		PTA_repo="http://download.opensuse.org/repositories/home:/please_try_again/${dist}_${distver}/"
		zypper lr -u | grep -q ${PTA_repo} || zypper ar $PTA_repo PTA
		zypper -n $autoimport refresh -r PTA
		zypper $noconfirm in -r PTA os-prober
	;;
	Fedora)
		yum $noconfirm install os-prober	
	;;
	esac
}

function install_pkg {
	case $dist in
	openSUSE) 
		zypper $noconfirm install $grub
	;;
	Fedora)
		rpm -qa | grep -q "grub-efi" && yum $noconfirm remove grub-efi
		yum $noconfirm install $grub $grub2
	;;
	esac
}

function install_grub {
	if [ "$EFI" ] ; then
		[ -f /boot/$ESP/$GRID ] || $ginstall --bootloader-id=$BLID --no-floppy
	else
		eval $(udevadm info --query=property --name=$gdev | awk '/DEVTYPE/ { print }')
		case $DEVTYPE in
		disk)
			declare -l YESNO
			read -n 1 -s -p "Are you sure that you want to install Grub2 in MBR of $gdev? [yn] " YESNO
			[ "$YESNO" == "y" ] && $ginstall $gdev
		;;
		partition)
			[ "$($gprobe -d $gdev)" == "ext2" ] || exec echo "Destination is not an ext4 or ext3 partition" 
			$ginstall --force $gdev
		;;
		esac
	fi
}

function grub_font {

	case $BLID in
	opensuse)
		zypper $noconfirm in gnu-unifont
		grub2-mkfont -o $gdir/unicode.pf2 /usr/share/fonts/uni/unifont.pcf.gz
	;;
	fedora)
		cd /tmp
		[ -f $unifont ] || wget ${unifont_url}/${unifont}
		[ -f $unifont ] || return
		gunzip $unifont
		grub2-mkfont -o $gdir/unicode.pf2 $(basename $unifont .gz)
	;;
	esac	
}


function gfx_menu {
[ -f $gdir/unicode.pf2 ] || grub_font

if [ "$USEBG" == "yes" ] ; then
	splashsrc=$grub_bg ; splash=splash.${splashsrc##*.}
	[ -f $gdir/$splash ] || cp $grub_bg $gdir/$splash
fi

if [ ! -f /etc/default/grub.orig -a -f /etc/default/grub  ] ; then
	echo "- patching /etc/default/grub ..."
	grub_timeout=${grub_timeout:-10}
	cp /etc/default/grub{,.orig}
	grub_gfx=${grub_gfx:-auto}
	grep -q "GRUB_GFXMODE" /etc/default/grub || echo "#GRUB_GFXMODE=640x480" >> /etc/default/grub
	cat << EOFGRUBDEFAULT | sed -i -f - /etc/default/grub
s|GRUB_TIMEOUT=.*|GRUB_TIMEOUT=$grub_timeout|
s|#GRUB_GFXMODE=640x480|GRUB_GFXMODE=$grub_gfx|
/GRUB_GFXMODE/ a\
GRUB_GFXPAYLOAD_LINUX=keep
EOFGRUBDEFAULT
if [ -f $gdir/$splash ] ; then
	cat << EOFGRUBDEFAULT2 | sed -i -f - /etc/default/grub
/GRUB_GFXMODE/ a\
GRUB_BACKGROUND=$gdir/$splash
EOFGRUBDEFAULT2
fi
fi

if [ ! -f /etc/grub.d/05_menu_color ] ; then
	cat > /etc/grub.d/05_menu_color << EOF05MENUCOLOR
#!/bin/sh -e
set -e

prefix=/usr
exec_prefix=/usr
libdir=/usr/lib

. \${libdir}/grub/grub-mkconfig_lib

COLOR_NORMAL="$COLOR_NORMAL/black"
COLOR_HIGHLIGHT="$COLOR_HIGHLIGHT/black"

if [ "\${GRUB_TERMINAL_OUTPUT}" = "gfxterm" ] ; then
        cat <<EOF
set color_normal=\${COLOR_NORMAL}
set color_highlight=\${COLOR_HIGHLIGHT}
EOF
else
  cat << EOF
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
EOF
fi
EOF05MENUCOLOR
chmod 0755 /etc/grub.d/05_menu_color
fi

}

function invalidHD {
	str="e[37;1m$devmap contains an orphan link: e[31;1m"$1"e[37;1m. Maybe you removed a hard disk since you installed Grub2. Either delete $devmap or edit the devices in this file to achieve a correct drive mapping. updateGrub2 can not work with an incorrect device.map.e[37;0m"
	printf "
%s

" "$str" | fmt
	exit
}

function efi_chainload {
# look for Linux bootloaders in the ESP on UEFI systems
for GREFI in $(find /boot/efi/EFI -name "$GRID" -o -name "$W7ID" 2>/dev/null | sed "/$BLID/d;s|Microsoft/Boot|windows|") ; do
	UUID=$($gprobe --target=fs_uuid $GREFI)
	t=$(echo ${GREFI%/*} | sed 's|.*/\(.\)\(.*\)|\U\1\E\2|')
	[ "$t" == "Windows" ] && T="$t x86_64 UEFI-GPT" || T="$t Grub"
	grep -q "$T" /etc/grub.d/40_custom && continue
	echo "chainloading $t ..."
	printf "
menuentry \"%s\" {
    insmod part_gpt
    insmod fat
    insmod search_fs_uuid
    insmod chain
    search --fs-uuid --no-floppy --set=root %s
    chainloader (\${root})%s
}
" "$T" "$UUID" "${GREFI/\/boot\/efi/}" >> $custom
done
}

function mbr_chainload {
# DEVICE/BIOS MAPPING
HDDEV=($(cat /proc/partitions | awk '!/major|dm/{ gsub(/[0-9]/,"",$4) ; print $4 }' | sort -u))
i=0
while [ $i -lt ${#HDDEV[li]} ] ; do eval ${HDDEV[$i]}=hd$i ; let i++ ; done
[/li]
# map hard disk devices to BIOS drives according to /boot/grub2/device.map (if this file exists)
if [ -f $devmap ] ; then
	devlinks=($(sed -n '/(hd/s|(\(.*\))[ 	][ 	]*\(.*\)|\2=\1|p' $devmap))
	if [ ${#devlinks[li]} -ge 1 ] ; then
[/li]		for dev in ${devlinks[li]} ; do
[/li]			sdx=${dev%=*} ; hdn=${dev#*=}
			if [ -b $sdx ] ; then
				[ -h $sdx ] && sdx=$(readlink $sdx)
			else
				invalidHD $sdx
			fi
			eval $(basename $sdx)=$hdn
		done
	fi
fi
DEVMAP=$(for d in ${HDDEV[li]} ; do printf "s|\\$\\$%s|%s|;" $d ${!d} ; done)
[/li]SKIPDEV=$(df -hl / /boot | awk '/^\/dev/ { print $1 }')
SKIPDEV=$(echo $SKIPDEV | tr " " "
" | sort -u | sed 's|/dev\(.*\)|\1\$/d;|')
devs=$(/sbin/fdisk -l 2>/dev/null | awk '/83/ { print $1 }' | sed -e "$SKIPDEV")

for dev in ${HDDEV[li]} $devs ; do
[/li]	if [ ${#dev} -eq 3 ] ; then
		CMT="$dev MBR"
		dev="/dev/$dev"
	else
		CMT="$dev"
	fi
	dd if=$dev bs=512 count=1 2>/dev/null | grep -q GRUB || continue
	D=${dev:0:8} ; D=${D##*/} ; N="${!D},msdos${dev:8}" 
	BS="BS$(hexdump -v -s 128 -n 2 -e '/1 "%x"' $dev)" ; BS=${!BS} ; T=${BS:-Grub}
	ORIGINAL_NAME="$T in $CMT"
	grep -q "${ORIGINAL_NAME}###" $custom && continue
	printf "
###Don't change this comment - UpdateGrub2 identifier: Original name: %s###
menuentry \"%s in %s \" {
    set root=(%s)
    chainloader +1
}
" "$ORIGINAL_NAME" "$T" "$dev" "$N" >> $custom
done
}


function update_menu {
	[ "$mkconfig" ] || exec echo "grub2 not found"
	if [ "$DISPLAYONLY" ] ; then
		echo "Scanning..."
		$mkconfig
	else
		if [ -d $gdir ] ; then
			[ "$ESP" ] && efi_chainload || mbr_chainload 
			$mkconfig -o $gmenu
			[ "$ESP" ] && cp $gmenu /boot/${ESP}/ 
		else
	  	    echo "Boot directory $gdir not found"
		fi
	fi
}


function restore_elilo {
[ $(efibootmgr | grep -c -i $BLID) -gt 1 ] && return

eliloPath=$(find /boot/efi -name "elilo.efi")
dev=$(grub2-probe -t device $eliloPath)
disk=${dev:0:8} ; part=${dev:8} 
eliloBldr=$(echo $eliloPath | sed 's|/boot/efi||;s|/|\\\\|g') 
efibootmgr --create --gpt --disk $disk --part $part --write-signature --label  "$DIST (elilo)" --loader "$eliloBldr"
}


function syntax {
cat << EOFHELP

$prg $version  - Grub2 install and boot menu update.

${G}Syntax:${N}  
  ${B}updateGrub2 [ options ]${N}

${G}Options:${N} 
    ${B}-n --noconfirm${N}           Installs packages and imports keys without asking for confirmation.
    ${B}-i --install [device]${N}    Installs Grub2 on UEFI systems.
                             On BIOS systems you have to specify a device. This option is ignored if
                             the root partition already contains Grub2 signature. Otherwise you will
                             be able to install Grub2 bootloader in any partition, including the MBR. 
                             Use this option with care! 
    ${B}-d --display${N}             Refreshes and prints the boot menu to standard output.
    ${B}-h --help${N}                Displays this help.

                             Without options, updateGrub2 scans for other OSes (provided os-prober is  
                             installed) and refreshes the boot entries in grub.cfg. The first time it
                             is run, it also modifies default settings, adds a script to /etc/grub.d, 
                             builds a missing font which prevents graphic mode from working, lets you
                             set a background image or uses the system default one.
EOFHELP
exit
}


# -------------------------------------------------

args=`getopt -q -u -o hndi:: -l help,noconfirm,display,install:: -- "$@"`
set -- $args

for i; do
	case "$i" in
	-n|--noconfirm) noconfirm="${dist_noconfirm}" ; autoimport="--gpg-auto-import-keys" ; shift ;;
	-i|--install) INSTALL=yes ; shift ;;
	-d|--display) DISPLAYONLY=yes ; shift ;;
	-h|--help) syntax ; shift ;;
	--) shift ; break ;;
	esac
done

gdev=$1 ; shift

case $UDISKS_PARTITION_SCHEME in
mbr)
EFI=""
ESP=""
grub2=""
[ "$(hexdump -v -s 128 -n  2 -e '/1 "%x"' $rootdev)" == "$GSIGN" ] && unset INSTALL
if [ "$INSTALL" == "yes" ] ; then
	[ "$gdev" ] || exec echo "Option --install requires an argument"
	[ -b  $gdev ] || exec echo "Destination is not a block device"
fi
;;
gpt)
EFI="-efi"
ESP="/efi/EFI/$BLID"
DIST="$dist $distver"
grub2="grub2"
;;
esac

grub="grub2$EFI"
mkconfig="${grub}-mkconfig"
ginstall="${grub}-install"
gprobe="${grub}-probe"
gdir="/boot/${grub}"
gmenu="$gdir/grub.cfg"
devmap="$gdir/device.map"
custom=/etc/grub.d/40_custom

if [ "$INSTALL" == "yes" ] ; then
	which os-prober &>/dev/null || install_osprober
	rpm -qa | grep -q $grub || install_pkg
	[ "$INSTALL" ] && install_grub
fi

gfx_menu
update_menu

I added support for chainloading. If you compare the functions efi_chainload and mbr_chainload in the code, you can see how UEFI can make multi-booting easy.

On UEFI systems, efi_chainload adds boot entries for Windows and other Linux 64 bit bootloaders.
On Legacy MBR systems, mbr_chainload adds boot entries for other Grub bootloaders (Legacy or Grub2) found in MBRs or partition boot sectors, except in the extended partition (because it wouldn’t boot).

In both grub2 and grub2-efi, the chainloader entries are written in** /etc/grub.d/40_custom**. Once an entry is present for a bootloader (found in a boot sector on BIOS systems or in the ESP on UEFI), updateGrub2 won’t add it again, hence the importance of the comment “* ###Don’t change this comment - UpdateGrub2 identifier: Original name*” similar to the one used by YaST, that you should NOT remove. But you can edit /etc/grub.d/40_custom and change menuentry titles as you like.

Most os-prober versions are buggy and drop kernel options (which might be necessary to boot) or use Linux device names in boot entries (which is bad). It affects updategrub, updateGrub2 as well as Ubuntu’s update-grub and all scripts that use os-prober (more exactly linux-boot-prober, I guess). It’s possible to write a workaround but it’s a lot of work again. I’d rather wait for an os-prober update. On the other hand, chainloader entries are safe, because they load the Grub of the OS you want to start, from where you can boot the native kernel with the correct boot options. Another solution is to copy/paste the boot entries found in the section ### BEGIN /etc/grub.d/10_linux ### in grub.cfg from one OS into the section ### BEGIN /etc/grub.d/30_os-prober ### of the other OS, but it won’t survive the next run or updateGrub2 (or update-grub under Ubuntu).

Notice that the command updategrub in the updategrub package is a symlink to the script updateLegacyGrub. If you are on a UEFI system, you will never use this command. The exception is Fedora’s Legacy grub-efi, which is supported now, but you have to remove grub-efi in order to install grub2-efi in Fedora, so you won’t probably never use updateLegacyGrub. Thus, in you are on a UEFI system, you can overwrite the symlink, so that it will point to updateGrub2 instead of updateLegacyGrub.

sudo ln -fs updateGrub2 /usr/bin/updategrub
  • The latest version has still not be published in OBS - it takes hours (or days). It’s getting worse and worse … Does anyone know why?

updateGrub2 can be used on (BIOS based) 12.2 M3 to refresh the boot menu as well as “improve” the original installation. I applied a minor change to the script because the path of the default background image is different under 12.2. That’s basically all I had to do to make it work under 12.2 - it already worked before, but failed to reboot in graphics mode (I’m talking about Grub’s graphical menu, not X !) Make sure you use version 1.3 of updateGrub2, which is included in updategrub-1.8.2 - updated today. I’ve been using updateGrub2 for a while now under openSUSE 12.1 and Fedora 16 to refresh the menu after a kernel update. As I already mentioned in other posts, it sometimes fail to add boot entries from other distros using Grub2, but never missed any Legacy Grub. This is due to a bug in os-prober. As soon as a partition has been mounted, it will find its kernel - even if you unmount the partition and scan again. I don’t know why. It might also add Fedora’s boot entries incompletely by simply ignoring the kernel options. That’s another os-prober bug. I might end up not using os-prober at all or just rewriting it from scratch. But for now it’s ok (I don’t have time). I’m sill hoping those bugs will get fixed in version 1.50.

To install updateGrub2, just install updategrub from my 12.1 repo. Notice that it won’t need to install os-prober - unlike under 12.1 - because it is already installed.


su -l
zypper ar [noparse]http://download.opensuse.org/repositories/home:/please_try_again/openSUSE_12.1/[/noparse]  PTA
zypper --gpg-auto-import-keys refresh -r PTA
zypper in updategrub

To use it, just type


updateGrub2

If you’re on a system with Grub2 only and don’t plan to install Legacy Grub, you may overwrite the updategrub symlink, as explained in the previous post. All right … I should change the default symlink so that it will point to updateGrub2 under 12.2 (but there aren’t 12.2 repos in OBS yet). Still I should to it … next time.

Here’s what updateGrub2 does when you run it the first time on a fresh openSUSE 12.2 M3:

  • installs gnu-unifont (say “y”) and builds the font unicode.pf2. It is needed for graphical menu.
  • gets a default background image (/usr/share/backgrounds/lightrays/morning-1280x1024.jpg under 12.2) and copies it to /boot/grub2 as the file splash.jpg
  • patches /etc/default/grub to set the background and enable GFXMODE.
  • writes the file /etc/grub.d/05_menu_color
  • scans for other Legacy and Grub2 boot loaders and writes chainload entries in /etc/grub.d/40_custom. This is NOT done by os-prober. This is an updategrub and updateGrub2 feature.
  • finally writes the menu /boot/grub/grub.cfg by running os-prober and adds the background image defined before. Of course you can (and I bet you will) change this background image. The easiest is to just overwrite the file /boot/grub2/splash.jpg with the picture of your choice and run updateGrub2 again.

Notice that you can use updateGrub2 to install Grub2 and Grub2-efi under 12.1 as well. It was primarily written for this purpose. It can also install Grub2-efi on Fedora (I don’t know if Fedora 17 uses Grub2-efi on UEFI systems. Fedora 16 does not - it uses grub-efi.)

What could go wrong?

Not much … but automatic graphical resolution might fail and you’ll see an “OUT OF RANGE” message at next boot. This is because I set the default to

GRUB_GFXMODE=auto

It worked fine with nvidia under 12.1 but failed with ATI under 12.2 M3. Should it happen …

  • Don’t panic!
  • Just wait! You’ll see a black screen for a while and the boot menu won’t appear, but the default system (obviously openSUSE 12.2) will boot after 60 seconds. Sorry for this timeout. After all, I write scripts to make my life easier, not just yours. :wink:
  • edit the file /etc/default/grub as root and replace
GRUB_GFXMODE=auto

with

GRUB_GFXMODE=800x600

This resolution is most likely to work on all systems. You may set a higher mode if your graphics card supports it (I bet it does).

  • run updateGrub2 again and enjoy that picture of Marie-Josée Croze . :stuck_out_tongue:

http://desmond.imageshack.us/Himg15/scaled.php?server=15&filename=updategrub01.png&res=crop](http://img15.imageshack.us/img15/1636/updategrub01.png)

  • well … this above is NOT Marie-Josée Croze, but only a screenshot of the installation.

I was wrong. It is actually not true. It occasionally misses Legacy Grub entries too. It’s still not fixed in os-prober 1.52 that I’m building in OBS right now. The simple workaround is to manually mount the partition.

I fixed that one. :slight_smile:

The problem was a wrong path in /usr/lib/linux-boot-probes/mounted/40grub2. It was looking for grub.cfg in /boot/grub while it should look in both locations /boot/grub2 (for openSUSE and Fedora) and /boot/grub (for Debian, Ubuntu, Mint, etc).

I submitted a bug report and a patch: Access Denied

Here’s the patch if you can not wait:

 
--- linux-boot-probes/mounted/40grub2.orig      2012-04-23 18:37:06.952422847 -0700
+++ linux-boot-probes/mounted/40grub2   2012-04-23 18:54:14.152780096 -0700
@@ -89,11 +89,17 @@
        entry_result
 }
 
-if  -e "$mpoint/boot/grub/grub.cfg" ] && \
+# fixes Grub2 menu patch for openSUSE and Fedora
+grubcfg=$mpoint/boot/grub/grub.cfg
+if  -e "$mpoint/boot/grub2/grub.cfg" ] ; then
+       grubcfg=$mpoint/boot/grub2/grub.cfg
+fi
+
+if  -e "$grubcfg" ] && \
    ( ! -e "$mpoint/boot/grub/menu.lst" ] || \
-     "$mpoint/boot/grub/grub.cfg" -nt "$mpoint/boot/grub/menu.lst" ]); then
+     "$grubcfg" -nt "$mpoint/boot/grub/menu.lst" ]); then
        debug "parsing grub.cfg"
-       parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$mpoint/boot/grub/grub.cfg"
+       parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$grubcfg"
 fi
 
 if  "$found_item" = 0 ]; then

You should run it from /usr/lib

cd /usr/lib
patch -b -p0 < /tmp/os-prober-40grub2.patch

You don’t need this patch to find Legacy Grub or Ubuntu’s boot entries (as I explained in the bug report, the path is correct in this case). You need this patch to find openSUSE 12.2 (or Fedora’s) kernel entries from anywhere else, such as openSUSE 11.4 or 12.1 if using updategrub or Ubuntu, Fedora or another openSUSE 12.2 installation with Grub2. I hope it’s clear … not sure though.

Here’s the latest updateGrub2 (for @rengejao to test it on ArchLinux).

#! /bin/bash
#
#: Title       : updateGrub2
#: Date Created: Sat Jan 14 22:34:57 PST 2012
#: Last Edit   : Sat Oct 20 15:04:56 PDT 2012
#: Author      : Agnelo de la Crotche (please_try_again)
#: Version     : 2.3
#: Description : install grub2, grub2-efi and refresh Grub2 menu
#: Requires    : os-prober
#: Usage       : updategrub2
#
# -----------------------------------------------

# variables you may modify. 

grub_timeout=60

# check the VESA resolutions available to your graphics card with hwinfo --framebuffer
# before changing this value. If you don't specify a video mode here, 'auto' will be used
# - it is often the the best choice. 

grub_gfx=800x600
#grub_gfx=1024x768x16
#grub_gfx=128x1024x16

# menu colors

COLOR_NORMAL="black"
COLOR_HIGHLIGHT="white"

# To use your own background image, put its path in the variable grub_bg
# and uncomment the line below 
# grub_bg=/usr/local/share/images/stellarcart.png

# You shouldn't need to change these values
unifont_url=http://unifoundry.com
unifont=unifont-5.1.20080820.bdf.gz

# -----------------------------------------------

# Do not modify the variables below!!!

# current version
version="2.3"
prg=$(basename $0)
declare -l	NOCONFIRM INSTALL BSD DISPLAYONLY BLID USEBG noconfirm autoimport gdev distcode grub_mkconfig_lib
GSIGN="020"
GRID="grubx64.efi"
W7ID="bootmgfw.efi"
USEBG=yes
G=$(tput setaf 2)
B=$(tput bold)
N=$(tput sgr0)
grub_mkconfig_lib=/usr/lib/grub/grub-mkconfig_lib
ALTERNATE=0

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Grub Bootsector ID at offset 0x80,81

BSaa75="Legacy Grub"
BS5272="Legacy Grub"
BS48b4="Grub 1.96"
BS488="Grub2 s core.img"
BS7c3c="Grub 1.98"
BS020="Grub 1.99"
BS8053="Lilo"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# Exit if we are not root
[ $(id -u) -gt 0 ] && exec echo "You need to run this script as root"

# We need lsb_release
which lsb_release &> /dev/null || exec cat << EOFLSB
Please install Linux Standard Base Release Tools
using this command: 

- under openSUSE:
  zypper in lsb_release
- under Fedora:
  yum install redhat-lsb  
- under ArchLinux:
  pacman -S lsb-release

EOFLSB
eval $(lsb_release -ircs | awk '{ sub(/SUSE LINUX/,"openSUSE", $0) ; printf "dist=%s;distver=%s;distcode=%s;", $1, $2, $3 }')
BLID=$dist

case $BLID in
opensuse|fedora|archlinux)
	[ "$distver" == "rolling" ] && distnum=0 || distnum=$((${distver/./}*1))
	case $distnum in
		121) bgsuse=upwind ;;
		122) bgsuse=lightrays ; grub_mkconfig_lib=/usr/share/grub2/grub-mkconfig_lib ;;
	esac
	
	# Default distro background image
	opensuse_bg=/usr/share/backgrounds/$bgsuse/morning-1280x1024.jpg
	fedora_bg=/usr/share/backgrounds/$distcode/default/standard/${distcode}.png
	archlinux_bg=/usr/share/archlinux/wallpaper/archlinux-arrival.jpg

	dist_bg=${BLID}_bg ; dist_bg=${!dist_bg} 
	[ "$grub_bg" ] && [ -f "$grub_bg" ] && dist_bg=$grub_bg
	[ -f $dist_bg ] && grub_bg=$dist_bg || unset USEBG
	
	opensuse_noconfirm="--non-interactive"
	fedora_noconfirm="--assumeyes"
	archlinux_noconfirm="--noconfirm"
	dist_noconfirm=${BLID}_noconfirm ; dist_noconfirm=${!dist_noconfirm}
;;
esac

rootdev=$(cat /etc/mtab | awk '/^\/dev/ { if ( $2 == "/" ) print $1 }')
eval $(udevadm info --query=all --name=$rootdev | awk '/UDISKS_PARTITION_SCHEME/ { print $2 }')


function install_osprober {
	case $BLID in
	opensuse) 
		PTA_repo="http://download.opensuse.org/repositories/home:/please_try_again/${dist}_${distver}/"
		zypper lr -u | grep -q ${PTA_repo} || zypper ar $PTA_repo PTA
		zypper -n $autoimport refresh -r PTA
		zypper $noconfirm in -r PTA os-prober
	;;
	fedora)
		yum $noconfirm install os-prober	
	;;
	archlinux)
		pacman -S os-prober
	;;
	esac
}

function install_pkg {
	case $BLID in
	opensuse) 
		zypper $noconfirm install $grub
	;;
	fedora)
		rpm -qa | grep -q "grub-efi" && yum $noconfirm remove grub-efi
		yum $noconfirm install $grub $grub2
	;;
	archlinux)
		pacman -S $grubpkg
	;;
	esac
}

function install_grub {
	if (  which $ginstall &>/dev/null ); then 
		if [ "$EFI" ] ; then
			[ -f /boot/$ESP/$GRID ] || $ginstall --bootloader-id=$BLID --no-floppy
		else
			eval $(udevadm info --query=property --name=$gdev | awk '/DEVTYPE/ { print }')
			case $DEVTYPE in
			disk)
				declare -l YESNO
				read -n 1 -s -p "Are you sure that you want to install Grub2 in MBR of $gdev? [yn] " YESNO
				[ "$YESNO" == "y" ] && $ginstall $gdev
			;;
			partition)
				if (  which $gprobe &>/dev/null ); then 
					[ "$($gprobe -d $gdev)" == "ext2" ] || exec echo "Destination is not an ext4 or ext3 partition" 
					$ginstall --force $gdev
				else
					exec printf "%s not found.
" $gprobe
				fi
			;;
			esac
		fi
	else
		exec printf "%s not found.
" $ginstall
	fi
}

function grub_font {
	case $BLID in
	opensuse)
		if [ ${distver/./} -lt 122 ] ; then
			zypper $noconfirm in gnu-unifont
			grub2-mkfont -o $gdir/unicode.pf2 /usr/share/fonts/uni/unifont.pcf.gz
		fi
	;;
	fedora)
		cd /tmp
		[ -f $unifont ] || wget ${unifont_url}/${unifont}
		[ -f $unifont ] || return
		gunzip $unifont
		grub2-mkfont -o $gdir/unicode.pf2 $(basename $unifont .gz)
	;;
	esac	
}

function gfx_menu {
[ -f $gdir/unicode.pf2 ] || grub_font

if [ "$USEBG" == "yes" ] ; then
	splashsrc=$grub_bg ; splash=splash.${splashsrc##*.}
	[ -f $gdir/$splash ] || cp $grub_bg $gdir/$splash
fi

if [ ! -f /etc/default/grub.orig -a -f /etc/default/grub  ] ; then
	echo "- patching /etc/default/grub ..."
	grub_timeout=${grub_timeout:-10}
	cp /etc/default/grub{,.orig}
	grub_gfx=${grub_gfx:-auto}
	grep -q "GRUB_GFXMODE" /etc/default/grub || echo "#GRUB_GFXMODE=640x480" >> /etc/default/grub
	cat << EOFGRUBDEFAULT | sed -i -f - /etc/default/grub
s|GRUB_TIMEOUT=.*|GRUB_TIMEOUT=$grub_timeout|
s|#GRUB_GFXMODE=640x480|GRUB_GFXMODE=$grub_gfx|
/GRUB_GFXMODE/ a\
GRUB_GFXPAYLOAD_LINUX=keep
EOFGRUBDEFAULT
if [ -f $gdir/$splash ] ; then
	cat << EOFGRUBDEFAULT2 | sed -i -f - /etc/default/grub
/GRUB_GFXMODE/ a\
GRUB_BACKGROUND=$gdir/$splash
EOFGRUBDEFAULT2
fi
fi

if [ ! -f /etc/grub.d/05_menu_color ] ; then
	cat > /etc/grub.d/05_menu_color << EOF05MENUCOLOR
#!/bin/sh -e
set -e

prefix=/usr
exec_prefix=/usr

. $grub_mkconfig_lib

COLOR_NORMAL="$COLOR_NORMAL/black"
COLOR_HIGHLIGHT="$COLOR_HIGHLIGHT/black"

if [ "\${GRUB_TERMINAL_OUTPUT}" = "gfxterm" ] ; then
        cat <<EOF
set color_normal=\${COLOR_NORMAL}
set color_highlight=\${COLOR_HIGHLIGHT}
EOF
else
  cat << EOF
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
EOF
fi
EOF05MENUCOLOR
chmod 0755 /etc/grub.d/05_menu_color
fi

}

function invalidHD {
	str="e[37;1m$devmap contains an orphan link: e[31;1m"$1"e[37;1m. Maybe you removed a hard disk since you installed Grub2. Either delete $devmap or edit the devices in this file to achieve a correct drive mapping. updateGrub2 can not work with an incorrect device.map.e[37;0m"
	printf "
%s

" "$str" | fmt
	exit
}

function efi_chainload {
# look for Linux bootloaders in the ESP on UEFI systems
[ $ALTERNATE -gt 0 ] && return
for GREFI in $(find /boot/efi/EFI -name "$GRID" -o -name "$W7ID" 2>/dev/null | sed "/$BLID/d;s|Microsoft/Boot|windows|") ; do
	UUID=$($gprobe --target=fs_uuid $GREFI)
	t=$(echo ${GREFI%/*} | sed 's|.*/\(.\)\(.*\)|\U\1\E\2|')
	[ "$t" == "Windows" ] && T="$t x86_64 UEFI-GPT" || T="$t Grub"
	grep -q "$T" /etc/grub.d/40_custom && continue
	echo "chainloading $t ..."
	printf "
menuentry \"%s\" {
    insmod part_gpt
    insmod fat
    insmod search_fs_uuid
    insmod chain
    search --fs-uuid --no-floppy --set=root %s
    chainloader (\${root})%s
}
" "$T" "$UUID" "${GREFI/\/boot\/efi/}" >> $custom
done
}

function mbr_chainload {
# DEVICE/BIOS MAPPING
HDDEV=($(cat /proc/partitions | awk '!/major|dm/{ gsub(/[0-9]/,"",$4) ; print $4 }' | sort -u))
i=0
while [ $i -lt ${#HDDEV[li]} ] ; do eval ${HDDEV[$i]}=hd$i ; let i++ ; done
[/li]
# map hard disk devices to BIOS drives according to /boot/grub2/device.map (if this file exists)
if [ -f $devmap ] ; then
	devlinks=($(sed -n '/(hd/s|(\(.*\))[ 	][ 	]*\(.*\)|\2=\1|p' $devmap))
	if [ ${#devlinks[li]} -ge 1 ] ; then
[/li]		for dev in ${devlinks[li]} ; do
[/li]			sdx=${dev%=*} ; hdn=${dev#*=}
			if [ -b $sdx ] ; then
				[ -h $sdx ] && sdx=$(readlink $sdx)
			else
				invalidHD $sdx
			fi
			eval $(basename $sdx)=$hdn
		done
	fi
fi
DEVMAP=$(for d in ${HDDEV[li]} ; do printf "s|\\$\\$%s|%s|;" $d ${!d} ; done)
[/li]SKIPDEV=$(df -hl / /boot | awk '/^\/dev/ { print $1 }')
SKIPDEV=$(echo $SKIPDEV | tr " " "
" | sort -u | sed 's|/dev\(.*\)|\1\$/d;|')
devs=$(/sbin/fdisk -l 2>/dev/null | awk '/83/ { print $1 }' | sed -e "$SKIPDEV")

for dev in ${HDDEV[li]} $devs ; do
[/li]	if [ ${#dev} -eq 3 ] ; then
		CMT="$dev MBR"
		dev="/dev/$dev"
	else
		CMT="$dev"
	fi
	dd if=$dev bs=512 count=1 2>/dev/null | grep -q GRUB || continue
	D=${dev:0:8} ; D=${D##*/} ; N="${!D},msdos${dev:8}" 
	BS="BS$(hexdump -v -s 128 -n 2 -e '/1 "%x"' $dev)" ; BS=${!BS} ; T=${BS:-Grub}
	ORIGINAL_NAME="$T in $CMT"
	grep -q "${ORIGINAL_NAME}###" $custom && continue
	printf "
###Don't change this comment - UpdateGrub2 identifier: Original name: %s###
menuentry \"%s in %s \" {
    set root=(%s)
    chainloader +1
}
" "$ORIGINAL_NAME" "$T" "$dev" "$N" >> $custom
done
}

function alt_linux {
	if [ -f /etc/grub.d/30_os-prober_alt ]; then
		case $1 in
		on)
			if [ -x /etc/grub.d/10_linux ]; then
				cp /etc/grub.d/10_linux{,.org}
				chmod 644 /etc/grub.d/10_linux.org
				sed -i '/gettext_/s/, with Linux/ - kernel/;s/OS="${GRUB_DISTRIBUTOR} Linux"/OS="${GRUB_DISTRIBUTOR}"/' /etc/grub.d/10_linux
			fi
			if [ -x /etc/grub.d/30_os-prober -a -f /etc/grub.d/30_os-prober_alt ] ; then
				chmod 644 /etc/grub.d/30_os-prober
				chmod 755 /etc/grub.d/30_os-prober_alt
			fi
		;;
		off)
			if [ -f /etc/grub.d/10_linux.org ]; then
				mv /etc/grub.d/10_linux{.org,}
				chmod 755 /etc/grub.d/10_linux
			fi
			if [ -x /etc/grub.d/30_os-prober_alt -a -f /etc/grub.d/30_os-prober ] ; then
		 		if [ $ALTERNATE -eq 1 ] ; then
					chmod 755 /etc/grub.d/30_os-prober
					chmod 644 /etc/grub.d/30_os-prober_alt
				fi
			fi
		;;
		esac
	else
		printf "WARNING: /etc/grub.d/30_os-prober_alt not found. Alternate script not used.
"
	fi
}

function update_menu {
	[ "$mkconfig" ] || exec echo "grub2 not found"
	if [ "$DISPLAYONLY" ] ; then
		echo "Scanning..."
		$mkconfig
	else
		if [ -d $gdir ] ; then
			[ "$ESP" ] && efi_chainload || mbr_chainload 
			$mkconfig -o $gmenu
			[ "$ESP" ] && cp $gmenu /boot/${ESP}/ 
		else
	  	    echo "Boot directory $gdir not found"
		fi
	fi
}


function restore_elilo {
[ $(efibootmgr | grep -c -i $BLID) -gt 1 ] && return

eliloPath=$(find /boot/efi -name "elilo.efi")
dev=$(grub2-probe -t device $eliloPath)
disk=${dev:0:8} ; part=${dev:8} 
eliloBldr=$(echo $eliloPath | sed 's|/boot/efi||;s|/|\\\\|g') 
efibootmgr --create --gpt --disk $disk --part $part --write-signature --label  "$DIST (elilo)" --loader "$eliloBldr"
}


function syntax {
cat << EOFHELP

$prg $version  - Grub2 install and boot menu update.

${G}Syntax:${N}  
  ${B}updateGrub2 [ options ]${N}

${G}Options:${N} 
    ${B}-n --noconfirm${N}           Install packages and import keys without asking for confirmation.
                             Requires a version of os-prober which mounts ufs1 and ufs2 correctly
                             and includes os probes for BSDs (like 1.53a in my repo!).
    ${B}-i --install [device]${N}    Install Grub2 on UEFI systems.
                             On BIOS systems you have to specify a device. This option is ignored if
                             the root partition already contains Grub2 signature. Otherwise you will
                             be able to install Grub2 bootloader in any partition, including the MBR. 
                             Use this option with care! 
    ${B}-d --display${N}             Refresh and print the boot menu to standard output.
    ${B}-a --alternate${N}           Use alternate os-prober script.
    ${B}-A --Alternate${N}           Permanently use alternate os-prober script.
    ${B}-h --help${N}                Displays this help.

                             Without options, updateGrub2 scans for other OSes (provided os-prober is  
                             installed) and refreshes the boot entries in grub.cfg. The first time it
                             is run, it also modifies default settings, adds a script to /etc/grub.d, 
                             builds a missing font which prevents graphic mode from working, lets you
                             set a background image or uses the system default one.
EOFHELP
exit
}


# -------------------------------------------------

args=`getopt -q -u -o haAnbdi:: -l help,alternate,Alternate,noconfirm,bsd,display,install:: -- "$@"`
set -- $args

for i; do
	case "$i" in
	-n|--noconfirm) noconfirm="${dist_noconfirm}" ; autoimport="--gpg-auto-import-keys" ; shift ;;
	-i|--install) INSTALL=yes ; shift ;;
	-d|--display) DISPLAYONLY=yes ; shift ;;
	-a|--alternate) ALTERNATE=1 ; shift ;;
	-A|--Alternate) ALTERNATE=2 ; shift ;;
	-h|--help) syntax ; shift ;;
	--) shift ; break ;;
	esac
done

gdev=$1 ; shift

case $UDISKS_PARTITION_SCHEME in
mbr)
EFI=""
ESP=""
grub2=""
[ "$(hexdump -v -s 128 -n  2 -e '/1 "%x"' $rootdev)" == "$GSIGN" ] && unset INSTALL
if [ "x$INSTALL" == "xyes" ] ; then
	[ "$gdev" ] || exec echo "Option --install requires an argument"
	[ -b  $gdev ] || exec echo "Destination is not a block device"
fi
;;
gpt)
EFI="-efi"
ESP="/efi/EFI/$BLID"
DIST="$dist $distver"
grub2="grub2"
;;
esac

case $BLID in 
	opensuse|fedora) grub="grub2$EFI" ;;
	archlinux)
		grub="grub$EFI"
		mac=$(uname -m)
		[ "$mac" == "x86_64" ] || mac=i386
		EFI=${EFI:+${mac}${EFI}}
		BIOS=${EFI:--bios}
		grubpkg="grub$BIOS"
		;;
	*) grub="grub$EFI" ;;
esac

	
mkconfig="${grub}-mkconfig"
ginstall="${grub}-install"
gprobe="${grub}-probe"
gdir="/boot/${grub}"
gmenu="$gdir/grub.cfg"
devmap="$gdir/device.map"
custom=/etc/grub.d/40_custom

if [ "x$INSTALL" == "xyes" ] ; then
	if [ $distnum -ge 122 ] ; then
		printf "updateGrub2 should not be used to install Grub2 on openSUSE >= 12.2
"
	else
		which os-prober &>/dev/null || install_osprober
		case $BLID in
			opensuse|fedora) rpm -qa | grep -q $grub || install_pkg ;;
			archlinux) pacman -Q | grep -q $grubpkg || install_pkg ;;
		esac
		[ "$INSTALL" ] && install_grub
	fi
fi

[ "$BLID" == "opensuse" -o "$BLID" == "fedora" ] && gfx_menu

if [ $ALTERNATE -gt 0 ] ; then
	alt_linux on
	update_menu
	alt_linux off
else
	update_menu
fi

Here is the result:
I’ve let my system as it is, /etc/grub.d/30_os-prober is disabled (non executable(?)).
09_openSUSE, 11_Windows, and 12_openSUSE_failsafe are scripts I’ve added in /etc/grub.d

[root@Archy bin]# ./updateGrub2-2.3 -d
Scanning...
Création de grub.cfg…
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
insmod part_gpt
insmod part_msdos
if  -s $prefix/grubenv ]; then
  load_env
fi
set default="0"

if  x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if  "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if  -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}

function load_video {
  if  x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}

if  x$feature_default_font_path = xy ] ; then
   font=unicode
else
insmod part_msdos
insmod ext2
set root='hd2,msdos5'
if  x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos5 --hint-efi=hd2,msdos5 --hint-baremetal=ahci2,msdos5  875955d0-d822-4f3a-86d1-e38f15965bba
else
  search --no-floppy --fs-uuid --set=root 875955d0-d822-4f3a-86d1-e38f15965bba
fi
    font="/usr/share/grub/unicode.pf2"
fi

if loadfont $font ; then
  set gfxmode=800x600
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=fr_CH
  insmod gettext
fi
terminal_input console
terminal_output gfxterm
Thème trouvé : /boot/grub/themes/archlinux/theme.txt
insmod part_msdos
insmod ext2
set root='hd2,msdos5'
if  x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos5 --hint-efi=hd2,msdos5 --hint-baremetal=ahci2,msdos5  875955d0-d822-4f3a-86d1-e38f15965bba
else
  search --no-floppy --fs-uuid --set=root 875955d0-d822-4f3a-86d1-e38f15965bba
fi
insmod gfxmenu
loadfont ($root)/boot/grub/themes/archlinux/dejavu_mono_14.pf2
loadfont ($root)/boot/grub/themes/archlinux/dejavu_sans_14.pf2
loadfont ($root)/boot/grub/themes/archlinux/dejavu_sans_bold_14.pf2
insmod png
set theme=($root)/boot/grub/themes/archlinux/theme.txt
export theme
set timeout=60
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/05_menu_color ###
set color_normal=black/black
set color_highlight=white/black
### END /etc/grub.d/05_menu_color ###

### BEGIN /etc/grub.d/09_openSUSE ###
menuentry 'openSUSE 12.1' --class openSUSE --class gnu-linux --class gnu --class os  'osprober-gnulinux-simple-40232fc8-8a28-443c-85db-5cd8284a7753' {
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos2'
	if  x = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos2 --hint-efi=hd2,msdos2 --hint-baremetal=ahci2,msdos2  40232fc8-8a28-443c-85db-5cd8284a7753
	else
	  search --no-floppy --fs-uuid --set=root 40232fc8-8a28-443c-85db-5cd8284a7753
	fi
	linux /boot/vmlinuz-3.1.10-1.16-default root=/dev/disk/by-id/ata-SAMSUNG_HD322HJ_S17AJ9DSA16936-part2 resume=/dev/disk/by-id/ata-SAMSUNG_HD322HJ_S17AJ9DSA16936-part1 splash=silent quiet showopts
	initrd /boot/initrd-3.1.10-1.16-default
}
### END /etc/grub.d/09_openSUSE ###

### BEGIN /etc/grub.d/10_linux ###
Image Linux trouvée : /boot/vmlinuz-linux
Image mémoire initiale trouvée : /boot/initramfs-linux.img
menuentry 'Arch GNU/Linux, avec Linux core repo kernel' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-core repo kernel-true-875955d0-d822-4f3a-86d1-e38f15965bba' {
	load_video
	set gfxpayload=keep
	insmod gzio
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos5'
	if  x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos5 --hint-efi=hd2,msdos5 --hint-baremetal=ahci2,msdos5  875955d0-d822-4f3a-86d1-e38f15965bba
	else
	  search --no-floppy --fs-uuid --set=root 875955d0-d822-4f3a-86d1-e38f15965bba
	fi
	echo	'Chargement de Linux core repo kernel…'
	linux	/boot/vmlinuz-linux root=UUID=875955d0-d822-4f3a-86d1-e38f15965bba ro  quiet
	echo	'Chargement du disque mémoire initial…'
	initrd	/boot/initramfs-linux.img
}
menuentry 'Arch GNU/Linux, with Linux core repo kernel (Fallback initramfs)' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-core repo kernel-fallback-875955d0-d822-4f3a-86d1-e38f15965bba' {
	load_video
	set gfxpayload=keep
	insmod gzio
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos5'
	if  x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos5 --hint-efi=hd2,msdos5 --hint-baremetal=ahci2,msdos5  875955d0-d822-4f3a-86d1-e38f15965bba
	else
	  search --no-floppy --fs-uuid --set=root 875955d0-d822-4f3a-86d1-e38f15965bba
	fi
	echo	'Chargement de Linux core repo kernel…'
	linux	/boot/vmlinuz-linux root=UUID=875955d0-d822-4f3a-86d1-e38f15965bba ro  quiet
	echo	'Chargement du disque mémoire initial…'
	initrd	/boot/initramfs-linux-fallback.img
}

### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/11_Windows ###
menuentry 'windows XP' --class windows --class os  'osprober-chain-E22CA44F2CA42091' {
	insmod part_msdos
	insmod ntfs
	set root='hd0,msdos1'
	if  x = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  E22CA44F2CA42091
	else
	  search --no-floppy --fs-uuid --set=root E22CA44F2CA42091
	fi
	drivemap -s hd0 hd1
#	drivemap -s (hd0) 
	chainloader +1
}
### END /etc/grub.d/11_Windows ###

### BEGIN /etc/grub.d/12_openSUSE_failsafe ###
menuentry 'Failsafe -- openSUSE 12.1' --class openSUSE --class gnu-linux --class gnu --class os  'osprober-gnulinux-/boot/vmlinuz-3.1.10-1.16-default--40232fc8-8a28-443c-85db-5cd8284a7753' {
		insmod part_msdos
		insmod ext2
		set root='hd2,msdos2'
		if  x = xy ]; then
		  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos2 --hint-efi=hd2,msdos2 --hint-baremetal=ahci2,msdos2  40232fc8-8a28-443c-85db-5cd8284a7753
		else
		  search --no-floppy --fs-uuid --set=root 40232fc8-8a28-443c-85db-5cd8284a7753
		fi
		linux /boot/vmlinuz-3.1.10-1.16-default root=/dev/disk/by-id/ata-SAMSUNG_HD322HJ_S17AJ9DSA16936-part2 showopts apm=off noresume nosmp maxcpus=0 edd=off powersaved=off nohz=off highres=off processor.max_cstate=1 nomodeset x11failsafe vga=0x345
		initrd /boot/initrd-3.1.10-1.16-default
	}
### END /etc/grub.d/12_openSUSE_failsafe ###

### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###

### BEGIN /etc/grub.d/20_memtest86+ ###
### END /etc/grub.d/20_memtest86+ ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if  -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif  -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###
fait

OK. 09_opensuse is not that good. You should execute 10_linux before foreign OSes. What is executable will be executed and what is not executable won’t be executed. But why do you want to do os-prober’s job? updateGrub2 is not helpful in this case.

updateGrub2 takes a different approach:

  • it writes chainloaders entries in /etc/grub.d/40_custom for other boot loaders if they don’t already exist, meaning it does that only once. I just noticed that the syntax I use to chainload MBRs is wrong. It should be:
set root=(hd0)

and not

set root=(hd0,msdos)

I’ll have to fix that.

  • it let you sort or skip boot entries according to 2 variables you can set in /etc/default/grub. Here’s what I use:

GRUB_OS_PROBER_SORT="Ubuntu Mint openSUSE Mandriva Fedora Arch Debian Gentoo FreeBSD NetBSD OpenBSD Windows"
GRUB_OS_PROBER_SKIP="recovery failsafe fallback single-user"

It means that I want the OS entries appear in this order and I don’t want to add boot entries which contain any of the words in GRUB_OS_PROBER_SKIP.

  • Finally when used with option -a (or -ad if you just want do print the menu to standard output), it will use an alternate 30_os-prober script called 30_os-prober_alt. This script is included in updategrub package for openSUSE and could be used under ArchLinux as well. I do not guarantee that you won’t need to modify a path, but it’s uncomplicated.

A couple features - such as Unix ufs2 support and menus for the different BSD OSes - are only available if you use my os-prober build.

That’s what I’ve done. And then I’ve copied the entry in a separated script.

What is executable will be executed and what is not executable won’t be executed.

That’s exactly what I want.

But why do you want to do os-prober’s job?

Because os-prober don’t make the menu like I want. I know it’s possible to modify the os-prober script, to change the text menu, or the order of detection’s os, but it’s too difficult, and “dangerous” for me. I’ve choose the safer way. If I have a problem, I chroot and reactive os-prober, and then I can regenerate a working menu.
…And I have to take the time do the same with the archlinux entries because I don’t (often) need the rescue entry, and I want to put it in the end, with the openSUSE one.

updateGrub2 is not helpful in this case.

I know. I test your script just for fun (and to help you), but I don’t really need it.
I hope you dont make all these changes just for me… no you don’t! I’m sure of it. lol!

I think I’ve not understand… So forget my response, I was taking about the os-prober script…:stuck_out_tongue:

edit: I’ve understand! 10_linux in my case, is for archlinux, and I want to have the openSUSE entry at the first place.

Here is the place I found this idea: GRUB 2 bootloader - Full tutorial
And there, they explain how to change the 30_os-prober, and 10_linux scripts: Ubuntu install: GRUB2 title tweaks

Cool! I didn’t know your script do that.
As you can see I spend long time to read and understand all you write. :stuck_out_tongue:

New result, with your script fully utilized!

#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
insmod part_gpt
insmod part_msdos
if  -s $prefix/grubenv ]; then
  load_env
fi
set default="0"

if  x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if  "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if  -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}

function load_video {
  if  x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}

if  x$feature_default_font_path = xy ] ; then
   font=unicode
else
insmod part_msdos
insmod ext2
set root='hd2,msdos5'
if  x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos5 --hint-efi=hd2,msdos5 --hint-baremetal=ahci2,msdos5 --hint='hd2,msdos5'  875955d0-d822-4f3a-86d1-e38f15965bba
else
  search --no-floppy --fs-uuid --set=root 875955d0-d822-4f3a-86d1-e38f15965bba
fi
    font="/usr/share/grub/unicode.pf2"
fi

if loadfont $font ; then
  set gfxmode=800x600
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=fr_CH
  insmod gettext
fi
terminal_input console
terminal_output gfxterm
insmod part_msdos
insmod ext2
set root='hd2,msdos5'
if  x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos5 --hint-efi=hd2,msdos5 --hint-baremetal=ahci2,msdos5 --hint='hd2,msdos5'  875955d0-d822-4f3a-86d1-e38f15965bba
else
  search --no-floppy --fs-uuid --set=root 875955d0-d822-4f3a-86d1-e38f15965bba
fi
insmod gfxmenu
loadfont ($root)/boot/grub/themes/archlinux/dejavu_mono_14.pf2
loadfont ($root)/boot/grub/themes/archlinux/dejavu_sans_14.pf2
loadfont ($root)/boot/grub/themes/archlinux/dejavu_sans_bold_14.pf2
insmod png
set theme=($root)/boot/grub/themes/archlinux/theme.txt
export theme
set timeout=60
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/05_menu_color ###
set color_normal=black/black
set color_highlight=white/black
### END /etc/grub.d/05_menu_color ###

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Arch GNU/Linux, avec Linux core repo kernel' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-core repo kernel-true-875955d0-d822-4f3a-86d1-e38f15965bba' {
	load_video
	set gfxpayload=keep
	insmod gzio
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos5'
	if  x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos5 --hint-efi=hd2,msdos5 --hint-baremetal=ahci2,msdos5 --hint='hd2,msdos5'  875955d0-d822-4f3a-86d1-e38f15965bba
	else
	  search --no-floppy --fs-uuid --set=root 875955d0-d822-4f3a-86d1-e38f15965bba
	fi
	echo	'Chargement de Linux core repo kernel…'
	linux	/boot/vmlinuz-linux root=UUID=875955d0-d822-4f3a-86d1-e38f15965bba ro  quiet
	echo	'Chargement du disque mémoire initial…'
	initrd	/boot/initramfs-linux.img
}
menuentry 'Arch GNU/Linux, with Linux core repo kernel (Fallback initramfs)' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-core repo kernel-fallback-875955d0-d822-4f3a-86d1-e38f15965bba' {
	load_video
	set gfxpayload=keep
	insmod gzio
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos5'
	if  x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos5 --hint-efi=hd2,msdos5 --hint-baremetal=ahci2,msdos5 --hint='hd2,msdos5'  875955d0-d822-4f3a-86d1-e38f15965bba
	else
	  search --no-floppy --fs-uuid --set=root 875955d0-d822-4f3a-86d1-e38f15965bba
	fi
	echo	'Chargement de Linux core repo kernel…'
	linux	/boot/vmlinuz-linux root=UUID=875955d0-d822-4f3a-86d1-e38f15965bba ro  quiet
	echo	'Chargement du disque mémoire initial…'
	initrd	/boot/initramfs-linux-fallback.img
}

### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###

### BEGIN /etc/grub.d/20_memtest86+ ###
### END /etc/grub.d/20_memtest86+ ###

### BEGIN /etc/grub.d/30_os-prober ###
menuentry 'Microsoft Windows XP Professionnel (sur /dev/sda1)' --class windows --class os $menuentry_id_option 'osprober-chain-E22CA44F2CA42091' {
	insmod part_msdos
	insmod ntfs
	set root='hd0,msdos1'
	if  x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  E22CA44F2CA42091
	else
	  search --no-floppy --fs-uuid --set=root E22CA44F2CA42091
	fi
	drivemap -s (hd0) ${root}
	chainloader +1
}
menuentry 'openSUSE 12.1 (i586)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-simple-40232fc8-8a28-443c-85db-5cd8284a7753' {
	insmod part_msdos
	insmod ext2
	set root='hd2,msdos2'
	if  x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos2 --hint-efi=hd2,msdos2 --hint-baremetal=ahci2,msdos2 --hint='hd2,msdos2'  40232fc8-8a28-443c-85db-5cd8284a7753
	else
	  search --no-floppy --fs-uuid --set=root 40232fc8-8a28-443c-85db-5cd8284a7753
	fi
	linux /boot/vmlinuz-3.1.10-1.16-default root=/dev/disk/by-id/ata-SAMSUNG_HD322HJ_S17AJ9DSA16936-part2 resume=/dev/disk/by-id/ata-SAMSUNG_HD322HJ_S17AJ9DSA16936-part1 splash=silent quiet showopts
	initrd /boot/initrd-3.1.10-1.16-default
}
submenu 'Options avancées pour openSUSE 12.1 (i586)' $menuentry_id_option 'osprober-gnulinux-advanced-40232fc8-8a28-443c-85db-5cd8284a7753' {
	menuentry 'openSUSE 12.1 - 3.1.10-1.16 (sur /dev/sdc2)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/boot/vmlinuz-3.1.10-1.16-default--40232fc8-8a28-443c-85db-5cd8284a7753' {
		insmod part_msdos
		insmod ext2
		set root='hd2,msdos2'
		if  x$feature_platform_search_hint = xy ]; then
		  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos2 --hint-efi=hd2,msdos2 --hint-baremetal=ahci2,msdos2 --hint='hd2,msdos2'  40232fc8-8a28-443c-85db-5cd8284a7753
		else
		  search --no-floppy --fs-uuid --set=root 40232fc8-8a28-443c-85db-5cd8284a7753
		fi
		linux /boot/vmlinuz-3.1.10-1.16-default root=/dev/disk/by-id/ata-SAMSUNG_HD322HJ_S17AJ9DSA16936-part2 resume=/dev/disk/by-id/ata-SAMSUNG_HD322HJ_S17AJ9DSA16936-part1 splash=silent quiet showopts
		initrd /boot/initrd-3.1.10-1.16-default
	}
	menuentry 'Failsafe -- openSUSE 12.1 - 3.1.10-1.16 (sur /dev/sdc2)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/boot/vmlinuz-3.1.10-1.16-default--40232fc8-8a28-443c-85db-5cd8284a7753' {
		insmod part_msdos
		insmod ext2
		set root='hd2,msdos2'
		if  x$feature_platform_search_hint = xy ]; then
		  search --no-floppy --fs-uuid --set=root --hint-bios=hd2,msdos2 --hint-efi=hd2,msdos2 --hint-baremetal=ahci2,msdos2 --hint='hd2,msdos2'  40232fc8-8a28-443c-85db-5cd8284a7753
		else
		  search --no-floppy --fs-uuid --set=root 40232fc8-8a28-443c-85db-5cd8284a7753
		fi
		linux /boot/vmlinuz-3.1.10-1.16-default root=/dev/disk/by-id/ata-SAMSUNG_HD322HJ_S17AJ9DSA16936-part2 showopts apm=off noresume nosmp maxcpus=0 edd=off powersaved=off nohz=off highres=off processor.max_cstate=1 nomodeset x11failsafe vga=0x345
		initrd /boot/initrd-3.1.10-1.16-default
	}
}

### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.

###Don't change this comment - UpdateGrub2 identifier: Original name: Legacy Grub in sda MBR###
menuentry "Legacy Grub in /dev/sda " {
    set root=(hd0,msdos)
    chainloader +1
}

###Don't change this comment - UpdateGrub2 identifier: Original name: Grub 1.99 in sdc MBR###
menuentry "Grub 1.99 in /dev/sdc " {
    set root=(hd2,msdos)
    chainloader +1
}

###Don't change this comment - UpdateGrub2 identifier: Original name: Legacy Grub in /dev/sdc2###
menuentry "Legacy Grub in /dev/sdc2 " {
    set root=(hd2,msdos2)
    chainloader +1
}
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if  -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif  -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###

Comment on the french forum. :wink:

OK. That’s the way to achieve this result. It’s not very conventional but it works.

Rather than changing 30_os-prober, I would copy 30_os-prober into 30_os-prober_alt and apply your changes in this file, leave 30_os-prober executable and 30_os-prober_alt non exectuable, run updateGrub2 with the option -a, and updateGrub2 will take care of the rest. If ever you wish to use the original 30_os-prober, run updateGrub2 without option -a. If you installed the latest updategrub package under openSUSE, copy the man page (openSUSE)/usr/share/man/man1/updateGrub2.1.gz to /usr/share/man/man1 in ArchLinux and have a look at it.

updateGrub2 also slightly modified 10_linux to print a more consistant description of the OS (IMO). But it restores the change afterwards. Thus after updateGrub2 -a has updated the menu, both 10_linux and 30_os-prober scripts are back to their original state, which I believe is better and safer.

It is not multilingual though. It will have no effect in your case.

if  -x /etc/grub.d/10_linux ]; then
	cp /etc/grub.d/10_linux{,.org}
	chmod 644 /etc/grub.d/10_linux.org
	sed -i '/gettext_/s/, **with** Linux/ - kernel/;s/OS="${GRUB_DISTRIBUTOR} Linux"/OS="${GRUB_DISTRIBUTOR}"/' /etc/grub.d/10_linux
fi

but

There must be a little bug in your 10_linux. The translator has not done his job completely. :wink:

And I don’t know what ArchLinux put in GRUB_DISTRIBUTOR in /etc/grub/default or even if it uses this variable. But you could still define it and write any description you like. I personnally use this in openSUSE:

GRUB_DISTRIBUTOR="openSUSE 12.2 (Mantis)"
The openSUSE 12.2 rpm creates a symlink “updategrub” which points to updateGrub2. You might want to do the same under ArchLinux. Similarly the openSUSE 12.1 rpm creates a symlink “updategrub” which points to updateLegacyGrub.

.

OK. I’ll meet you there.

I’m using opensuse 12.3 KDE would be safe to run updategrub? (I’ve installed 12.2 version of your program/script )