Linux – GRUB_DEFAULT seems to be ineffectual when trying to boot a custom kernel by ID on Debian 8

grub2kernellinuxlinux-kernel

I've built a custom kernel on a Debian 8 machine, and I want to set it as the default. A seemingly simple task, but I can't get it to work for the life of me.

I built my kernel using the official source code (via git), not using the vendor tarball provided my debian. Once built, I installed the kernel and modules with:

$ sudo make modules_install install

This installed a new menu entry into grub, which indeed works if you manually select it at boot time. So that's good.

Now, to get this to boot by default, I must edit /etc/default/grub and change GRUB_DEFAULT. At the top of the file is a comment pointing the user to an info page, which says:

'GRUB_DEFAULT'
     The default menu entry.  This may be a number, in which case it
     identifies the Nth entry in the generated menu counted from zero,
     or the title of a menu entry, or the special string 'saved'.  Using
     the id may be useful if you want to set a menu entry as the default
     even though there may be a variable number of entries before it.

     For example, if you have:

     menuentry 'Example GNU/Linux distribution' --class gnu-linux --id example-gnu-linux {
        ...
     }

     then you can make this the default using:

          GRUB_DEFAULT=example-gnu-linux

     Previously it was documented the way to use entry title.  While
     this still works it's not recommended since titles often contain
     unstable device names and may be translated

     If you set this to 'saved', then the default menu entry will be
     that saved by 'GRUB_SAVEDEFAULT' or 'grub-set-default'.  This
     relies on the environment block, which may not be available in all
     situations (*note Environment block::).

     The default is '0'.

First, it's unclear from the prose if an "id" is the same as a "title". That aside, it looks like I should use the string after the --id in the generated grub config.

So, make install inserted the following into /boot/grub/grub.cfg:

    menuentry 'Debian GNU/Linux, with Linux 3.16.36krunsystickless+' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-3.16.36krunsystickless+-advanced-197f20c1-1808-41b5-831f-b85a40358757' {
        load_video                                                              
        insmod gzio                                                             
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi      
        insmod part_msdos                                                       
        insmod ext2                                                             
        set root='hd0,msdos1'                                                   
        if [ x$feature_platform_search_hint = xy ]; then                        
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  197f20c1-1808-41b5
-831f-b85a40358757
        else                                                                    
          search --no-floppy --fs-uuid --set=root 197f20c1-1808-41b5-831f-b85a40358757
        fi                                                                      
        echo    'Loading Linux 3.16.36krunsystickless+ ...'                     
        linux   /boot/vmlinuz-3.16.36krunsystickless+ root=UUID=197f20c1-1808-41b5-831f-b85a40358757 ro  quiet console=ttyS0,115200n8 intel_psta
te=disable
        echo    'Loading initial ramdisk ...'                                   
        initrd  /boot/initrd.img-3.16.36krunsystickless+                        
    }

Where, earlier in the file $menuentry_id_option is set:

if [ x"${feature_menuentry_id}" = xy ]; then                                    
  menuentry_id_option="--id"                                                    
else                                                                            
  menuentry_id_option=""                                                        
fi

So presumably, I should set GRUB_DEFAULT in /etc/grub/default to:

gnulinux-3.16.36krunsystickless+-advanced-197f20c1-1808-41b5-831f-b85a40358757

Then run:

$ sudo update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.16.36softdevnohzfullall
Found initrd image: /boot/initrd.img-3.16.36softdevnohzfullall
Found linux image: /boot/vmlinuz-3.16.36krunsystickless+
Found initrd image: /boot/initrd.img-3.16.36krunsystickless+
Found linux image: /boot/vmlinuz-3.16.36krunsystickless+.old
Found initrd image: /boot/initrd.img-3.16.36krunsystickless+
Found linux image: /boot/vmlinuz-3.16.0-4-amd64
Found initrd image: /boot/initrd.img-3.16.0-4-amd64
done

Before finally rebooting.

But this does not seem to work. The same kernel as before is instead booted. Does anyone know why?

Other things I have tried:

  • Numeric index GRUB_DEFAULTS — seem to have no effect.
  • Escaping the plus in the kernel id.
  • grub-set-default

I'm going to look into feature_menuentry_id now, but I have a feeling it will be a red herring. If anyone can put me out of my misery in the meantime, I will be most grateful.

Thanks

Best Answer

In the end I managed to boot my kernel with the following line in /etc/default/grub:

GRUB_DEFAULT=gnulinux-advanced-197f20c1-1808-41b5-831f-b85a40‌​358757>gnulinux-3.16‌​.36krunsystickless+-‌​advanced-197f20c1-18‌​08-41b5-831f-b85a403‌​58757

The documentation is misleading. You cannot simply put the ID into GRUB_DEFAULT if there is a sub-menu involved. You have to think in terms of navigating the grub menu using (potentially many) ids. The > above (which I've not found in the docs btw) means "go into this sub-menu".

I hope this helps others confused by this same issue.

Cheers