mirror of
				https://git.proxmox.com/git/grub2
				synced 2025-10-31 03:50:11 +00:00 
			
		
		
		
	 382eda4503
			
		
	
	
		382eda4503
		
	
	
	
	
		
			
			If other operating systems are installed, then automatically unhide the menu. Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus if available to check whether Shift is pressed. If it is, show the menu, otherwise boot immediately. If keystatus is not available, then fall back to a short delay interruptible with Escape. This may or may not remain Ubuntu-specific, although it's not obviously wanted upstream. It implements a requirement of https://wiki.ubuntu.com/DesktopExperienceTeam/KarmicBootExperienceDesignSpec#Bootloader. If the previous boot failed (defined as failing to get to the end of one of the normal runlevels), then show the boot menu regardless. Author: Richard Laager <rlaager@wiktel.com> Author: Robie Basak <robie.basak@ubuntu.com> Forwarded: no Last-Update: 2015-09-04 Patch-Name: quick_boot.patch
		
			
				
	
	
		
			304 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| #! /bin/sh
 | |
| set -e
 | |
| 
 | |
| # grub-mkconfig helper script.
 | |
| # Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
 | |
| #
 | |
| # GRUB 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 3 of the License, or
 | |
| # (at your option) any later version.
 | |
| #
 | |
| # GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| prefix="@prefix@"
 | |
| exec_prefix="@exec_prefix@"
 | |
| datarootdir="@datarootdir@"
 | |
| ubuntu_recovery="@UBUNTU_RECOVERY@"
 | |
| quiet_boot="@QUIET_BOOT@"
 | |
| quick_boot="@QUICK_BOOT@"
 | |
| 
 | |
| . "$pkgdatadir/grub-mkconfig_lib"
 | |
| 
 | |
| export TEXTDOMAIN=@PACKAGE@
 | |
| export TEXTDOMAINDIR="@localedir@"
 | |
| 
 | |
| CLASS="--class gnu-linux --class gnu --class os"
 | |
| 
 | |
| if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
 | |
|   OS=GNU/Linux
 | |
| else
 | |
|   case ${GRUB_DISTRIBUTOR} in
 | |
|     Ubuntu|Kubuntu)
 | |
|       OS="${GRUB_DISTRIBUTOR}"
 | |
|       ;;
 | |
|     *)
 | |
|       OS="${GRUB_DISTRIBUTOR} GNU/Linux"
 | |
|       ;;
 | |
|   esac
 | |
|   CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
 | |
| fi
 | |
| 
 | |
| # loop-AES arranges things so that /dev/loop/X can be our root device, but
 | |
| # the initrds that Linux uses don't like that.
 | |
| case ${GRUB_DEVICE} in
 | |
|   /dev/loop/*|/dev/loop[0-9])
 | |
|     GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
 | |
|     # We can't cope with devices loop-mounted from files here.
 | |
|     case ${GRUB_DEVICE} in
 | |
|       /dev/*) ;;
 | |
|       *) exit 0 ;;
 | |
|     esac
 | |
|   ;;
 | |
| esac
 | |
| 
 | |
| # btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
 | |
| # and mounting btrfs requires user space scanning, so force UUID in this case.
 | |
| if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
 | |
|     || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
 | |
|     || test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm; then
 | |
|   LINUX_ROOT_DEVICE=${GRUB_DEVICE}
 | |
| else
 | |
|   LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
 | |
| fi
 | |
| 
 | |
| case x"$GRUB_FS" in
 | |
|     xbtrfs)
 | |
| 	rootsubvol="`make_system_path_relative_to_its_root /`"
 | |
| 	rootsubvol="${rootsubvol#/}"
 | |
| 	if [ "x${rootsubvol}" != x ]; then
 | |
| 	    GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
 | |
| 	fi;;
 | |
|     xzfs)
 | |
| 	rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
 | |
| 	bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
 | |
| 	LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}"
 | |
| 	;;
 | |
| esac
 | |
| 
 | |
| title_correction_code=
 | |
| 
 | |
| if [ -x /lib/recovery-mode/recovery-menu ]; then
 | |
|     GRUB_CMDLINE_LINUX_RECOVERY=recovery
 | |
| else
 | |
|     GRUB_CMDLINE_LINUX_RECOVERY=single
 | |
| fi
 | |
| if [ "$ubuntu_recovery" = 1 ]; then
 | |
|     GRUB_CMDLINE_LINUX_RECOVERY="$GRUB_CMDLINE_LINUX_RECOVERY nomodeset"
 | |
| fi
 | |
| 
 | |
| linux_entry ()
 | |
| {
 | |
|   os="$1"
 | |
|   version="$2"
 | |
|   type="$3"
 | |
|   args="$4"
 | |
| 
 | |
|   if [ -z "$boot_device_id" ]; then
 | |
|       boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
 | |
|   fi
 | |
|   if [ x$type != xsimple ] ; then
 | |
|       case $type in
 | |
| 	  recovery)
 | |
| 	      title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;;
 | |
| 	  *)
 | |
| 	      title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;;
 | |
|       esac
 | |
|       if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
 | |
| 	  replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
 | |
| 	  quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
 | |
| 	  title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
 | |
| 	  grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
 | |
|       fi
 | |
|       echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
 | |
|   else
 | |
|       echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
 | |
|   fi      
 | |
|   if [ "$quick_boot" = 1 ]; then
 | |
|       echo "	recordfail" | sed "s/^/$submenu_indentation/"
 | |
|   fi
 | |
|   if [ x$type != xrecovery ] ; then
 | |
|       save_default_entry | grub_add_tab
 | |
|   fi
 | |
| 
 | |
|   # Use ELILO's generic "efifb" when it's known to be available.
 | |
|   # FIXME: We need an interface to select vesafb in case efifb can't be used.
 | |
|   if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
 | |
|       echo "	load_video" | sed "s/^/$submenu_indentation/"
 | |
|   else
 | |
|       if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then
 | |
| 	  echo "	load_video" | sed "s/^/$submenu_indentation/"
 | |
|       fi
 | |
|       if [ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]; then
 | |
| 	  echo "	set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/"
 | |
|       fi
 | |
|   fi
 | |
| 
 | |
|   echo "	insmod gzio" | sed "s/^/$submenu_indentation/"
 | |
| 
 | |
|   if [ x$dirname = x/ ]; then
 | |
|     if [ -z "${prepare_root_cache}" ]; then
 | |
|       prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
 | |
|     fi
 | |
|     printf '%s\n' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/"
 | |
|   else
 | |
|     if [ -z "${prepare_boot_cache}" ]; then
 | |
|       prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
 | |
|     fi
 | |
|     printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
 | |
|   fi
 | |
|   if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
 | |
|     message="$(gettext_printf "Loading Linux %s ..." ${version})"
 | |
|     sed "s/^/$submenu_indentation/" << EOF
 | |
| 	echo	'$(echo "$message" | grub_quote)'
 | |
| EOF
 | |
|   fi
 | |
|   if test -d /sys/firmware/efi && test -e "${linux}.efi.signed"; then
 | |
|     sed "s/^/$submenu_indentation/" << EOF
 | |
| 	linux	${rel_dirname}/${basename}.efi.signed root=${linux_root_device_thisversion} ro ${args}
 | |
| EOF
 | |
|   else
 | |
|     sed "s/^/$submenu_indentation/" << EOF
 | |
| 	linux	${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
 | |
| EOF
 | |
|   fi
 | |
|   if test -n "${initrd}" ; then
 | |
|     # TRANSLATORS: ramdisk isn't identifier. Should be translated.
 | |
|     if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
 | |
|       message="$(gettext_printf "Loading initial ramdisk ...")"
 | |
|       sed "s/^/$submenu_indentation/" << EOF
 | |
| 	echo	'$(echo "$message" | grub_quote)'
 | |
| EOF
 | |
|     fi
 | |
|     sed "s/^/$submenu_indentation/" << EOF
 | |
| 	initrd	${rel_dirname}/${initrd}
 | |
| EOF
 | |
|   fi
 | |
|   sed "s/^/$submenu_indentation/" << EOF
 | |
| }
 | |
| EOF
 | |
| }
 | |
| 
 | |
| machine=`uname -m`
 | |
| case "x$machine" in
 | |
|     xi?86 | xx86_64)
 | |
| 	list=
 | |
| 	for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do
 | |
| 	    if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
 | |
| 	done ;;
 | |
|     *) 
 | |
| 	list=
 | |
| 	for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do
 | |
|                   if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
 | |
| 	done ;;
 | |
| esac
 | |
| 
 | |
| case "$machine" in
 | |
|     i?86) GENKERNEL_ARCH="x86" ;;
 | |
|     mips|mips64) GENKERNEL_ARCH="mips" ;;
 | |
|     mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
 | |
|     arm*) GENKERNEL_ARCH="arm" ;;
 | |
|     *) GENKERNEL_ARCH="$machine" ;;
 | |
| esac
 | |
| 
 | |
| prepare_boot_cache=
 | |
| prepare_root_cache=
 | |
| boot_device_id=
 | |
| title_correction_code=
 | |
| 
 | |
| # Extra indentation to add to menu entries in a submenu. We're not in a submenu
 | |
| # yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
 | |
| submenu_indentation=""
 | |
| 
 | |
| is_top_level=true
 | |
| while [ "x$list" != "x" ] ; do
 | |
|   linux=`version_find_latest $list`
 | |
|   case $linux in
 | |
|     *.efi.signed)
 | |
|       # We handle these in linux_entry.
 | |
|       list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
 | |
|       continue
 | |
|       ;;
 | |
|   esac
 | |
|   gettext_printf "Found linux image: %s\n" "$linux" >&2
 | |
|   basename=`basename $linux`
 | |
|   dirname=`dirname $linux`
 | |
|   rel_dirname=`make_system_path_relative_to_its_root $dirname`
 | |
|   version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
 | |
|   alt_version=`echo $version | sed -e "s,\.old$,,g"`
 | |
|   linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
 | |
| 
 | |
|   initrd=
 | |
|   for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
 | |
| 	   "initrd-${version}" "initramfs-${version}.img" \
 | |
| 	   "initrd.img-${alt_version}" "initrd-${alt_version}.img" \
 | |
| 	   "initrd-${alt_version}" "initramfs-${alt_version}.img" \
 | |
| 	   "initramfs-genkernel-${version}" \
 | |
| 	   "initramfs-genkernel-${alt_version}" \
 | |
| 	   "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
 | |
| 	   "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
 | |
|     if test -e "${dirname}/${i}" ; then
 | |
|       initrd="$i"
 | |
|       break
 | |
|     fi
 | |
|   done
 | |
| 
 | |
|   config=
 | |
|   for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
 | |
|     if test -e "${i}" ; then
 | |
|       config="${i}"
 | |
|       break
 | |
|     fi
 | |
|   done
 | |
| 
 | |
|   initramfs=
 | |
|   if test -n "${config}" ; then
 | |
|       initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"`
 | |
|   fi
 | |
| 
 | |
|   if test -n "${initrd}" ; then
 | |
|     gettext_printf "Found initrd image: %s\n" "${dirname}/${initrd}" >&2
 | |
|   elif test -z "${initramfs}" ; then
 | |
|     # "UUID=" and "ZFS=" magic is parsed by initrd or initramfs.  Since there's
 | |
|     # no initrd or builtin initramfs, it can't work here.
 | |
|     linux_root_device_thisversion=${GRUB_DEVICE}
 | |
|   fi
 | |
| 
 | |
|   if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
 | |
|     linux_entry "${OS}" "${version}" simple \
 | |
|     "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
 | |
| 
 | |
|     submenu_indentation="$grub_tab"
 | |
|     
 | |
|     if [ -z "$boot_device_id" ]; then
 | |
| 	boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
 | |
|     fi
 | |
|     # TRANSLATORS: %s is replaced with an OS name
 | |
|     echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
 | |
|     is_top_level=false
 | |
|   fi
 | |
| 
 | |
|   linux_entry "${OS}" "${version}" advanced \
 | |
|               "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
 | |
|   if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
 | |
|     linux_entry "${OS}" "${version}" recovery \
 | |
|                 "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}"
 | |
|   fi
 | |
| 
 | |
|   list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
 | |
| done
 | |
| 
 | |
| # If at least one kernel was found, then we need to
 | |
| # add a closing '}' for the submenu command.
 | |
| if [ x"$is_top_level" != xtrue ]; then
 | |
|   echo '}'
 | |
| fi
 | |
| 
 | |
| echo "$title_correction_code"
 |