在内核日志记录开始之前调试 grub 中的启动性能问题

在内核日志记录开始之前调试 grub 中的启动性能问题

我的电脑需要很长时间才能启动。我有理由相信这是由 grub 之后、内核日志记录开始之前的延迟引起的(启动需要 30 秒,但dmesg消息的时间戳介于0.00000-之间9.34223,详细信息见这个帖子)。

有什么方法可以调试正在发生的事情吗?尤其:

  • 有没有办法让 grub 本身变得更加详细,或者保留日志?
  • grub 和内核日志记录之间是否还有其他可能需要时间的进程?我该如何调试这些?

我相信这个问题并不特定于我的设置。但以防万一,我正在运行 Ubuntu 16.10 和 grub(2)

编辑:

根据 @TooTea 的建议,我设置了debug=all环境变量,它产生了很多消息,这script/script.c:50 malloc 0x7a9a2ca0应该不是问题。然后有一组消息与 8 秒延迟延迟一致:

kern/dl.c:56 Detecting ext2... 
lib/relocator.c:1397 chunks = 0x7a7e0ae0
lib/relocator.c:434 trying to allocate in ...-... aligned ... size ...
lib/relocator.c:1198 allocated: ...+...
lib/relocator.c:1409 allocated .../...
lib/relocator.c:1410  chunks = 0x7a7e0ae0

答案1

这当然不是我自己问题的完整答案,但可能对其在调查类似问题时登陆此处的其他人有用。

GRUB 手册建议使用debug环境变量,或者debug=all带有设施名称的逗号/空格列表。然后它说:

有关更多详细信息,请参阅来源。

我无法在网上找到潜在名单。因此,为了将来参考,我从当前的 github 存储库 coreos/grub 中提取了这些名称的列表,希望这对我和其他人将来有用。当然,如果不进一步调查来源,这的用途是有限的,但仍然可能是一个很好的起点。

name                frequency in source
acpi                |||||
affs                |
ahci                ||
appleload           |
arcdisk             ||
archelp             ||
ata                 ||
atkeyb              ||
biosdisk            ||
bsd                 ||||
btrfs               ||
cache               ||
cbfs                |
chain               |||
crypt               ||
cryptodisk          ||
datetime            |
devalias            ||
disk                |||||
diskfilter          ||
dl                  ||||||||
dns                 ||
drivemap            ||
efi                 ||
efidisk             ||
efiemu              ||||||||||||||
ehci                ||
elf                 ||
exfat               |
expand              ||
fat                 |
fb                  ||
fdt                 |
fixvideo            ||
font                ||
fs                  ||
geli                ||
gpt                 ||||
hostdisk            |||||
init                |||||
jpeg                |
keystatus           ||
lexer               |
linux               |||||||||||||
loader              |||||||
luks                ||
memdisk             ||
mm                  ||
mmap                |||||
modules             ||
multiboot_loader    |||||
nativedisk          ||
net                 ||||||||||
ohci                ||
partition           ||||||
pata                ||
play                ||
reiserfs_tree       ||
relocator           |||
scripting           ||
scsi                ||
serial              ||
smbios              ||
syslinux            ||
tftp                ||
tga                 ||
ubootdisk           ||
uhci                ||
usb                 ||||||
usb_keyboard        ||
usbms               ||
video               |||||||
xen                 |||||||||
xen_loader          ||
xfs                 ||
xnu                 ||||||
zfs                 |||||

例如你可以写

set debug=linux,video,fs

进入您的/boot/grub/grub.cfg以减少 GRUB 的调试冗余并仅显示这些设施的调试消息

答案2

正如您可能想象的那样,GRUB 和 Linux 之间的切换涉及一些非常复杂的低级步骤,因此没有空间进行高级跟踪或日志记录。幸运的是,这应该不是问题,因为该代码中也没有空间容纳任何扩展停顿。您可以通过设置 GRUB 中的所有准备步骤来获得非常详细的跟踪debug环境变量

然而,更有可能的是,无论您看到什么延迟,都是在控制权转移到 Linux 内核之后发生的。通常,在控制台初始化之前您看不到日志消息。另外,正如您所指出的,在计时子系统初始化之前,所有时间戳均为零,因此稍后无法计算出计时。

幸运的是,您可以使用earlyprintk引导选项使内核实际上在某处打印日志消息,以便您可以实时跟踪它们并查看延迟发生在哪里。earlyprintk可以定向到不同的目的地,但与通常(物理)机器最相关的是serialvga(老式控制台)或efi。确保您的内核是使用适当的配置选项构建的 ( CONFIG_EARLY_PRINTK*)。

相关内容