By Falcon of TinyLab.org
May 14, 2019
注:泰晓科技新增 Debugging+Tracing 专辑,全面连载各类 debug 实战技能。本文是该专辑的第一篇,欢迎持续关注。通过该专辑,您可以学习到分析和解决实际问题的方式、方法、工具和技巧。
背景介绍
前段时间为 Linux Lab 新增了 5.0.10 for ARM64/virt board,期间遇到了启动死机问题,本文对该问题进行详解。
在继续阅读之前,建议准备好 Linux Lab,方便同时做实验。为复现该问题,请先注释掉 boards/virt/Makefile 中的 QEMU 所在行,或者键入如下命令确保使用旧版本的 qemu。
$ export QEMU=
问题现象
编译完 Linux 5.0.10 并通过 Linux Lab 运行时:
$ make BOARD=virt
$ make boot V=1
直接卡死了,只看到 Qemu 的输出日志,没有看到任何内核日志输出 ;-(
分析过程
理清问题基本信息
首先需要承认,面对这种不按套路出牌的 Linux 启动状况(不确定性),这个时候谁都可能“惶恐不安”。接着告诉自己,问题必须解决,冷静!
有两个信息先捋一下:之前的 Linux v4.5.5 ok,启动完美
网上已经有同学完美启动了 5.0 for ARM64
所以,问题可能原因:Linux v5.0.10 相比 v4.5.5 有变更引入了衰退
Linux Lab 所使用的环境跟网上其他同学的环境有差异,可能差异在编译器和 Qemu。
接下来有两个思路:用二分法找出引入问题的变更,即从 v4.5.5 到 v5.0.10 之间找出第一个启动不了的内核版本
升级 Linux Lab 中的编译器和 Qemu 到最新版本
可是,虽然这两个工作都可行,但还都蛮耗费时间(第2个相对而言没那么耗时),所以,不能逃避,正面扛着看看!
定下分析方式
ok,先保持内核版本不变、环境不变,正面分析到底 Linux 内核卡死在哪里?!
打开 early Logging 机制
竟然内核什么都没有输出,那么先想办法输出点东西。
死得这么早,可能是普通串口初始化之前就挂了,要在这之前就打印东西,能想到是 early printk:
$ make boot V=1 XKCLI="earlycon"
earlycon 是内核最新的 early printk 逻辑,说明文档在 linux-stable/Documentation/admin-guide/kernel-parameters.txt:
earlycon= [KNL] Output early console device and options.
[ARM64] The early console is determined by the stdout-path property in device tree's chosen node, or determined by the ACPI SPCR table.
[X86] When used with no options the early console is determined by the ACPI SPCR table.
加上以后,很幸运,有东西咕噜咕噜滚出来了:
$ mak