Ubuntu 用户经常需要快速重启,例如内核更新后或者测试某些需要重启的设置时。
我想要一种方法(例如脚本)让我能够尽可能节省执行重新启动的时间。
在用户会话准备就绪之前,可以避免这些事情以减少重新启动时间:
- 如果可能,跳过 BIOS/UEFI/固件初始化和 POST
- 跳过 GRUB 菜单(预先选择所需条目一次并直接启动,无任何超时)
- 跳过登录屏幕(使用无密码自动登录一次)
也许还有更多的事情可以跳过,以便快速重启。
我已经看到了快速重启Ubuntu Wiki 中的规范,但该页面最后编辑于 2010-02-03。
但即使我们可能还不能正确使用上述内容kexec
跳过固件初始化等,临时预选 GRUB 条目并使用自动登录进行一次重启应该是可能的。我该如何设置?
我在具有 UEFI 的 Acer Aspire E5-773G 机器上使用 Ubuntu 16.04,64 位,带有 Unity DE、lightdm 和 GRUB,与 Windows 10(以及即将推出的更多 Linux 发行版)双启动。
答案1
重启时间
在这个“过于忙碌”的世界里,我们有时会推迟重启,不想浪费 5 秒或 15 秒。当我第一次看到这个问题时,我的启动时间已经从 45 秒缩短到 14 秒,这得益于 SSD 和systemd
调整。
最近我买了一台“现代”笔记本电脑,它配备了 NVMe M.2 Gen 3.0 x 4 SSD,Windows 读取速度高达 3.4 GB/s,Linux 读取速度高达 2 GB/s。所以它应该更快吧?嗯……不。它慢得令人难以忍受:
$ systemd-analyze
Startup finished in 6.823s (firmware) + 4.447s (loader) + 3.467s (kernel) + 8.412s (userspace) = 23.151s
这次其实后调整。80 秒后情况变得更糟,因为 nVidia 和戴尔选择切断驱动 HDMI 端口的 nVidia GTX970M 显卡上的 HDMI 音频电源。因此setpci
需要一条命令,这会导致出现“低图形错误”消息,并且您必须等待 20 秒才能让鼠标指针继续。然后它会重新加载所有图形驱动程序并重新启动 lightdm。
“现代”笔记本电脑的另一个问题是 BIOS POST 需要 15 秒。在 BIOS 中调整以关闭硬件错误检查、关闭加载 NIC 的启动驱动程序和其他我不记得的调整,将 BIOS POST 时间更改为 6 秒。相比之下,“旧”笔记本电脑 BIOS POST 时间只有几秒钟,使用传统 BIOS CSM 并且没有 BIOS 调整。
Ubuntu RapidReboot
2010 年的项目
Ubuntu快速重启ByteCommander 的帖子中提到的项目来自 2010 年。该项目的基本原理总结如下:
基本原理
在某些情况下,我们可以放心地假设用户不想看到引导加载程序;在这些情况下,我们应该使用 kexec 来避免长时间的重新启动、BIOS POST 和引导加载程序时间。在最佳情况下,这可能需要 10 秒;但对于 SCSI 或 RAID BIOS 和网络引导 ROM,时间可能会增加到 20、30 甚至 60 秒以上,即使在加载内核和看到登录屏幕之间的时间为 30-60 秒的情况下也是如此。
项目的使用示例:
用例
- Bob 刚刚升级了他的内核;更新通知程序通知他必须重新启动才能使更改生效,并且“重新启动”按钮使用 kexec 来加快此速度。
- Alice 刚刚升级了 dbus;update-notifier 告诉她重新启动,并使用 kexec。
- Seveas 在过去一个月内进行了多次更新,由于不同的程序使用不同的共享库副本,现在的内存压力是原来的三倍。他决定重启以解决此问题,并使用“快速重启”来加快速度。
- Keybuk 刚刚安装了 Ubuntu Edgy 并想要启动它。LiveCD 使用 kexec 加载目标内核和 initrd;卸载所有基于磁盘的文件系统;同步;然后使用 kexec 启动新系统,而不是重新启动。
使用 kexec 重新启动
kexec
是我们施展的魔法,无需 BIOS POST 和一些其他低级发现机制(例如 RAID 设置)即可重启。
内核必须使用CONFIG_KEXEC
标志进行编译
第一步是确保您的内核是使用以下CONFIG_KEXEC=y
选项编译的:
$ uname -r
4.14.2-041402-generic
$ grep KEXEC= /boot/config-`uname -r`
CONFIG_KEXEC=y
第一个命令uname -r
是可选的,仅用于显示您启动的内核。正如我们在第二个命令中看到的,内核是由 Ubuntu 团队编译的,并设置了必要的标志。不确定这是什么时候添加的,但可能是在 2012 年之前。
安装kexec-tools
下一步是安装kexec
用户空间的工具:
$sudo apt install kexec-tools
正常二进制下载后,您将看到以下屏幕:
我之所以回答No
这个问题,部分原因是这个错误报告指出该选项与无关systemd
。
然后安装继续(如下所示的代码片段):
Unpacking kexec-tools (1:2.0.10-1ubuntu2.4) ...
Processing triggers for man-db (2.7.5-1) ...
Processing triggers for systemd (229-4ubuntu21) ...
Setting up kexec-tools (1:2.0.10-1ubuntu2.4) ...
Generating /etc/default/kexec...
Generating grub configuration file ...
(... CUT ...)
Found Windows Boot Manager on /dev/nvme0n1p2@/EFI/Microsoft/Boot/bootmgfw.efi
Found Windows Boot Manager on /dev/sda1@/efi/Microsoft/Boot/bootmgfw.efi
Adding boot menu entry for EFI firmware configuration
done
Processing triggers for systemd (229-4ubuntu21) ...
配置kexec
ArchLinux 的同事们出色的 kexec 文档但它需要针对 Ubuntu / Debian 发行版进行调整。
基本用法是两个命令:
sudo kexec -l /boot/vmlinuz-`uname -r` --initrd=/boot/initrd.img-`uname -r` --reuse-cmdline
sudo kexec -e
从此时起,每次您单击重新启动时,它都会在快速重启模式下自动重新加载最后一个内核。
使用 Systemd 加载 kexec
创建文件:/etc/systemd/system/[email protected]
[Unit]
Description=load %i kernel into the current kernel
Documentation=man:kexec(8)
DefaultDependencies=no
Before=shutdown.target umount.target final.target
[Service]
Type=oneshot
ExecStart=/usr/bin/kexec -l /boot/vmlinuz-%i --initrd=/boot/initrd.img-%i --reuse-cmdline
[Install]
WantedBy=kexec.target
然后启用您想要加载的内核的服务文件,例如简单地设置当前内核uname -r
:
$ sudo systemctl enable kexec-load@`uname -r`
Created symlink from /etc/systemd/system/kexec.target.wants/[email protected] to /etc/systemd/system/[email protected].
然后到 kexec:
$ sudo systemctl kexec
如果您正在youtube
运行,则可能存在系统抑制器阻止您重新启动,在这种情况下请使用:
$ sudo systemctl kexec -i
如果您希望为下一个 kexec 加载不同的内核,例如 4.12.2-041202-generic,请禁用当前内核的服务并启用新内核的服务:
$ sudo systemctl disable kexec-load@`uname -r`
$ sudo systemctl enable [email protected]
更多精彩
我现在必须发布这个答案,因为是时候启动、修复、启动、修复、重复了。我有一个复杂的设置,其中systemd
加载了五个nVidia
驱动程序,我必须卸载它们,运行setpci
以打开音频到 HDMI,重新加载 nVidia 驱动程序并重新启动 lightdm。这可能需要一段时间才能解决。
使这些cli
方法奏效后,我将创建一个桌面快捷方式,用于一键重启并sudo
输入密码。之后,我将创建一个桌面快捷方式,指向一个yad
对话框,允许您从已安装的内核中进行选择以进行重启。类似于 grub 的高级选项菜单。
答案2
为了极快地重启 Linux 机器,请调用重启内核函数。它将刷新磁盘(至少在内核版本 3.x 中)并立即重启。中间没有任何操作,没有操作系统函数、脚本等……只有内核调用。
如何?
创建reboot.c,内容如下:
#include <stdio.h>
#include <sys/reboot.h>
int
main (int argc, char **argv)
{
if (reboot (RB_AUTOBOOT) < 0) {
fprintf (stderr, "%s: call to reboot() system call failed.\n",
argv[0]);
}
return 0;
}
将reboot.c编译成reboot:
gcc reboot.c -o reboot
执行重启(它会将数据刷新到磁盘并重启,就是这样!):
./reboot
祝您重启顺利!
答案3
如果你想部分重启你的计算机(并且不加快启动速度),以下是我的理解:Linux 启动主要分为 3 个部分:
- 步骤1:计算机启动直至启动管理器/操作系统选择(rEFInd、Grub……)
- 第2步:启动Linux和主要服务
- 步骤3:开始会话
- 用户登录
- 窗口管理器,如 Cinnamon、KDE、Gnome 等)
仅重新启动步骤 3:
- 类型Alt-F2和R
- 或者sudo 服务 $(cat /etc/X11/default-display-manager) 重新启动
仅重新启动步骤 2 和 3:
我不知道如何从启动管理器重启 Linux
重新开始所有步骤
- 在主菜单中,选择“重新开始“
- 在命令行中输入sudo 重启