如果使用 GRUB 通过 LAN 唤醒启动,则启动不同的操作系统

Pas*_*cal 2 grub2

我有一台运行 Windows 和 Linux 的 PC。我希望Windows系统成为默认系统,因为这台PC主要用于游戏。

但是,我偶尔会将它用作我的远程开发箱。我已经为它启用了 WOL,所以只要我在路上尝试访问它,它就会启动。

当计算机通过 WOL 启动时,是否可以以某种方式告诉 GRUB2 启动到 Linux,否则启动到 Windows?

arc*_*t30 5

我最近找到了适用于我的用例的此问题的解决方案。虽然这个问题比较老了,我还是把它贴在这里供参考:

该方法需要 (root) 访问目标 PC 以外的某些设备,这些设备应该可以从 PC 的网络内访问 - 例如树莓派或有根的 android 手机。它还需要使用 UEFI 启动。这个想法是让该设备唤醒 PC,同时充当 TFTP 服务器(参见此处的指南),它提供一个配置文件,告诉 GRUB 通过设置default变量来引导什么。因此,您需要:

  • 在 TFTP 服务器上,表单的脚本

    #!/bin/bash
    echo 'default <boot-target>' > /srv/tftp/grub_conf
    wol <PC MAC>
    sleep 15     # wait for GRUB to boot
    echo > /srv/tftp/grub_conf
    
    Run Code Online (Sandbox Code Playgroud)

    (当然,只是休眠 15 秒有点麻烦,如果同时启动脚本的多个实例,可能会中断,尤其是当它包含多个引导目标选项时。稍微干净的解决方案是只清除文件,如果它不是在 15 秒内没有改变。可能最好的解决方案是使用服务器hooktftp,这将允许在 grub 访问文件时注意到并在之后立即清除它。但是,我还没有时间对此进行测试。我会一旦我确定这有效,就编辑帖子。)

    这将是启动 PC 的脚本。它可以很容易地扩展到允许多个引导选项的选择,然后可以通过命令行参数进行选择。

  • 配置您的 UEFI BIOS 以在启动期间初始化网络堆栈(请注意,这可能需要多个不同的 BIOS 选项才能可靠地工作)

  • 找出如何告诉 GRUB 如何与您的服务器通信。这对我来说需要一些 GRUB 命令行,对其他人来说可能更容易。你想从跑步开始

    insmod net
    insmod efinet
    insmod tftp
    
    Run Code Online (Sandbox Code Playgroud)

    然后,如果你的 UEFI 配置正确,运行net_ls_cars应该会给出一个网卡(对我来说,它被称为efinet0)。然后需要将此卡配置为能够与您的服务器通信。理论上,简单地运行net_bootp(发送 DHCP 请求并相应地配置网络)应该可以工作。不过,它不适合我,所以我通过使用net_add_addr efinet0:link efinet0 <localIP>do 给卡一些本地 IP 地址(可能192.168.0/1.something)来解决它。显然,即使您的路由器实际上希望您使用 DHCP(PC 无论如何都不会与路由器通信,所以没关系),只要您设置的 IP 地址未被占用,这也可以工作。就我而言,我能够为我的 PC 设置一个固定的本地 IP 地址,这解决了问题。

    如果您的服务器没有固定的 IP 地址,则需要通过其主机名来引用它,因此您还需要添加带有net_add_dns. 在GRUB文档中包含的所有命令的列表。但是,这些描述非常简短,因此如果遇到困难,您可能需要参考源代码。

  • 然后,您可以测试是否可以使用cat (tftp,<server>)/grub_conf.

  • 如果您已经弄清楚如何使用 grub 配置网络,您可以将其添加到 .grub 中的 grub 配置中/etc/grub.d/40-custom.conf。就我而言,它看起来像这样:

    insmod net
    insmod efinet
    insmod tftp
    net_add_addr efinet0:link efinet0 192.168.1.40
    source (tftp,192.168.1.41)/grub_conf
    
    Run Code Online (Sandbox Code Playgroud)

    (我的 PC 和服务器分别绑定到192.168.1.40192.168.1.41)。然后用于sudo update-grub更新您的grub.cfg.

    幸运的是,source如果文件访问失败,则不会执行任何操作,因此您不需要任何错误处理来检查您的服务器是否可用。

配置到此结束,这两个文件应该是您让服务器告诉 PC 何时启动以及启动什么所需的全部文件。您可能需要一些额外的配置才能从任何地方唤醒 PC - 为了提供一些灵感,我将分享我的个人配置:

  • 我的 TFTP 服务器是一个 raspberry pi,它也被配置为一个 web 服务器并且可以通过 ssh 访问,全部通过端口443(使用sslh)。我使用noip为服务器提供一个可普遍访问的 URL。
  • Web服务器上的一个页面提供了一个Web界面,用于通过http请求唤醒PC(即Web服务器上的PHP脚本侦听请求并相应地启动上述bash脚本)。吨
  • 我使用 Android 应用程序Automate来获取发送 HTTP 请求的主屏幕快捷方式(这就是我使用 HTTP 的全部原因 - AFAIK Automate 不知道 ssh)。
  • 最终结果是我在主屏幕上有两个快捷方式,分别用于启动 Linux 和 Windows。如果我想远程关闭 PC,我可以通过 ssh 进入我的树莓派(例如使用Termux并从那里访问 PC。通过一些配置,您还可以远程关闭运行 Windows 的 PC)