您的位置:首页 >如何通过dmesg日志优化启动速度
发布于2026-05-02 阅读(0)
扫一扫,手机访问

想找到启动慢的“元凶”,第一步得把证据链抓全。最直接的方法,就是抓取带时间戳的内核日志。建议优先使用可读时间格式,执行 dmesg -T > boot.txt。拿到日志后,怎么找关键点呢?通常,可以搜索“Freeing unused kernel memory”这行,把它当作“内核初始化完成”的参考终点。然后,从这个终点向前回溯,仔细看看哪些地方出现了明显的时间断层,或者哪个区段耗时特别长。
当然,光看大概还不够,得量化。在内核启动参数里加上 printk.time=1 和 initcall_debug,就能让日志打印出每个初始化函数(initcall)的开始、结束以及具体耗时。这样一来,排序定位最慢的初始化项就方便多了。如果担心日志被截断或者可读性不佳,别忘了在内核配置中开启 CONFIG_PRINTK_TIME、CONFIG_KALLSYMS,必要时还得增大 CONFIG_LOG_BUF_SHIFT 的缓冲区大小。
话说回来,对于喜欢直观分析的朋友,还有个更高效的工具:图形化。将 dmesg 的输出通过内核源码自带的 scripts/bootgraph.pl 脚本处理,就能生成一个 kernel.svg 矢量图。这张图能一目了然地展示各个 initcall 的耗时占比和串行瓶颈,哪里是“拖油瓶”一看便知。
定位到问题后,接下来就是对症下药。以下是几个最常见的瓶颈及其优化思路:
控制台输出过慢:大量信息往串口“吐”,本身就会成为瓶颈。在产品发布阶段,完全可以使用内核参数 quiet 来大幅降低控制台输出量。别担心会丢失日志,事后用 dmesg 命令一样能读出来。不过得提醒一句,在调试阶段可别过早用上 quiet,不然关键的错误线索可能就看不到了。
驱动探测与 initcall 串行:这就是为什么前面要打开 initcall_debug,它能帮你精确“揪出”耗时最长的初始化函数。优化策略很直接:对于那些可以模块化的功能,果断改为模块,按需加载;对于那些必须内置的驱动,则可以在其探测逻辑中合理使用 -EPROBE_DEFER 机制,推迟非关键设备的初始化。这样一来,就能减少第一轮初始化的阻塞时间,有效缩短串行阶段的总时长。
文件系统挂载与检查:如果在 dmesg 里看到两个挂载点之间出现了明显的“时间断层”,那多半是 fsck 文件系统检查或者 f2fs resize 这类耗时操作在作祟。一个有效的思路是,把这些任务改为异步执行,或者干脆按需执行,避免它们阻塞主线程。另外,如果你调整过分区或UUID,务必记得同步更新 initramfs 中的 resume/swap 配置并重建,否则系统可能会因为寻找旧分区而陷入长时间的等待。
延迟循环校准(lpj):这是内核启动早期的一个固定动作——校准延迟循环(BogoMIPS/lpj)。在日志里找到形如“lpj=xxxxxxx”的行,把这个值直接作为内核参数 lpj=xxxxxxx 预设进去,就能跳过校准过程。别小看这个操作,根据平台不同,它能帮你省下几百毫秒到数秒不等的时间,算是个“低垂的果实”。
理论说完了,具体怎么干?可以遵循下面这个从分析到验证的闭环流程:
dmesg -T > boot.txt;在日志中定位“Freeing unused kernel memory”作为分析终点锚点。printk.time=1 与 initcall_debug,重新启动并测试一次,以获取每个 initcall 的详细耗时分布。scripts/bootgraph.pl 生成 kernel.svg,直观识别最耗时的 initcall 与长串行段落。lpj= 预设参数中。为了方便查阅,这里把文中提到的关键命令整理如下:
dmesg -T > boot.txtprintk.time=1 initcall_debugcat boot.log | perl scripts/bootgraph.pl > kernel.svgcat /proc/uptime(其首字段即为系统运行时间)echo 1 4 1 7 > /proc/sys/kernel/printk(可降低输出量以提速,但调试阶段不建议使用)update-initramfs -u(适用于 Debian 系发行版)上一篇:怎样用dmesg日志监控磁盘健康
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9