repos/kloeckner.com.ar

Backup of part of my webpage
Commits Files Refs README LICENSE
blog/grub-linux-version-fix/grub-linux-version-fix.md (63 lines)

%% title: "GRUB Menu: Linux Version Not Detected" date: "02-Nov-2024" %%

GRUB Menu: Linux Version Not Detected

If your grub installation doesn't detect the Linux versions properly, and displays it wrong in the prompt menu at boot, like in my case in which appeared as Arch Linux with Linux version linux, you can solve it by modifying the helper scripts which grub uses to build the configuration file.

The problem is caused by the script grub-mkconfig which is used to build the grub configuration file grub.cfg (generally located on /boot/grub/).

The script grub-mkconfig uses other helper scripts located on /etc/grub.d/, and in particular the file used to detect the Linux version is /etc/grub.d/10_linux, which uses the file name of the kernel file to detect the version (for example /boot/vmlinuz-6.1.0-25-amd64). The issue is caused on distributions like Arch Linux that doesn't add the suffix of version to the main kernel file (for example /boot/vmlinuz-linux).

The solution is to to modify the file /etc/grub.d/10_linux and make the following changes (also as a diff file):

--- /etc/grub.d/10_linux
+++ /etc/grub.d/10_linux
@@ -144,7 +144,7 @@
     fi
     printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
   fi
-  message="$(gettext_printf "Loading Linux %s ..." ${version})"
+  message="$(gettext_printf "Loading Linux %s ..." ${display_version})"
   sed "s/^/$submenu_indentation/" << EOF
    echo	'$(echo "$message" | grub_quote)'
    linux	${rel_dirname}/${basename} root=${linux_root_device_thisversion} rw ${args}
@@ -217,6 +217,7 @@
   dirname=`dirname $linux`
   rel_dirname=`make_system_path_relative_to_its_root $dirname`
   version=`echo $basename | sed -e "s,vmlinuz-,,g"`
+  display_version=`file $linux | grep -oP '(?<=version )\S*'`
   alt_version=`echo $version | sed -e "s,\.old$,,g"`
   linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
 
@@ -290,7 +291,7 @@
   fi
 
   if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then
-    linux_entry "${OS}" "${version}" simple \
+    linux_entry "${OS}" "${display_version}" simple \
     "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
 
     submenu_indentation="$grub_tab"

This modification makes the script 10_linux get the Linux version, from the output of the file command executed on the kernel file (for example $ file /boot/vmlinuz-linux). Note that the output of the command is filtered using GNU grep with Perl syntax (-P option) this allows the use of positive look-behind regex (?<=version).

   1 %%
   2 title: "GRUB Menu: Linux Version Not Detected"
   3 date: "02-Nov-2024"
   4 %%
   5 
   6 # GRUB Menu: Linux Version Not Detected
   7 
   8 If your grub installation doesn't detect the Linux versions properly, and
   9 displays it wrong in the prompt menu at boot, like in my case in which appeared
  10 as `Arch Linux with Linux version linux`, you can solve it by modifying the
  11 helper scripts which grub uses to build the configuration file.
  12 
  13 The problem is caused by the script `grub-mkconfig` which is used to build the
  14 grub configuration file `grub.cfg` (generally located on `/boot/grub/`).
  15 
  16 The script `grub-mkconfig` uses other helper scripts located on `/etc/grub.d/`,
  17 and in particular the file used to detect the Linux version is
  18 `/etc/grub.d/10_linux`, which uses the file name of the kernel file
  19 to detect the version (for example `/boot/vmlinuz-6.1.0-25-amd64`). The issue is
  20 caused on distributions like Arch Linux that doesn't add the suffix of version
  21 to the main kernel file (for example `/boot/vmlinuz-linux`).
  22 
  23 The solution is to to modify the file `/etc/grub.d/10_linux` and make the
  24 following changes (also as a [diff file](https://gist.githubusercontent.com/mjkloeckner/214a0ee42c920affe572e12e933a1bb0/raw/24bda0dfa02c7baba3b983fb71662c1904645fa8/fix-grub-linux-display-version.diff)):
  25 
  26 ```diff
  27 --- /etc/grub.d/10_linux
  28 +++ /etc/grub.d/10_linux
  29 @@ -144,7 +144,7 @@
  30      fi
  31      printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
  32    fi
  33 -  message="$(gettext_printf "Loading Linux %s ..." ${version})"
  34 +  message="$(gettext_printf "Loading Linux %s ..." ${display_version})"
  35    sed "s/^/$submenu_indentation/" << EOF
  36      echo    '$(echo "$message" | grub_quote)'
  37      linux    ${rel_dirname}/${basename} root=${linux_root_device_thisversion} rw ${args}
  38 @@ -217,6 +217,7 @@
  39    dirname=`dirname $linux`
  40    rel_dirname=`make_system_path_relative_to_its_root $dirname`
  41    version=`echo $basename | sed -e "s,vmlinuz-,,g"`
  42 +  display_version=`file $linux | grep -oP '(?<=version )\S*'`
  43    alt_version=`echo $version | sed -e "s,\.old$,,g"`
  44    linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
  45  
  46 @@ -290,7 +291,7 @@
  47    fi
  48  
  49    if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then
  50 -    linux_entry "${OS}" "${version}" simple \
  51 +    linux_entry "${OS}" "${display_version}" simple \
  52      "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
  53  
  54      submenu_indentation="$grub_tab"
  55 ```
  56 
  57 This modification makes the script `10_linux` get the Linux version, from the
  58 output of the `file` command executed on the kernel file (for example `$ file
  59 /boot/vmlinuz-linux`). *Note* that the output of the command is filtered using
  60 GNU grep with Perl syntax (`-P` option) this allows the use of positive
  61 look-behind regex `(?<=version)`.
  62 
  63 * [Previous diff file as GitHub gist](https://gist.github.com/mjkloeckner/214a0ee42c920affe572e12e933a1bb0)