help-grub
[Top][All Lists]
Advanced

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

A grub.cfg script to list linux kernel versions at runtime


From: Paul Gover
Subject: A grub.cfg script to list linux kernel versions at runtime
Date: Sat, 30 Jan 2021 13:38:40 +0000

I'm not fond of the grub.cfg made by grub-mkconfig, as I don't wish to build a 
new grub.cfg each time I update my linux kernel version.  So instead I use a 
hand-scripted grub.cfg that by default lists "vmlinuz" and "vmlinux.old", and 
use symlinks maintained by the kernels "make install" and "installkernel" 
script.  So far so good.

However, if things go wrong, it would be good to have a grub submenu of the 
available kernels by version number.  It turns out it's possible to code this 
in the grub.cfg script language.  It's very inefficient, but as the only user 
is the grub screen, it will do.  I thought I'd share the script functions with 
the grub commmunity:

### Compare version numbers; returns true if $1 precedes $2
### Paul Gover, 2021.
function precedes {
        # regex calls prefix strings with X to avoid leading hyphens being      
        # interpreted as options
        # Note, if grub script supported printf, it would be much faster to 
        # create a canonical version from the  VMR-rc fields
        # (e.g. 5.9.2-rc3 -> 005090203) 

        # Parse out V.R.M from the parameters
        regexp --set=1:a --set=2:arc "([0-9.]+)(.*\$)" "X$1"
        regexp --set=1:b --set=2:brc "([0-9.]+)(.*\$)" "X$2"

        while true
        do
                a1=""
                b1=""
                # Parse out the next numeric field in the V.R.M
                regexp --set=1:a1 --set=2:a "([0-9]+)(.*\$)" "X$a"
                regexp --set=1:b1 --set=2:b "([0-9]+)(.*\$)" "X$b"

                # In the following comparisons, append 0s to prevent    
                # invalid null string comparisons
                if   [ "${a1}0" -lt "${b1}0" ]
                then return 0
                elif [ "${a1}0" -gt "${b1}0" ]
                then return 1
                elif [ "$a1$b1" = "" ]
                then break
                fi 

        done
        # V.R.M equal, assume the rest contain
        # release candidate (rc) numbers
        regexp --set=a1 "([0-9]+)" "X$arc"
        regexp --set=b1 "([0-9]+)" "X$brc"

        # Note that e.g. 5.4.6-rc1 PRECEDES 5.4.6, since the latter
        # is a real release, not a candidate
        if   [ -z "$a1" ]
        then return 1
        elif [ -z "$b1" ]
        then return 0
        fi

        # We have 2 release candidate numbers; compare them
        test "${a1}0" -lt "${b1}0"
}

# A submenu for each versioned kernel name in /boot
submenu --id="kernel_list.new" "Kernels by version --->" "$KernelOptions" {
        spacer "Kernels by version"
        spacer

        # Generate the list of kernels sorted by decending order
        # of version number
        # This is a very inefficient algorithm,
        # but noone else is using the cpu...
        last="-99999999"
        max="-00000000"
        while true
        do
                next="$max"
                for kernel in /boot/vmlinuz-*
                do
                    regexp --set=suffix "^/boot/vmlinuz(.*)" "$kernel"
                    if precedes "$next" "$suffix"
                        then    if precedes "$suffix" "$last"
                                then next="$suffix"
                                fi
                        fi
                done

                if [ "$next" = "$max" ]
                then break
                fi

                menuentry "Gentoo GNU/Linux vmlinuz$next" {
                        linux /boot/vmlinuz$next
                }
                last="$next"
        done
}




reply via email to

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