While traveling, I have been asked a few times by security agents at airports to turn on my laptop, and well, show them it did work, and looked like a real computer.
Although they never searched the content and nothing bad ever happend, every time I cross the border or go through security I am worried about what might happen, especially given recent stories of people being searched and their laptops taken away for further inspection.
The fact I use full disk encryption does not help: if I was asked to boot, my choice would be to either enter the password and login, thus disclosing most of the content of the disk, or refuse and probably have my laptop taken away for further inspection.
So.. for the first time in 10 years, I decided to keep Windows on my personal laptop. Even more, leave it as the default operating system in GRUB, and well, not show up GRUB at all during boot.
Not because I think it is safer this way, but just to create as little pretexts or excuses for anyone to further poke at my laptop, in case I need to show it or they need to inspect it.
Getting grub out of the way was not as easy as it should have been, so this post is to document what I did.
First of all, here are the problems:
The Debian GRUB setup scripts create a menu entry in GRUB for each kernel you have installed, followed by other detected Operating Systems. This means that every time you install a new kernel, the entry number of other Operating Systems change (eg, Windows becomes the 3rd entry, or 4th entry, ...). Given that the default Operating System is specified by entry number, if you want to default to windows, well, it doesn't play out well.
By default, GRUB will show a menu. If you disable that menu (relatively easy), it will still show a "Loading GRUB." message followed by "Welcome to GRUB!", something like:
Loading GRUB. Welcome to GRUB!
Turns out that those messages are not configurable, as they are printed before any config file can be read by GRUB. Ubuntu and a few other vendors have provided a patched version of GRUB, but I really don't want to go down that path: don't want to keep installing my own version of GRUB or patch and recompile for each new release.
So, here's what I did...
There might be better ways to provide a default that is not an integer, the name of an entry, for example. However, I really wanted windows to show up first in GRUB.
To fix the order of the menu entries, I:
Opened /boot/grub/grub.cfg
, and manually copied the entry for Windows I wanted
to keep. In my case, the entry was:
menuentry "Windows 7 (loader) (on /dev/sda2)" --class windows --class os { insmod part_msdos insmod ntfs set root='(hd0,msdos2)' search --no-floppy --fs-uuid --set=root F646B41846B3D817 chainloader +1 }
Disabled automated discovery of operating systems. I don't care, I don't install new systems that often, and when I do, I'm well aware I have to update grub config. To do so, you need to:
$ sudo -s # vim /etc/default/grub ... GRUB_DISABLE_OS_PROBER=true
eg, add GRUB_DISABLE_OS_PROBER=true
to /etc/default/grub
.
In /etc/grub.d
, added a script 06_windows
like this:
$ sudo -s # cd /etc/grub.d # cat > 06_windows <<EOF #!/bin/sh exec tail -n +3 $0 menuentry "Windows 7 (loader) (on /dev/sda2)" --class windows --class os { insmod part_msdos insmod ntfs set root='(hd0,msdos2)' search --no-floppy --fs-uuid --set=root F646B41846B3D817 chainloader +1 } EOF # chmod 0755 ./06_windows
Run update-grub
to get the grub configuration updated for real.
/boot/grub/grub.cfg
manually, and reboot
to
verify. Windows should be the first entry now.This was relatvely easy to do, just edit /etc/default/grub
, make sure you
have the following lines:
GRUB_DEFAULT=0 GRUB_TIMEOUT=0 GRUB_HIDDEN_TIMEOUT=5 GRUB_HIDDEN_TIMEOUT_QUIET=true
The first line will tell grub to start Windows by default (the first boot entry), the second one tells grub to show the menu for 0 seconds by default, thus not showing it, the 3rd one will wait for 5 seconds for you to press a key before the menu, the last one will not show the counter going from 5 to 0 before showing the menu.
The only hiccup I had here was that most of the documents say you have to hold shift
to get into the menu, but no, for me I had to press ESC
, or any other key? I still
need to try :).
Don't forget to run update-grub
and reboot
to test this out. You should see that
despite the changes, you will still have a Loading GRUB.
message, and a Welcome to GRUB!
,
although nothing else will show up before booting Windows.
So, how do you get rid of the annoying:
Loading GRUB. Welcome to GRUB!
? Most forums and online discussions will tell you to patch the GRUB source code and recompile. Those messages are printed out well before any config file can be loaded, and there are really not that many alternatives.
I really didn't want to patch, as I did not want to maintain a set of patched binaries for my own use on my own system (yes, I love keeping the system up to date! And I love playing with testing/unstable, which means frequent updates).
The idea was simple: if the messages are displayed, they must be stored somewhere.
And if any equivalent of printf
is used, I can replace the first character of each
of those strings with a \0
to prevent them from showing up.
This is terribly terribly hacky. But 2 hours of work to find the right files and the right process gave me exactly what I wanted: a tool that modifies a few of the grub files to remove the messages, which works like a charm.
By adding a hook in /etc/initramfs-tools
or /etc/grub.d
, I can just run
the tool every time grub configs are changed, without having to recompile and patch the source.
I've just uploaded some code to github
if you want to try it. Read the README
, but it should be really straightforward to
get it rolling.
Again, don't expect too much, it's not clean and beautiful, it only works.
Most distributions used an entirely different path: patching GRUB to unconditionally disable those messages. As a user, I'd rather prefer to have the choice to disable those messages or not, especially given the fact that those messages can be useful for debugging.
Unsurprisingly, the GRUB maintainers refused those patches, which are now maintained separately by each distro that includes them.
Related to grub-shusher
, I will need to update it every time bootstrap.S
and a few
other .S
files change in GRUB. This doesn't happen often, but I am sure I
will eventually grow tired of maintaining it.
It would still be great to have a real, supported, solution for configuration parameters that are needed before, well, a configuration file can be read and loaded.
Here are some proposals:
It would not be hard to add some sort of watermark before each configuration
variable in the .S file, and binary blobs?
Then we could have a tool like grub-shusher
that reliably
can find those watermarks, the corresponding variables, and change them directly
into the binary? For example, in bootstrap.S
we could have a bool
to determine
if messages have to displayed or not, code would check that bool value before
displaying the messages. Before that bool definition, we can add a
watermark like 0xabcd
(any value that is not used throughout the binary, really)
to indicate that the following bytes are a configurable bool? Have something
like grub-shusher
find those watermarks, and allow to change them. This is
probably worth doing if there are more variables than well, just one.
Ship GRUB with variances of kernel.img
, with different parameters compiled
in, and let grub-install
figure out which variances to install on the
MBR based on user configs or command line flags. This would work only if there
are a handful of variables, as the number of combinations would explode exponentially.
It seems brittle, but would work.