Это лишь частичный ответ, и я обязательно предлагаю другой ответ, который может быть более исчерпывающим и ясным.
Содержание этого ответа взято из файла kernel / reboot.c
ядра Linux 3.13 (что может быть не первым предположением, так как имя не shutdown.c, а reboot.c)
В любом случае у нас есть в основном три функции, которые набрасывают процесс выключения системы
void kernel_halt (void)
// который завершается остановкой системы void kernel_power_off (void)
// что завершается отключением системы void kernel_restart (char * cmd)
// что завершает работу системы, но перезапускает ее Эти функции очень краткие и поэтому могут быть вставлены сюда полностью. Их код лучше всего показывает, какие шаги предпринимаются для завершения работы ядра. (комментарии принадлежат мне и могут быть не на 100% идеальными и правильными, убедитесь в этом сами. Это просто попытка.
void kernel_halt (void)
void kernel_halt(void) { // 1st step does: // a) call functions/callback registered to run at reboot/shutdown // b) set system_sate to SYSTEM_HALT // c) stop the userspacetool interaction // d) call device_shutdown() function kernel_shutdown_prepare(SYSTEM_HALT); // 2nd step: I think this is mostly a necessity for multi-cpu systems migrate_to_reboot_cpu(); // 3rd step: // syscore_shutdown - Execute all the registered system core shutdown callbacks syscore_shutdown(); // 4th messages pr_emerg("System halted\n"); kmsg_dump(KMSG_DUMP_HALT); // 5th call arch specific cpu-halt-code machine_halt(); }
все это инициируется с помощью sys_reboot
системный вызов, который, учитывая, что он не только перезагружается, но и завершает работу, в любом случае не является прямым средством связи с процессом завершения работы.
Основные ресурсы для понимания того, как работает ядро Linux:
В этом случае я не могу найти что-либо актуальное в документации или на LWN, так что это LXR.
Последнее, что делает код пользовательского пространства, это вызывает системный вызов reboot
. Требуется 4 аргумента, поэтому ищите SYSCALL_DEFINE4 (перезагрузка
на LXR, что приводит к kernel / reboot.c
.После проверки прав и аргументов вызывающего абонента точка входа системного вызова вызывает одну из нескольких функций: kernel_restart
для перезагрузки, kernel_halt
для остановки в замкнутом цикле, kernel_poweroff
чтобы выключить систему, с kernel_kexec
по замените ядро новым (если оно скомпилировано) или спящий режим
, чтобы сохранить память на диск перед выключением .
kernel_restart
, kernel_halt
и
kernel_power_off
довольно похожи:
reboot_notifier_list
, который представляет собой список ловушки, которые компоненты ядра могут зарегистрировать для выполнения кода при выключении питания. На этом этапе только несколько драйверов должны выполнять код, в основном это сторожевые таймеры. system_state
. device_shutdown
, чтобы разблокировать или выключить все устройства в системе. Многие водители подключаются к этому этапу. migrate_to_reboot_cpu
заботится о переключении на один конкретный ЦП и предотвращении отправки кода планировщиком на другие ЦП. После этого работает только один ЦП. syscore_shutdown
вызывает метод shutdown
для зарегистрированных операций системного ядра . Я думаю, что в основном речь идет об отключении прерываний; несколько хуков имеют метод выключения
. machine_restart
, machine_halt
или machine_power_off
. Код гибернации проходит через следующие этапы:
kernel_restart
, kernel_halt
или kernel_power_off
, либо какой-либо метод гибернации для конкретной платформы. Другой способ выключить систему - machine_emergency_restart
. Это вызывается волшебным ключом SysRq B . Клавиша O работает иначе: вызывает kernel_power_off
.
Система также может отключиться из-за паники , то есть неисправимой ошибки. Паника пытается зарегистрировать сообщение, а затем перезагрузить систему (либо через аппаратный сторожевой таймер, либо через экстренный перезапуск).