当Linux系统休眠并从休眠状态恢复时,我认为内核需要知道它正在恢复,而不是引导。否则,内核将启动通常的引导过程,并且不会加载交换的数据。内核如何知道它正在恢复?
起初,我以为GRUB(或另一个引导加载程序)通过内核参数告诉内核。但只要我检查/proc/cmdline,内核参数就和平常一样了。是否有任何机制让内核知道它正在恢复?
答案1
休眠通过使用交换分区来交换所有进程的内存、内核状态,最后保存 CPU 和可能的其他设备的某些状态,然后关闭电源。途中,它在交换分区中指出这是一个休眠映像。
从休眠状态恢复的工作原理是告诉内核尝试resume=
使用内核参数从交换分区恢复resume=/dev/sda4
(如果 /dev/sda4 是您的交换分区)resume=UUID=deadbeef-cafe-b00b-1337-123456123456
或类似的。
然后,内核在启动期间查看该分区,在交换分区中找到“嘿,这是休眠映像”的注释,并从中恢复设备、内核和进程。如果注释不存在,则它会正常启动。
你可以检查源代码,具体功能描述software_resume()
:
* software_resume - Resume from a saved hibernation image.
*
* This routine is called as a late initcall, when all devices have been
* discovered and initialized already.
*
* The image reading code is called to see if there is a hibernation image
* available for reading. If that is the case, devices are quiesced and the
* contents of memory is restored from the saved image.
因此,这涉及内核的两个实例,“启动内核”和“映像内核”,并且该过程在官方内核文档这也解释了为什么这不是通过引导加载程序完成的:
虽然原则上可以将映像加载到内存中并由引导加载程序恢复休眠前内存内容,但实际上这是不可能完成的,因为引导加载程序不够智能并且没有建立协议来传递必要的信息。因此,引导加载程序将一个新的内核实例(称为“恢复内核”)加载到内存中,并以通常的方式将控制权传递给它。然后恢复内核读取系统映像,恢复休眠前的内存内容,并将控制权交给映像内核。因此,从休眠状态恢复涉及两个不同的内核实例。
如今,也可以是许多(大多数?)文件系统上的交换文件,或者 LVM 卷……。