From 4eca366b66953e15b1244351d1dc1054e6bc586e Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Mon, 11 Aug 2025 10:42:41 +0800 Subject: [PATCH 1/9] grub.d/10_linux: Use an in-house script for generating linux entries Now we have to deal with different kernel page sizes, since we want to show up in the top-level menu, instead of in the "Advanced options for" submenu. Also, we want to prefer a certain kernel with specific page size over the other ones, otherwise the machine might not boot. --- util/grub.d/10_linux.in | 613 +++++++++++++++++++++------------------- 1 file changed, 324 insertions(+), 289 deletions(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index e896c0c1a..10df977cd 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -1,315 +1,350 @@ -#! /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 . - -prefix="@prefix@" -exec_prefix="@exec_prefix@" -datarootdir="@datarootdir@" - -. "$pkgdatadir/grub-mkconfig_lib" - -export TEXTDOMAIN=@PACKAGE@ -export TEXTDOMAINDIR="@localedir@" +#!/bin/bash + +[ -e /etc/default/grub ] && source /etc/default/grub +[ -e /etc/default/grub-aosc ] && source /etc/default/grub-aosc +. /usr/share/grub/grub-mkconfig_lib + +indent="" +tab=$'\t' +arch=$(uname -m) +KERNELS=() +# Using an associative array to keep track of unprocessed kernels. +# They can be easily modified, unlike ordinary arrays. +declare -A UNPROCESSED_VERSIONS +KERNEL_VERSIONS=() +OS=$(gettext_printf "AOSC OS") +OS_ID="aosc" +KERNEL_DIR=${KERNEL_DIR:-/boot} + +shopt -s extglob + +bool() { + [[ "$1" == "true" || "$1" == "1" || "$1" =~ [yY] ]] +} -CLASS="--class gnu-linux --class gnu --class os" +info() { + echo "-- $@" >&2 +} -if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then - OS="$(sed 's, release .*$,,g' /etc/system-release)" +if bool "$AOSC_GRUB_DEBUG" ; then + #set -x + debug() { + echo -e ">> $@" >&2 + } else - OS="${GRUB_DISTRIBUTOR}" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" + debug() { + : noop + } 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/"` - ;; -esac - -: ${GRUB_CMDLINE_LINUX_RECOVERY:=single} +if [ -z "$GRUB_DEVICE" ] ; then + GRUB_DEVICE="`${grub_probe} --target=device /`" + GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true + GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2> /dev/null`" || true +fi -# Default to disabling partition uuid support to maintian compatibility with -# older kernels. -: ${GRUB_DISABLE_LINUX_PARTUUID=true} +if [ -z "$GRUB_DEVICE_BOOT" ] ; then + # Device containing our /boot partition. Usually the same as GRUB_DEVICE. + GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" + GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true +fi -# 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_DEVICE_PARTUUID}" = "x" ] ) \ - || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ - && [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \ - || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ - && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \ - || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then - LINUX_ROOT_DEVICE=${GRUB_DEVICE} -elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \ - || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then - LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID} -else - LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} +if [[ -z "$GRUB_DEVICE" || -z "$GRUB_DEVICE_BOOT" ]] ; then + gettext_printf "Internal error - Failed to gather information of the root partition\n" + exit 1 fi -case x"$GRUB_FS" in - xbtrfs) +# From GRUB: specify subvolume ID for btrfs, if the filesystem has subvolumes. +if [ "$GRUB_FS" = "btrfs" ] ; then 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= - -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 [ 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/" - if grep -qx "CONFIG_FB_EFI=y" "${config}" 2> /dev/null \ - && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" "${config}" 2> /dev/null; then - echo " set gfxpayload=keep" | sed "s/^/$submenu_indentation/" - fi - else - if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then - echo " load_video" | sed "s/^/$submenu_indentation/" - fi - echo " set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/" - 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 - message="$(gettext_printf "Loading Linux %s ..." ${version})" - sed "s/^/$submenu_indentation/" << EOF - echo '$(echo "$message" | grub_quote)' - linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} -EOF - if test -n "${initrd}" ; then - # TRANSLATORS: ramdisk isn't identifier. Should be translated. - message="$(gettext_printf "Loading initial ramdisk ...")" - initrd_path= - for i in ${initrd}; do - initrd_path="${initrd_path} ${rel_dirname}/${i}" - done - sed "s/^/$submenu_indentation/" << EOF - echo '$(echo "$message" | grub_quote)' - initrd $(echo $initrd_path) -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="" - -# Perform a reverse version sort on the entire list. -# Temporarily replace the '.old' suffix by ' 1' and append ' 2' for all -# other files to order the '.old' files after their non-old counterpart -# in reverse-sorted order. - -reverse_sorted_list=$(echo $list | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') - -if [ "x$GRUB_TOP_LEVEL" != x ]; then - reverse_sorted_list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_list}) + GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" + fi +fi +# Depends on whether /boot is a mounted filesystem, the path GRUB loads the +# kernel changes. +if [ "$GRUB_DEVICE" == "$GRUB_DEVICE_BOOT" ] ; then + GRUB_KERNEL_DIR="${KERNEL_DIR%%/}/" +else + GRUB_KERNEL_DIR="/" fi -is_top_level=true -for linux in ${reverse_sorted_list}; do - 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_early= - for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \ - ${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do - if test -e "${dirname}/${i}" ; then - initrd_early="${initrd_early} ${i}" - fi - done - - initrd_real= - for i in "initrd.img-${version}" "initrd-${version}.img" \ - "initrd-${alt_version}.img.old" "initrd-${version}.gz" \ - "initrd-${alt_version}.gz.old" "initrd-${version}" \ - "initramfs-${version}.img" "initramfs-${alt_version}.img.old" \ - "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_real="${i}" - break - fi - done +MENUENTRY_PREP="$(prepare_grub_to_access_device "$GRUB_DEVICE_BOOT")" - initrd= - if test -n "${initrd_early}" || test -n "${initrd_real}"; then - initrd="${initrd_early} ${initrd_real}" +if [ -z "$GRUB_GFXPAYLOAD_LINUX" ] ; then + _GFXPAYLOAD_LINUX="set gfxpayload=keep" +else + _GFXPAYLOAD_LINUX="set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" +fi - initrd_display= - for i in ${initrd}; do - initrd_display="${initrd_display} ${dirname}/${i}" - done - gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 - fi +# Handle microcodes. +for rd in ${GRUB_EARLY_INITRD_LINUX_STOCK[@]} \ + ${GRUB_EARLY_INITRD_LINUX_CUSTOM[@]} ; do + if [ -e "$KERNEL_DIR"/"$rd" ] ; then + INITRD_EARLY="${INITRD_EARLY} ${rd}" + fi +done +# Returns the default page size suffix. +# WARN $arch is the output of `uname -m`, which is not exactly the same as +# `dpkg --print-architecture`. +default_pagesize() { + case "$arch" in + loongarch64) + printf "16k" + ;; + *) + printf "4k" + ;; + esac +} - 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 +pagesize_str() { + case "$1" in + 4k) + if [ "$(default_pagesize)" = "$1" ] ; then + printf "" + else + gettext_printf "4K Page Size" + fi + ;; + 16k) + if [ "$(default_pagesize)" = "$1" ] ; then + printf "" + else + gettext_printf "16K Page Size" + fi + ;; + 64k) + if [ "$(default_pagesize)" = "$1" ] ; then + printf "" + else + gettext_printf "64K Page Size" + fi + ;; + *) + # Unknown page size. + echo "" + ;; + esac +} - initramfs= - if test -n "${config}" ; then - initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"` - fi +# Localize the given variant. +variant_str() { + case "$1" in + rc) + gettext_printf "RC Kernel" + ;; + lts) + gettext_printf "LTS Kernel" + ;; + main) + : noop + ;; + *) + gettext_printf "Kernel variant '%s'" "$1" + ;; + esac +} - if ( test -z "${initramfs}" && test -z "${initrd_real}" ) || \ - [[ "${initrd_real}" = "intel-ucode.img" ]]; then - # "UUID=" and "ZFS=" magic is parsed by initrd or initramfs. Since there's - # no initrd or builtin initramfs, it can't work here. - if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \ - || [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then +# Break localversion apart, return the processed comments. +# E.g. +# - "-aosc-main" -> "" +# - "-aosc-lts" -> " (LTS Kernel)" +# - "-aosc-main-4k" -> " (4K Page Size)" +# - "-aosc-rc-4k" -> " (RC Kernel, 4K Page Size)" +get_comments() { + local _str="$1" _fullver="$1" segs=() comments=() sep=", " variant pagesize + # Not an AOSC OS kernel + if ! [[ "$_str" =~ \.[0-9]+-aosc- ]] ; then + return + fi + + _str="${_str##*-aosc-}" + IFS=- + segs=($_str) + unset IFS + variant="$(variant_str "${segs[0]}")" + pagesize="$(pagesize_str "${segs[1]}")" + comment="${variant}${sep}${pagesize}" + if [ "x$comment" = "x$sep" ] ; then + return + fi + comment="${comment##$sep}" + comment="${comment%%$sep}" + printf "%s" " ($comment)" +} - linux_root_device_thisversion=${GRUB_DEVICE} - else - linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID} - fi - fi +linux_entry() { + title="$1" + kernel="$2" + initrd="$3" + args="$4" + _id="$5" + + printf "${indent}menuentry '%s' --class linux \$menuentry_id_option '%s' {\n" "$title" "$_id" + printf "$(echo "$MENUENTRY_PREP" | sed "s|^|\t${indent}|g")\n" + printf "${indent}\t$_GFXPAYLOAD_LINUX\n" + printf "${indent}\tinsmod gzio\n" + printf "${indent}\techo '%s'\n" "$(gettext_printf "Loading kernel $kernel ...")" + printf "${indent}\tlinux %s %s\n" "$kernel" "$args" + if [ -n "$initrd" ] ; then + printf "${indent}\techo '%s'\n" "$(gettext_printf "Loading initial ramdisk ...")" + printf "${indent}\tinitrd %s\n" "$initrd" + fi + printf "${indent}\techo '%s'\n" "$(gettext_printf "Booting up $OS ...")" + printf "${indent}}\n\n" +} - # The GRUB_DISABLE_SUBMENU option used to be different than others since it was - # mentioned in the documentation that has to be set to 'y' instead of 'true' to - # enable it. This caused a lot of confusion to users that set the option to 'y', - # 'yes' or 'true'. This was fixed but all of these values must be supported now. - if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then - GRUB_DISABLE_SUBMENU="true" - fi +find_rootdev() { + local ident_type=uuid + if ! [ -e "$GRUB_DEVICE" ] ; then + ident_type=error + elif bool "$GRUB_DISABLE_LINUX_UUID" ; then + if bool "$GRUB_DISABLE_LINUX_PARTUUID" ; then + ident_type=path + else + ident_type=partuuid + fi + else + if [ ! -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID,,}" ] ; then + ident_type=partuuid + fi + if [ ! -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID,,}" ] || \ + bool "${GRUB_DISABLE_LINUX_PARTUUID}" || \ + uses_abstraction "${GRUB_DEVICE}" lvm ; then + ident_type=path + fi + + fi + case "$ident_type" in + path) + printf "%s" "$GRUB_DEVICE" + ;; + uuid) + printf "UUID=%s" "$GRUB_DEVICE_UUID" + return + ;; + partuuid) + printf "PARTUUID=%s" "$GRUB_DEVICE_PARTUUID" + ;; + *) + # Propogate the error + ;; + esac +} - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then - linux_entry "${OS}" "${version}" simple \ - "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" +# Prioritize kernel names in "$@", based on the default size. +# The kernel with the default size will be always on top. If it does +# not exist, then the kernel without page size suffix will be on top. +prioritize() { + local kernels newkernels default_pgsize flag + kernels=("$@") + newkernels=() + default_pgsize="$(default_pagesize)" + for k in "${kernels[@]}" ; do + # This system probably don't have other page sizes. + if [ "${k%%-[0-9]*k}" = "$k" ] ; then + newkernels=("$k" "${newkernels[@]}") + continue + fi + if [ "${k%%-$default_pgsize}" != "$k" ] ; then + newkernels=("$k" "${newkernels[@]}") + continue + fi + newkernels+=("$k") + done + OLDIFS="$IFS" + IFS=$'\n' + echo -n "${newkernels[*]}" + IFS="$OLDIFS" +} - 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 +scan_for_kernels() { + IFS=$'\n' + KERNELS=($(find $KERNEL_DIR -maxdepth 1 -type f -a \( -name 'vmlinux-*' -o -name 'vmlinuz-*' -o -name 'kernel-*' \) -printf '%P\n')) + if [ "${#KERNELS[@]}" -lt 1 ] ; then + unset IFS + return + fi + KERNEL_VERSIONS+=($(echo -e "${KERNELS[*]}" | grep -o '[0-9]*\.[0-9]*\.[0-9]*' | sort -rVu)) + for ver in "${KERNEL_VERSIONS[@]}" ; do + UNPROCESSED_VERSIONS["$ver"]="$ver" + done + debug "Kernel versions:\n${KERNEL_VERSIONS[*]}" + unset IFS k +} - 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 -done +# Scan for a corresponding initrd image for the kernel. +# $1: Full version of the kernel. +get_initrd() { + local rd ret="${INITRD_EARLY}" + for rd in \ + initramfs-"$1".img \ + initramfs.img-"$1" \ + initrd-"$1".img \ + initrd.img-"$1" \ + initrd-"$1".gz ; do + if [ -e "$KERNEL_DIR/$rd" ] ; then + info "$(gettext_printf "Initial ramdisk image for kernel %s: %s" "$1" "${GRUB_KERNEL_DIR}${rd}")" + ret="${ret} ${GRUB_KERNEL_DIR}${rd}" + break + else + continue + fi + done + printf "%s" "$ret" +} -# 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 +process_kernels() { + local kernel uname_r latest latest_kernels localpart + # Use the latest non-RC kernel. + # Whatever. I don't care. + IFS=$'\n' + latest="${KERNEL_VERSIONS[0]}" + latest_kernels=($(echo "${KERNELS[*]}" | grep "$latest")) + latest_kernels=($(prioritize ${latest_kernels[@]})) + unset IFS + ROOT_PARAM="root=$(find_rootdev)" + if [ -z "${ROOT_PARAM##root=}" ] ; then + gettext_printf "Internal error - Failed to find the root device\n" >&2 + exit 1 + fi + ARGS="${ROOT_PARAM} ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" + for kernel in "${latest_kernels[@]}" ; do + uname_r=${kernel/#@(vmlinu?|kernel)-/} + info $(gettext_printf "Processing kernel '%s'\n" "$uname_r") + localpart="${uname_r//$latest/}" + comments="$(get_comments "$uname_r")" + title="${OS}${comments}" + linux_entry "$title" "${GRUB_KERNEL_DIR}${kernel}" "$(get_initrd "$uname_r")" "$ARGS" "${OS_ID}-${kernel}" + done + # Now we processed the latest versions of the kernel, time to put + # other kernel versions into the submenu. + unset UNPROCESSED_VERSIONS["$latest"] + if [ "${#UNPROCESSED_VERSIONS[@]}" = "0" ] ; then + return + fi + submenu_title="$(gettext_printf "More kernel options for %s" "$OS")" + printf "submenu '%s' {\n" "$submenu_title" + indent="$indent$tab" + for version in "${UNPROCESSED_VERSIONS[@]}" ; do + IFS=$'\n' + kernels=($(echo "${KERNELS[*]}" | grep "$version")) + unset IFS + for kernel in "${kernels[@]}" ; do + uname_r=${kernel/#@(vmlinu?|kernel)-/} + info $(gettext_printf "Processing kernel '%s'\n" "$uname_r") + localpart="${uname_r//$latest/}" + comments="$(gettext_printf "With kernel %s" "$uname_r")" + comments=" ($(echo "$comments" | grub_quote))" + title="${OS}${comments}" + linux_entry "$title" "${GRUB_KERNEL_DIR}/${kernel}" "$(get_initrd "$uname_r")" "$ARGS" "${OS_ID}-${kernel}" + done + done + printf "}\n" +} -echo "$title_correction_code" +scan_for_kernels +process_kernels +info "$(gettext_printf "Done generating entries for %s." "$OS")" From 5677364b6c94d8af0c545c47b148a6ee6d5dfdd0 Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Mon, 11 Aug 2025 10:45:05 +0800 Subject: [PATCH 2/9] grub.pot: update PO template for new strings in 10_linux --- po/grub.pot | 114 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 86 insertions(+), 28 deletions(-) diff --git a/po/grub.pot b/po/grub.pot index b4936ace6..36be588ab 100644 --- a/po/grub.pot +++ b/po/grub.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: grub 2.12\n" "Report-Msgid-Bugs-To: bug-grub@gnu.org\n" -"POT-Creation-Date: 2024-11-16 22:18+0800\n" +"POT-Creation-Date: 2025-08-11 10:38+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -145,8 +145,8 @@ msgstr "" msgid "error: %s.\n" msgstr "" -#: grub-core/commands/acpihalt.c:368 grub-core/kern/efi/mm.c:147 -#: grub-core/kern/efi/mm.c:160 grub-core/kern/emu/misc.c:96 +#: grub-core/commands/acpihalt.c:368 grub-core/kern/efi/mm.c:143 +#: grub-core/kern/efi/mm.c:156 grub-core/kern/emu/misc.c:96 #: grub-core/kern/emu/misc.c:108 grub-core/kern/emu/misc.c:118 #: grub-core/kern/emu/misc.c:147 grub-core/kern/emu/mm.c:34 #: grub-core/kern/emu/mm.c:44 grub-core/kern/emu/mm.c:73 @@ -239,7 +239,7 @@ msgstr "" #: grub-core/loader/i386/xen.c:861 grub-core/loader/i386/xnu.c:487 #: grub-core/loader/ia64/efi/linux.c:459 grub-core/loader/ia64/efi/linux.c:539 #: grub-core/loader/mips/linux.c:238 grub-core/loader/mips/linux.c:429 -#: grub-core/loader/mips64/linux.c:395 grub-core/loader/mips64/linux.c:507 +#: grub-core/loader/mips64/linux.c:396 grub-core/loader/mips64/linux.c:509 #: grub-core/loader/multiboot.c:322 grub-core/loader/multiboot.c:374 #: grub-core/loader/multiboot.c:384 #: grub-core/loader/powerpc/ieee1275/linux.c:280 @@ -297,7 +297,7 @@ msgstr "" #: grub-core/loader/i386/bsd.c:2095 grub-core/loader/i386/linux.c:1065 #: grub-core/loader/i386/pc/linux.c:412 grub-core/loader/i386/xen.c:783 #: grub-core/loader/i386/xen.c:866 grub-core/loader/ia64/efi/linux.c:545 -#: grub-core/loader/mips/linux.c:432 grub-core/loader/mips64/linux.c:510 +#: grub-core/loader/mips/linux.c:432 grub-core/loader/mips64/linux.c:512 #: grub-core/loader/multiboot.c:388 #: grub-core/loader/powerpc/ieee1275/linux.c:358 #: grub-core/loader/sparc64/ieee1275/linux.c:387 grub-core/loader/xnu.c:591 @@ -1754,8 +1754,8 @@ msgstr "" #: grub-core/commands/nativedisk.c:326 msgid "" -"Switch to native disk drivers. If no modules are specified default set (pata," -"ahci,usbms,ohci,uhci,ehci) is used" +"Switch to native disk drivers. If no modules are specified default set " +"(pata,ahci,usbms,ohci,uhci,ehci) is used" msgstr "" #: grub-core/commands/parttool.c:40 @@ -3054,7 +3054,7 @@ msgstr "" #: grub-core/efiemu/loadcore.c:346 grub-core/kern/dl.c:629 #: grub-core/loader/ia64/efi/linux.c:345 grub-core/loader/mips/linux.c:248 -#: grub-core/loader/mips64/linux.c:405 grub-core/loader/multiboot_elfxx.c:89 +#: grub-core/loader/mips64/linux.c:406 grub-core/loader/multiboot_elfxx.c:89 #: grub-core/loader/powerpc/ieee1275/linux.c:291 #: grub-core/loader/sparc64/ieee1275/linux.c:320 msgid "this ELF file is not of the right type" @@ -3481,7 +3481,7 @@ msgstr "" #: grub-core/kern/riscv/dl.c:47 grub-core/kern/sparc64/dl.c:36 #: grub-core/kern/x86_64/dl.c:36 grub-core/loader/i386/bsd.c:1451 #: grub-core/loader/i386/bsdXX.c:52 grub-core/loader/ia64/efi/linux.c:341 -#: grub-core/loader/mips/linux.c:298 grub-core/loader/mips64/linux.c:438 +#: grub-core/loader/mips/linux.c:298 grub-core/loader/mips64/linux.c:439 #: grub-core/loader/multiboot.c:232 grub-core/loader/multiboot_elfxx.c:86 #: grub-core/loader/powerpc/ieee1275/linux.c:305 #: grub-core/loader/sparc64/ieee1275/linux.c:331 @@ -3543,7 +3543,7 @@ msgstr "" msgid "Print infomation useful for GDB debugging" msgstr "" -#: grub-core/kern/efi/mm.c:139 +#: grub-core/kern/efi/mm.c:135 #, c-format msgid "invalid memory address (0x%s > 0x%s)" msgstr "" @@ -3926,7 +3926,7 @@ msgstr "" #: grub-core/loader/emu/linux.c:172 grub-core/loader/i386/linux.c:1157 #: grub-core/loader/i386/pc/linux.c:483 grub-core/loader/i386/xen.c:969 #: grub-core/loader/i386/xen.c:971 grub-core/loader/ia64/efi/linux.c:591 -#: grub-core/loader/mips/linux.c:498 grub-core/loader/mips64/linux.c:562 +#: grub-core/loader/mips/linux.c:498 grub-core/loader/mips64/linux.c:572 #: grub-core/loader/powerpc/ieee1275/linux.c:406 #: grub-core/loader/sparc64/ieee1275/linux.c:511 msgid "Load Linux." @@ -3936,7 +3936,7 @@ msgstr "" #: grub-core/loader/emu/linux.c:174 grub-core/loader/i386/linux.c:1159 #: grub-core/loader/i386/pc/linux.c:486 grub-core/loader/i386/xen.c:973 #: grub-core/loader/ia64/efi/linux.c:594 grub-core/loader/mips/linux.c:500 -#: grub-core/loader/mips64/linux.c:564 +#: grub-core/loader/mips64/linux.c:574 #: grub-core/loader/powerpc/ieee1275/linux.c:408 #: grub-core/loader/sparc64/ieee1275/linux.c:513 msgid "Load initrd." @@ -7365,9 +7365,9 @@ msgstr "" #: util/grub.d/10_hurd.in:118 util/grub.d/10_kfreebsd.in:87 #, c-format -#: util/grub.d/10_linux.in:105 util/grub.d/10_netbsd.in:113 +#: util/grub.d/10_netbsd.in:113 util/grub.d/20_linux_xen.in:131 #, c-format -#: util/grub.d/20_linux_xen.in:131 util/grub.d/30_os-prober.in:290 +#: util/grub.d/30_os-prober.in:290 #, c-format msgid "" "Please don't use old title `%s' for GRUB_DEFAULT, use `%s' (for versions " @@ -7387,9 +7387,7 @@ msgstr "" #. TRANSLATORS: %s is replaced with an OS name #: util/grub.d/10_hurd.in:252 util/grub.d/10_kfreebsd.in:243 #, c-format -#: util/grub.d/10_linux.in:297 util/grub.d/10_netbsd.in:182 -#, c-format -#: util/grub.d/30_os-prober.in:266 +#: util/grub.d/10_netbsd.in:182 util/grub.d/30_os-prober.in:266 #, c-format msgid "Advanced options for %s" msgstr "" @@ -7424,35 +7422,80 @@ msgstr "" msgid "Found kernel module directory: %s\\n" msgstr "" -#: util/grub.d/10_linux.in:97 +#: util/grub.d/10_linux.in:15 #, c-format -msgid "%s, with Linux %s (recovery mode)" +msgid "AOSC OS" msgstr "" -#: util/grub.d/10_linux.in:99 +#: util/grub.d/10_linux.in:53 #, c-format -msgid "%s, with Linux %s" +msgid "Internal error - Failed to gather information of the root partition\\n" msgstr "" -#: util/grub.d/10_linux.in:143 util/grub.d/20_linux_xen.in:147 +#: util/grub.d/10_linux.in:106 #, c-format -msgid "Loading Linux %s ..." +msgid "4K Page Size" +msgstr "" + +#: util/grub.d/10_linux.in:113 +#, c-format +msgid "16K Page Size" +msgstr "" + +#: util/grub.d/10_linux.in:120 +#, c-format +msgid "64K Page Size" +msgstr "" + +#: util/grub.d/10_linux.in:134 +#, c-format +msgid "RC Kernel" +msgstr "" + +#: util/grub.d/10_linux.in:137 +#, c-format +msgid "LTS Kernel" +msgstr "" + +#: util/grub.d/10_linux.in:143 +#, c-format +msgid "Kernel variant '%s'" msgstr "" #. TRANSLATORS: ramdisk isn't identifier. Should be translated. -#: util/grub.d/10_linux.in:150 util/grub.d/20_linux_xen.in:161 +#: util/grub.d/10_linux.in:190 util/grub.d/20_linux_xen.in:161 #, c-format msgid "Loading initial ramdisk ..." msgstr "" -#: util/grub.d/10_linux.in:209 util/grub.d/20_linux_xen.in:289 +#: util/grub.d/10_linux.in:287 #, c-format -msgid "Found linux image: %s\\n" +msgid "Initial ramdisk image for kernel %s: %s" msgstr "" -#: util/grub.d/10_linux.in:250 util/grub.d/20_linux_xen.in:325 +#: util/grub.d/10_linux.in:307 #, c-format -msgid "Found initrd image: %s\\n" +msgid "Internal error - Failed to find the root device\\n" +msgstr "" + +#: util/grub.d/10_linux.in:313 util/grub.d/10_linux.in:334 +#, c-format +msgid "Processing kernel '%s'\\n" +msgstr "" + +#: util/grub.d/10_linux.in:325 +#, c-format +msgid "More kernel options for %s" +msgstr "" + +#: util/grub.d/10_linux.in:336 +#, c-format +msgid "With kernel %s" +msgstr "" + +#: util/grub.d/10_linux.in:347 +#, c-format +msgid "Done generating entries for %s." msgstr "" #: util/grub.d/10_netbsd.in:105 @@ -7532,6 +7575,11 @@ msgstr "" msgid "Loading Xen %s ..." msgstr "" +#: util/grub.d/20_linux_xen.in:147 +#, c-format +msgid "Loading Linux %s ..." +msgstr "" + #: util/grub.d/20_linux_xen.in:172 #, c-format msgid "Loading XSM policy ..." @@ -7542,6 +7590,16 @@ msgstr "" msgid "Xen hypervisor, version %s" msgstr "" +#: util/grub.d/20_linux_xen.in:289 +#, c-format +msgid "Found linux image: %s\\n" +msgstr "" + +#: util/grub.d/20_linux_xen.in:325 +#, c-format +msgid "Found initrd image: %s\\n" +msgstr "" + #. TRANSLATORS: %s is replaced with an OS name #: util/grub.d/20_linux_xen.in:357 #, c-format From 8ca03b12cb6ae6fe378f15b1fbcad187d49c6efe Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Wed, 13 Aug 2025 09:26:51 +0800 Subject: [PATCH 3/9] 10_linux: lower the priority of RC kernels --- util/grub.d/10_linux.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 10df977cd..c24aec951 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -245,7 +245,11 @@ prioritize() { for k in "${kernels[@]}" ; do # This system probably don't have other page sizes. if [ "${k%%-[0-9]*k}" = "$k" ] ; then - newkernels=("$k" "${newkernels[@]}") + if [ "${k%%-rc}" != "$k" ] ; then + newkernels+=("$k") + else + newkernels=("$k" "${newkernels[@]}") + fi continue fi if [ "${k%%-$default_pgsize}" != "$k" ] ; then From bad4f1ec2a3fc23d4c6ee5fef5c2dec0844fc027 Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Wed, 13 Aug 2025 09:28:17 +0800 Subject: [PATCH 4/9] 10_linux: fix the path of early initramfses (e.g. microcodes). --- util/grub.d/10_linux.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index c24aec951..85835e027 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -82,7 +82,7 @@ fi for rd in ${GRUB_EARLY_INITRD_LINUX_STOCK[@]} \ ${GRUB_EARLY_INITRD_LINUX_CUSTOM[@]} ; do if [ -e "$KERNEL_DIR"/"$rd" ] ; then - INITRD_EARLY="${INITRD_EARLY} ${rd}" + INITRD_EARLY="${INITRD_EARLY} ${KERNEL_DIR}/${rd}" fi done # Returns the default page size suffix. From 954f4f97a5d7826dc3593a1d84dec8f382a75636 Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Wed, 13 Aug 2025 09:35:38 +0800 Subject: [PATCH 5/9] 10_linux: add missing `savedefault' to save the current selection --- util/grub.d/10_linux.in | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 85835e027..7d6150d3a 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -15,6 +15,7 @@ KERNEL_VERSIONS=() OS=$(gettext_printf "AOSC OS") OS_ID="aosc" KERNEL_DIR=${KERNEL_DIR:-/boot} +SAVEDEFAULT= shopt -s extglob @@ -78,6 +79,11 @@ else _GFXPAYLOAD_LINUX="set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" fi +# `savedefault' for saving current selection upon boot. +if [ "$GRUB_SAVEDEFAULT" = "true" ] ; then + SAVEDEFAULT="savedefault" +fi + # Handle microcodes. for rd in ${GRUB_EARLY_INITRD_LINUX_STOCK[@]} \ ${GRUB_EARLY_INITRD_LINUX_CUSTOM[@]} ; do @@ -185,6 +191,7 @@ linux_entry() { printf "${indent}menuentry '%s' --class linux \$menuentry_id_option '%s' {\n" "$title" "$_id" printf "$(echo "$MENUENTRY_PREP" | sed "s|^|\t${indent}|g")\n" printf "${indent}\t$_GFXPAYLOAD_LINUX\n" + printf "${indent}\t$SAVEDEFAULT\n" printf "${indent}\tinsmod gzio\n" printf "${indent}\techo '%s'\n" "$(gettext_printf "Loading kernel $kernel ...")" printf "${indent}\tlinux %s %s\n" "$kernel" "$args" From b773360179281a913bfd8708958a19d17a66c558 Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Wed, 13 Aug 2025 09:53:49 +0800 Subject: [PATCH 6/9] 10_linux: use PARTUUID or path for kernels with no initrd generated --- util/grub.d/10_linux.in | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 7d6150d3a..195590fb8 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -207,7 +207,7 @@ find_rootdev() { local ident_type=uuid if ! [ -e "$GRUB_DEVICE" ] ; then ident_type=error - elif bool "$GRUB_DISABLE_LINUX_UUID" ; then + elif bool "$GRUB_DISABLE_LINUX_UUID" || [ "$1" = "fallback" ] ; then if bool "$GRUB_DISABLE_LINUX_PARTUUID" ; then ident_type=path else @@ -317,6 +317,7 @@ process_kernels() { latest_kernels=($(prioritize ${latest_kernels[@]})) unset IFS ROOT_PARAM="root=$(find_rootdev)" + ROOT_PARAM_FALLBACK="root=$(find_rootdev fallback)" if [ -z "${ROOT_PARAM##root=}" ] ; then gettext_printf "Internal error - Failed to find the root device\n" >&2 exit 1 @@ -328,7 +329,13 @@ process_kernels() { localpart="${uname_r//$latest/}" comments="$(get_comments "$uname_r")" title="${OS}${comments}" - linux_entry "$title" "${GRUB_KERNEL_DIR}${kernel}" "$(get_initrd "$uname_r")" "$ARGS" "${OS_ID}-${kernel}" + initrd="$(get_initrd "$uname_r")" + if [ -z ${initrd/${INITRD_EARLY}/} ] ; then + args="${ARGS/$ROOT_PARAM/$ROOT_PARAM_FALLBACK}" + else + args="$ARGS" + fi + linux_entry "$title" "${GRUB_KERNEL_DIR}${kernel}" "$initrd" "$args" "${OS_ID}-${kernel}" done # Now we processed the latest versions of the kernel, time to put # other kernel versions into the submenu. @@ -350,7 +357,13 @@ process_kernels() { comments="$(gettext_printf "With kernel %s" "$uname_r")" comments=" ($(echo "$comments" | grub_quote))" title="${OS}${comments}" - linux_entry "$title" "${GRUB_KERNEL_DIR}/${kernel}" "$(get_initrd "$uname_r")" "$ARGS" "${OS_ID}-${kernel}" + initrd="$(get_initrd "$uname_r")" + if [ -z ${initrd/${INITRD_EARLY}/} ] ; then + ARGS="${ARGS/$ROOT_PARAM/$ROOT_PARAM_FALLBACK}" + else + args="$ARGS" + fi + linux_entry "$title" "${GRUB_KERNEL_DIR}${kernel}" "$initrd" "$args" "${OS_ID}-${kernel}" done done printf "}\n" From ca4e8f14dd44fdcae1f441823ac079fdd9d8de53 Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Wed, 13 Aug 2025 09:56:58 +0800 Subject: [PATCH 7/9] 10_linux: inform if no initrd is found for the kernel --- util/grub.d/10_linux.in | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 195590fb8..b5ac2b4c1 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -90,6 +90,7 @@ for rd in ${GRUB_EARLY_INITRD_LINUX_STOCK[@]} \ if [ -e "$KERNEL_DIR"/"$rd" ] ; then INITRD_EARLY="${INITRD_EARLY} ${KERNEL_DIR}/${rd}" fi + INITRD_EARLY="${INITRD_EARLY##[ ]}" done # Returns the default page size suffix. # WARN $arch is the output of `uname -m`, which is not exactly the same as @@ -297,14 +298,18 @@ get_initrd() { initrd.img-"$1" \ initrd-"$1".gz ; do if [ -e "$KERNEL_DIR/$rd" ] ; then - info "$(gettext_printf "Initial ramdisk image for kernel %s: %s" "$1" "${GRUB_KERNEL_DIR}${rd}")" + info "$(gettext_printf "Initial ramdisk image for kernel '%s': '%s'" "$1" "${GRUB_KERNEL_DIR}${rd}")" ret="${ret} ${GRUB_KERNEL_DIR}${rd}" break else continue fi done - printf "%s" "$ret" + if [ -n "$ret" ] ; then + printf "%s" "$ret" + else + info "$(gettext_printf "No initial ramdisk image found for kernel '%s'" "$1")" + fi } process_kernels() { From dbdc8beb4fc4ee39b5bed8090eba6ef38cc6b480 Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Fri, 15 Aug 2025 10:22:02 +0800 Subject: [PATCH 8/9] 10_linux: Sort kernel versions in the submenu; Add various comments --- util/grub.d/10_linux.in | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index b5ac2b4c1..98d1d828b 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -71,8 +71,10 @@ else GRUB_KERNEL_DIR="/" fi +# search --fs-uuid commands. MENUENTRY_PREP="$(prepare_grub_to_access_device "$GRUB_DEVICE_BOOT")" +# set gfxpayload= directrives. if [ -z "$GRUB_GFXPAYLOAD_LINUX" ] ; then _GFXPAYLOAD_LINUX="set gfxpayload=keep" else @@ -92,6 +94,7 @@ for rd in ${GRUB_EARLY_INITRD_LINUX_STOCK[@]} \ fi INITRD_EARLY="${INITRD_EARLY##[ ]}" done + # Returns the default page size suffix. # WARN $arch is the output of `uname -m`, which is not exactly the same as # `dpkg --print-architecture`. @@ -106,6 +109,7 @@ default_pagesize() { esac } +# Localize page size comment string. pagesize_str() { case "$1" in 4k) @@ -182,13 +186,14 @@ get_comments() { printf "%s" " ($comment)" } +# Generates a menuentry for linux. linux_entry() { title="$1" kernel="$2" initrd="$3" args="$4" _id="$5" - + printf "${indent}menuentry '%s' --class linux \$menuentry_id_option '%s' {\n" "$title" "$_id" printf "$(echo "$MENUENTRY_PREP" | sed "s|^|\t${indent}|g")\n" printf "${indent}\t$_GFXPAYLOAD_LINUX\n" @@ -204,8 +209,12 @@ linux_entry() { printf "${indent}}\n\n" } +# Get the root= parameter depending on various conditions. find_rootdev() { local ident_type=uuid + # If UUID is disabled, use PARTUUID if PARTUUID is available. + # Otherwise use plain paths (which is dangerous, but there's + # nothing we can do anyways. if ! [ -e "$GRUB_DEVICE" ] ; then ident_type=error elif bool "$GRUB_DISABLE_LINUX_UUID" || [ "$1" = "fallback" ] ; then @@ -312,11 +321,13 @@ get_initrd() { fi } +# Make all variants of the latest version appear on the top level menu. +# Everything else go into the submenu. process_kernels() { local kernel uname_r latest latest_kernels localpart - # Use the latest non-RC kernel. - # Whatever. I don't care. IFS=$'\n' + # Process the latest kernel(s). + # Never asusme there's only one variant here! latest="${KERNEL_VERSIONS[0]}" latest_kernels=($(echo "${KERNELS[*]}" | grep "$latest")) latest_kernels=($(prioritize ${latest_kernels[@]})) @@ -349,9 +360,14 @@ process_kernels() { return fi submenu_title="$(gettext_printf "More kernel options for %s" "$OS")" + # Sort other versions. However we can't prioritize them, it will + # mess up the order. + IFS=$'\n' + unprocessed_sorted=($(echo "${UNPROCESSED_VERSIONS[*]}" | sort -rVu)) + unset IFS printf "submenu '%s' {\n" "$submenu_title" indent="$indent$tab" - for version in "${UNPROCESSED_VERSIONS[@]}" ; do + for version in "${unprocessed_sorted[@]}" ; do IFS=$'\n' kernels=($(echo "${KERNELS[*]}" | grep "$version")) unset IFS From 5daedd627358a1e7a93126a1ecc1d0f336933bd4 Mon Sep 17 00:00:00 2001 From: Xinhui Yang Date: Fri, 15 Aug 2025 10:27:54 +0800 Subject: [PATCH 9/9] 10_linux: pagesize -> configuration Since we may have other variant specific configurations other than page sizes. This makes it easier for other maintainers to add localized strings. --- util/grub.d/10_linux.in | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 98d1d828b..a9d858969 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -98,7 +98,7 @@ done # Returns the default page size suffix. # WARN $arch is the output of `uname -m`, which is not exactly the same as # `dpkg --print-architecture`. -default_pagesize() { +default_configuration() { case "$arch" in loongarch64) printf "16k" @@ -110,24 +110,24 @@ default_pagesize() { } # Localize page size comment string. -pagesize_str() { +configuration_str() { case "$1" in 4k) - if [ "$(default_pagesize)" = "$1" ] ; then + if [ "$(default_configuration)" = "$1" ] ; then printf "" else gettext_printf "4K Page Size" fi ;; 16k) - if [ "$(default_pagesize)" = "$1" ] ; then + if [ "$(default_configuration)" = "$1" ] ; then printf "" else gettext_printf "16K Page Size" fi ;; 64k) - if [ "$(default_pagesize)" = "$1" ] ; then + if [ "$(default_configuration)" = "$1" ] ; then printf "" else gettext_printf "64K Page Size" @@ -159,13 +159,21 @@ variant_str() { } # Break localversion apart, return the processed comments. +# The LOCALVERSION comes with several parts: +# -VENDOR-VARIANT-CONFIGURATOIN +# Where: +# - VENDOR: Undoubtably, "aosc". +# - VARIANT: The variant of the kernel, built for specific purposes or +# devices, e.g. "main" for mainline kernel, "lts" for LTS kernel, and +# "asahi" for Apple Silicon devices. +# - CONFIGURATION: Variant specific configurations, e.g. page sizes. # E.g. # - "-aosc-main" -> "" # - "-aosc-lts" -> " (LTS Kernel)" # - "-aosc-main-4k" -> " (4K Page Size)" # - "-aosc-rc-4k" -> " (RC Kernel, 4K Page Size)" get_comments() { - local _str="$1" _fullver="$1" segs=() comments=() sep=", " variant pagesize + local _str="$1" _fullver="$1" segs=() comments=() sep=", " variant configuration # Not an AOSC OS kernel if ! [[ "$_str" =~ \.[0-9]+-aosc- ]] ; then return @@ -176,8 +184,8 @@ get_comments() { segs=($_str) unset IFS variant="$(variant_str "${segs[0]}")" - pagesize="$(pagesize_str "${segs[1]}")" - comment="${variant}${sep}${pagesize}" + configuration="$(configuration_str "${segs[1]}")" + comment="${variant}${sep}${configuration}" if [ "x$comment" = "x$sep" ] ; then return fi @@ -255,10 +263,10 @@ find_rootdev() { # The kernel with the default size will be always on top. If it does # not exist, then the kernel without page size suffix will be on top. prioritize() { - local kernels newkernels default_pgsize flag + local kernels newkernels default_configuration flag kernels=("$@") newkernels=() - default_pgsize="$(default_pagesize)" + default_configuration="$(default_configuration)" for k in "${kernels[@]}" ; do # This system probably don't have other page sizes. if [ "${k%%-[0-9]*k}" = "$k" ] ; then @@ -269,7 +277,7 @@ prioritize() { fi continue fi - if [ "${k%%-$default_pgsize}" != "$k" ] ; then + if [ "${k%%-$default_configuration}" != "$k" ] ; then newkernels=("$k" "${newkernels[@]}") continue fi