在Linux系统中,Suspend-Resume是一个复杂的过程,其涉及到BIOS、Kernel、Graphic驱动以及相关的应用程序。本文将介绍如何调试Suspend-Resume相关Bug,如何缩小引起Suspend-Resume失败的范围。
在此之前,我们必须Kill所有使用/proc/acpi/event的进程,例如:gnome-power-manager。
1. 运行:lsof /proc/acpi/event;
2. Kill以上列出的进程;
需要注意一点:
1. 分别在Console模式(Level 3)和X模式(Level 5)执行Suspend/Resume。如果只在X模式测试失败,说明该BUG是与X相关的,那么我们就检查DDX驱动,XServer或者其他与Suspend-Resume相关的应用程序,例如:pm-suspend等等。如果在两种模式下,测试都是失败的,那我们调试的重点放到Console模式;
2. 在Suspend之前和Resume之后分别执行:dmesg;
3. 为了缩小范围,我们可以尝试删除一些内核模块。比如:如果删除了Intel的i915驱动,系统能够正常Suspend/Resume,那么,我们有理由怀疑i915驱动是该BUG的罪魁祸首;
S3 Suspend (Suspendto RAM):
检查Resume Hang是否由Graphic驱动导致的
1. 运行:dmesg > dmesg_before; echo mem > /sys/power/state; dmesg >dmesg_after
2. 按电源键,观察系统是否可以正常Resume;
3. 如果无法正常Resume,那么重启系统,检查文件dmesg_after;
4. 如果文件dmesg_after存在,说系统可以正常从BIOS中Resume回来,那么该BUG很有可能是由Graphics导致的;否则,该BUG就和Graphics不相关,需要从BIOS角度去查找原因;
在Suspend/Resume的时候,忽略BIOS
1. 在Kernel的配置文件中,将“CONFIG_PM_DEBUG”给enable,这样我们就可以使用/sys/power/pm_test;
2. 运行:echo core/processors/devices > /sys/power/pm_test;
3. 运行:dmesg > dmesg_before; echo mem > /sys/power/state; dmesg >dmesg_after;
4. 等待5秒,观察系统是否可以正常Resume;
5. 如果系统无法正常Resume, 那么该BUG很有可能是由Graphics导致的;
S4 hibernation(Suspend to Disk)
如果在kernel启动的时候,Resume失败了,那么我们试试在boot选项中增加“resume=/dev/xxxx”(xxxx表示swap分区);
检查该Bug是否在Console模式和X模式都是一样失败的:
1. 启动系统至Console模式(Level 3);
2. 运行:echo disk > /sys/power/state;
3. 按电源键,观察系统是否可以正常Resume;
4. 如果系统可以正常Resume,说明该BUG可能与Graphics驱动相关;
5. 如果系统无法正常Resume,说明该BUG可能与Linux Kernel相关;