![在内核日志记录开始之前调试 grub 中的启动性能问题](https://linux22.com/image/148822/%E5%9C%A8%E5%86%85%E6%A0%B8%E6%97%A5%E5%BF%97%E8%AE%B0%E5%BD%95%E5%BC%80%E5%A7%8B%E4%B9%8B%E5%89%8D%E8%B0%83%E8%AF%95%20grub%20%E4%B8%AD%E7%9A%84%E5%90%AF%E5%8A%A8%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98.png)
我的电脑需要很长时间才能启动。我有理由相信这是由 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
可以定向到不同的目的地,但与通常(物理)机器最相关的是serial
、vga
(老式控制台)或efi
。确保您的内核是使用适当的配置选项构建的 ( CONFIG_EARLY_PRINTK*
)。