I have a PC running Windows and Linux. I want the Windows system to be the default system because this PC is mainly used for gaming.
I do, however, occasionally use it as my remote development box.
I've enabled WOL for it, so it will boot as soon as I try to access it while on the road.
Is it somehow possible to tell GRUB2 to boot into Linux when the computer is booted via WOL and boot to Windows if not?
Best Answer
I recently found a solution to this problem that works for my use-case. Although this question is rather old, I'm going to post it here for reference:
The method requires (root) access to some device other than the target PC, which should be accessible from within the PC's network - e.g. a raspberry pi or a rooted android phone. It also requires booting with UEFI. The idea is to have that device wake the PC, and simultaneously act as a TFTP server (see here for a guide) which provides a configuration file telling GRUB what to boot by setting the
default
variable. Therefore, you need:on the TFTP server, a script of the form
(just sleeping for 15 seconds is, of course, somewhat hacky and might break if multiple instances of the script are started simultaneously, especially if it contains multiple options for boot targets. A slightly cleaner solution would be to only clear the file if it wasn't changed during the 15 seconds. The potentially best solution is to use the server hooktftp, which would allow for noticing when grub accesses the file and clearing it right after. However, I did not yet have the time to test this. I will edit the post once I am sure that this works.)
This will be the script that starts up the PC. It can easily be extended to allow for multiple choices of the boot option, which can then be chosen by command-line arguments.
configuring your UEFI BIOS to initialize the network stack during booting (note that this may take multiple different BIOS options to work reliably)
finding out how to tell GRUB how to talk to your server. This took some playing around with the GRUB command line for me, it might be easier for others. You want to start by running
Then, if your UEFI is configured correctly, running
net_ls_cars
should give a network card (for me, it was calledefinet0
). This card then need to be configured to be able to talk to your server. In theory, simply runningnet_bootp
(which sends a DHCP-request and configures the network accordingly) should work. It didn't for me, though, so I worked around it by usingnet_add_addr efinet0:link efinet0 <localIP>
do give the card some local IP address (probably192.168.0/1.something
). Apparently this works even if your router actually wants you to use DHCP (the PC isn't going to talk to the router anyway, so it doesn't matter), as long as the IP address you set is not occupied already. In my case I was able to just set a fixed local IP address for my PC, which solved the problem.If your server does not have a fixed IP address, you need to refer to it by its host name, so that you will also need to add a DNS server with
net_add_dns
. The GRUB documentation contains a list of all the commands. The descriptions are quite brief, however, so you might need to refer to the source code if you run into difficulties.Then, you can test whether you're able to read files from your server with
cat (tftp,<server>)/grub_conf
.If you've figured out how to configure networking with grub, you can add this to the grub config in
/etc/grub.d/40-custom.conf
. In my case, it looked like this:(with my PC and server being bound to
192.168.1.40
and192.168.1.41
respectively). Then usesudo update-grub
to update yourgrub.cfg
.Luckily,
source
doesn't do anything if the file access fails, so you don't need any error handling to check if your server is available.The configuration ends here, these two files should be all that you need to have the server tell the PC when and what to boot. You might need some extra configuration to be able to wake the PC from anywhere - to provide some inspiration I am going to share my personal configuration:
443
(using sslh). I use noip to give the server a universally accessible URL.