34

I'm running GRUB 2.00 on a Gentoo Linux system.

I compile my own kernels manually, and then I install them in /boot with make install. I have the following kernels in /boot at the moment:

# ls -1 /boot/vmlinuz*
/boot/vmlinuz-3.7.4-gentoo-5
/boot/vmlinuz-3.7.4-gentoo-first
/boot/vmlinuz-3.7.4-gentoo-fourth
/boot/vmlinuz-3.7.4-gentoo-third

Running grub2-mkconfig results in the following output:

# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.7.4-gentoo-third
Found linux image: /boot/vmlinuz-3.7.4-gentoo-fourth
Found linux image: /boot/vmlinuz-3.7.4-gentoo-first
Found linux image: /boot/vmlinuz-3.7.4-gentoo-5
done

If I now read the resulting /boot/grub2/grub.cfg file, I notice that the following entries have been created:

  • A main default entry which starts vmlinuz-3.7.4-gentoo-third
  • A submenu with the all the other entries (including recovery ones), in the same order as the grub2-mkconfig command

The problem is that at boot time I'd like to load by default the fifth revision of my kernel (vmlinuz-3.7.4-gentoo-5), not the third one (vmlinuz-3.7.4-gentoo-third). I also prefer not to access the submenu for choosing the right kernel to load.

How can I change this behaviour? How can I tell GRUB that I want to run the fifth revision of my kernel by default and not the older third revision? In general, how can I change the default entry line to match the kernel I want and not a seemingly random one picked by GRUB?

I also tried putting the following lines in /etc/default/grub:

GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

This doesn't fix the problem the way I desire. But at least GRUB seems to remembers the latest kernel I booted from and automatically selects it from the submenu. It's just that I don't like to access the submenu.

  • I noticed you specified -o /boot/grub2/grub.cfg as output file. Does the directory /boot/grub/ still exist? – ott-- Feb 26 '13 at 14:01

11 Answers11

21

To select a menu entry under the sub-menu "Advanced options" set GRUB_DEFAULT="1>3". You can now run grub2-mkconfig to generate the grub config file. On the next reboot vmlinuz-3.7.4-gentoo-5 should boot.

Note: This won't change the default entry in the grub menu, i.e., the default entry will still indicate the same entry as you have right now. But the image which will be booted by default will be the 4th image under the "Advanced options". To make the vmlinuz-3.7.4-gentoo-5 as the default entry in the grub menu, the ordering of images should be such that the vmlinuz-3.7.4-gentoo-5 should be the first image when you run grub2-mkconfig.

Anthon
  • 79,293
anaken78
  • 311
12

If you have a submenu in your grub.cfg you should use two digits like this:

grub-reboot '1>3'

The first is menu index, and the second is submenu index.

For example, to boot last entry from config like this:

grep menu /boot/grub/grub.cfg

menuentry 'Debian GNU/Linux' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-1ffa16a9-fda2-43b5-91b9-c91a08ff190f' {
submenu 'Advanced options for Debian GNU/Linux' $menuentry_id_option 'gnulinux-advanced-1ffa16a9-fda2-43b5-91b9-c91a08ff190f' {
    menuentry 'Debian GNU/Linux, with Linux 4.6.0-0.bpo.1-amd64' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.6.0-0.bpo.1-amd64-advanced-1ffa16a9-fda2-43b5-91b9-c91a08ff190f' {
    menuentry 'Debian GNU/Linux, with Linux 4.6.0-0.bpo.1-amd64 (sysvinit)' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.6.0-0.bpo.1-amd64-init-sysvinit-1ffa16a9-fda2-43b5-91b9-c91a08ff190f' {
    menuentry 'Debian GNU/Linux, with Linux 4.6.0-0.bpo.1-amd64 (recovery mode)' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.6.0-0.bpo.1-amd64-recovery-1ffa16a9-fda2-43b5-91b9-c91a08ff190f' {
    menuentry 'Debian GNU/Linux, with Linux 3.16.0-4-amd64' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-3.16.0-4-amd64-advanced-1ffa16a9-fda2-43b5-91b9-c91a08ff190f' {
    menuentry 'Debian GNU/Linux, with Linux 3.16.0-4-amd64 (sysvinit)' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-3.16.0-4-amd64-init-sysvinit-1ffa16a9-fda2-43b5-91b9-c91a08ff190f' {
    menuentry 'Debian GNU/Linux, with Linux 3.16.0-4-amd64 (recovery mode)' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-3.16.0-4-amd64-recovery-1ffa16a9-fda2-43b5-91b9-c91a08ff190f' {

you should use:

grub-reboot '1>5'

and reboot.

AstraSerg
  • 231
  • 6
    Weird. submenu index start with 0, while main menu from 1 –  Sep 19 '17 at 14:38
  • @VarunAgw that's NOT weird; both of them start at 0. In 1>5, the 1 refers to the second entry at toplevel (in this case the submenu) while the 5 refers to the sixth item inside that submenu. The name submenu is probably poorly chosen; it shoud probably be something like menuentry-with-subentries or something.

    Also, the correct command is grub-set-default, not grub-reboot, since the latter only holds for the next reboot, while the former is permanent.

    – xdavidliu Aug 27 '22 at 20:11
  • also, note that grub-set-default requires GRUB_DEFAULT=saved in /etc/default/grub in order to have an effect – xdavidliu Aug 27 '22 at 20:49
8

With centos7 (or RHEL7) and grub2:

grub uses 'saved_entry' entry from grubenv as default to boot, sniplet from /boot/grub2/grub.cfg:

if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="${saved_entry}"
fi

to check what is the 'saved_entry' is now my build:

grub2-editenv list

saved_entry=CentOS Linux (3.10.0-693.2.2.el7.ari.x86_64) 7 (Core)

to change it e.g to my debug build:

grub2-editenv - set saved_entry='CentOS Linux 3.10.0-693.2.2.el7.ari.x86_64.debug) 7 (Core)'
Gryu
  • 837
ari
  • 81
  • Works similarly with Fedora (here 34) for changing my LibreELEC entry for dual booting # grub2-editenv - set saved_entry='LibreELEC' to default. – Erich Kuester Oct 24 '21 at 09:32
6

you may as well use GRUB_DEFAULT=saved. In this case you'd use

$ grub2-set-default -h
Usage: grub2-set-default [OPTION] MENU_ENTRY
Set the default boot menu entry for GRUB.

  -h, --help              print this message and exit
  -v, --version           print the version information and exit
  --boot-directory=DIR    expect GRUB images under the directory DIR/grub2
                          instead of the /boot/grub2 directory

MENU_ENTRY is a number, a menu item title or a menu item identifier.

or if it's only for the next boot:

$ grub2-reboot -h
Usage: grub2-reboot [OPTION] MENU_ENTRY
Set the default boot menu entry for GRUB, for the next boot only.

  -h, --help              print this message and exit
  -v, --version           print the version information and exit
  --boot-directory=DIR    expect GRUB images under the directory DIR/grub2
                          instead of the /boot/grub2 directory

MENU_ENTRY is a number, a menu item title or a menu item identifier.
Flow
  • 854
  • 1
  • 11
  • 23
2

Try

mkdir -p /boot/grub/backup
mv -v /boot/grub/vmlinuz-3.7.4-gentoo-{first,third,fourth} /boot/grub/backup

This moves all your unused kernels to a backup directory, now:

grub2-mkconfig -o /boot/grub/grub.cfg

This only adds choice r5 to your menu. After doing so, read this this link and then reame all the kernels in the backup directory something other than vmlinuz if you insist on keeping them

Ramesh
  • 39,297
eyoung100
  • 6,252
  • 23
  • 53
1

I suspect that grub2-mkconfig sorts the kernels in reverse order, assuming that they primarily contain monotonically increasing version numbers. So start picking your tags to fit that convention.

cpugeniusmv
  • 2,657
1

What I did to achieve the wanted result had been:

  • set the GRUB_DEFAULT=saved as outlined in the grub-set-default help

    grub-set-default Menu entry not specified. Usage: grub-set-default [OPTION] MENU_ENTRY Set the default boot menu entry for GRUB. This requires setting GRUB_DEFAULT=saved in /etc/default/grub. -h, --help print this message and exit -V, --version print the version information and exit --boot-directory=DIR expect GRUB images under the directory DIR/grub instead of the /boot/grub directory MENU_ENTRY is a number, a menu item title or a menu item identifier.

  • Set the default value

    grub-set-default "1>2"

    It creates a new file in /boot/grub called grubenv with the info required.

  • After it I recreate the config file

    grub-mkconfig > /boot/grub/grub.cfg

And I've seen that the config was changed to use the saved state:

if [ "${next_entry}" ] ; then set default="${next_entry}" set next_entry= save_env next_entry set boot_once=true else set default="${saved_entry}" fi

Zioalex
  • 286
0

mv those new/not used version files in /boot to a backup directory for example /boot/back

initrd.img-3.13.0-xx-generic  
vmlinuz-3.13.0-xx-generic 
config-3.13.0-xx-generic
System.map-3.13.0-xx-generic

Reboot system into rescue mode, then choose grub in rescue dialog, then everything will be okay.

It is most suitable method I think. I am using ubuntu 14.04.

Gryu
  • 837
0

in ubuntu:

sudo grub-pc

grub-pc will let you choose which menu.

sudo update-grub

see: https://askubuntu.com/questions/384388/how-to-select-option-in-configuration-grub-pc-menu

0

You can set the default choice by numerical value. If you set

`GRUB_DEFAULT=3` 

in /etc/default/grub
You will set the default to the gentoo-5 entry.
GRUB_DEFAULT is zero offset, so 3 will select the fourth entry as you wish.

bsd
  • 11,036
  • 2
    I don't know why, but it seems it doesn't work. I set GRUB_DEFAULT=3 as you said, then re-run grub2-mkconfig. But at boot time the default entry is still vmlinuz-3.7.4-gentoo-third. –  Jan 27 '13 at 12:54
  • 1
    Try commenting out GRUB_SAVEDEFAULT=true It shouldn't matter, but it's not needed with numerical. – bsd Jan 27 '13 at 14:04
  • 2
    I don't have that option in my /etc/default/grub file. –  Jan 27 '13 at 15:04
0

I wrote a simple python script to help you select the default kernel in next bootup:

import subprocess
import os
import sys
import re

if os.geteuid() != 0: subprocess.call(['sudo', 'python3', *sys.argv]) sys.exit()

output = subprocess.check_output( ("cat", "/boot/grub/grub.cfg")).decode("iso-8859-1") output = output.splitlines() display_options = [] options = [] digit1 = -1 digit2 = -1 displaynr = -1 for line in output: # +? denotes non-greedy search res = re.fullmatch( r"^(\t?)menuentry '(.+?)'.$", line) if res: displaynr += 1 if res.group(1): display_options.append(("\t" + res.group(2), displaynr)) digit2 += 1 options.append((res.group(2), f"{str(digit1)}>{str(digit2)}")) else: digit2 = -1 display_options.append((res.group(2), displaynr)) digit1 += 1 options.append((res.group(2), str(digit1))) else: res = re.fullmatch( r"^submenu '(.+?)'.$", line) if res: digit2 = -1 display_options.append((res.group(1), -1)) digit1 += 1

ljust = 3 if displaynr > 9 else 2 for i, option in enumerate(display_options): if option[1] != -1: print(f"[{option[1]}".ljust(ljust) + f"] {option[0]}") else: print(" " * ljust + f" {option[0]}")

option = int(input("\nPick one: ")) selection = options[option] print(f"Your choice: {selection[0]}")

grub = open("/etc/default/grub", 'r') lines = grub.readlines() for i, line in enumerate(lines): if re.match(r"^GRUB_DEFAULT=.*$", line): lines[i] = "GRUB_DEFAULT="" + selection[1] + ""\n"

grub = open("/etc/default/grub", 'w') grub.writelines(lines) grub.close()

subprocess.run(("update-grub"))

You can also see it in the This snippet can help you change your grub default kernel when booting up..

  • We don’t like code-only answers, or even code-mostly answers.  Please explain what this does and how it does it. … … … … … … … … … … … … … … … … … … … … … … … … Please do not respond in comments; [edit] your answer to make it clearer and more complete. – G-Man Says 'Reinstate Monica' Aug 15 '22 at 22:28