If you’re like me, most of the time I prefer to just work in Linux and only rarely use Windows in my dual-boot setup. So, I’d rather only see the GRUB menu if I’m holding down a key to switch into Windows and otherwise simply default to Ubuntu. The process to set that up is a little involved, though, so be warned!
But first off, a mandatory disclaimer.
Disclaimer
Follow these instructions at your own risk. Make sure to backup your data and/or GRUB configuration in case something goes wrong. Furthermore, editing your GRUB configuration has a risk in resulting in an unbootable system, so make sure to do your own research.
Hiding the menu in GRUB options
The process outlined here is mainly from Arch Linux’s wiki 1, but with some modifications to work on Ubuntu.
First, we have to enable the hidden menu by adding the following options in /etc/default/grub
GRUB_FORCE_HIDDEN_MENU="true"
GRUB_GFXPAYLOAD_LINUX=keep
You might be wondering why we have to enable GRUB_GFXPAYLOAD_LINUX=keep
. In fact, it’s currently a known error where hwmatch (a module that has allowlists and denylists for certain hardware platforms) is omitted from 64-bit based linux distributions, so GRUB scripts relying on the module will show an error such as error: can't find command hwmatch
2.
The fix recommended in the bug report is to enable GRUB_GFXPAYLOAD_LINUX=keep
which causes the GRUB scripts to skip the logic requiring hwmatch
, effectively hiding the error 3.
Creating the GRUB scripts
Then we copy the script linked to in Arch Linux’s guide to /etc/grub.d/31_hold_shift
. However, we have to modify a couple lines for it to work on Ubuntu.
If we don’t, then you’ll see an error like /etc/grub.d/31_hold_shift: 10: source: not found
when running update-grub
.
To fix the issue, we remove the following lines,
prefix="/usr"
exec_prefix="${prefix}"
datarootdir="${prefix}/share"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
source "${datarootdir}/grub/grub-mkconfig_lib"
replacing it with the below.
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
quick_boot="1"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
. "$pkgdatadir/grub-mkconfig_lib"
These lines were taken directly from the other grub scripts already in /etc/grub.d/
. It seems like the source
command in particular is not available when running update-grub
.
An important thing to note is that this script uses keystatus, which might not be available as pointed out in the Arch Linux wiki. If that is the case, you likely won’t be able to enter the GRUB menu without removing all the modifications we’ve done so far.
Finalizing the GRUB script
Now that we finished editing the GRUB script, just make it executable and run update grub.
sudo chmod a+x /etc/grub.d/31_hold_shift
sudo update-grub
Now reboot, and all should be good to go!
Related posts
Must-reads
An Amazing Win at the NYC Student Disrupt Hackathon
What I learned from hacking Google Chrome
What I learned winning 3rd place at StuyHacks IX: Misconceptions about Hackathons and Tips for Success
How I optimized my fractal viewer and the things I learned along the way