ARM64 기반 리눅스 시스템을 종료할 때 어떤 작업이 진행되는지 알아보던 중 커널 코드를 확인한 기억이 나는데.. 나중에 다시 확인하기 위해 문서로 남겨둔다.
구현된 기능중 일부 내용 기록
자세한 내용은 리눅스 커널의kernel/reboot.c
코드 참조
void kernel_restart(char *cmd)
{
kernel_restart_prepare(cmd)
migrate_to_reboot_cpu();
syscore_shutdown();
if (!cmd)
pr_emerg("Restarting system\n");
else
pr_emerg("Restarting system with command '%s'\n", cmd)
kmsg_dump(KMSG_DUMP_RESTART);
machine_restart(cmd);
}
EXPORT_SYMBOL_GPL(kernel_restart);
void kernel_power_off(void)
{
kernel_shutdown_prepare(SYSTEM_POWER_OFF);
if (pm_power_off_prepare)
pm_power_off_prepare();
migrate_to_reboot_cpu();
syscore_shutdown();
pr_emert("Power down\n");
kmsg_dump(KMSG_DUMP_POWEROFF);
machine_power_off();
}
EXPORT_SYMBOL_GPL(kernel_power_off)
kernel_power_off
와 약간 다른 부분 빼면 시퀀스는 같음.
void kernel_halt(void)
{
//kernel_shutdown_prepare(SYSTEM_POWER_OFF);
kernel_shutdown_prepare(SYSTEM_HALT);
//if (pm_power_off_prepare)
// pm_power_off_prepare();
migrate_to_reboot_cpu();
syscore_shutdown();
pr_emert("Power down\n");
kmsg_dump(KMSG_DUMP_POWEROFF);
machine_halt();
}
EXPORT_SYMBOL_GPL(kernel_halt);
Linux Kernel의 arch
디렉터리를 보면 각 하드웨어(아키텍처)에 의존적인 코드가 들어있음.
kernel/reboot.c
에서 사용하는 아키텍처 의존적인 일부 함수가 어떻게 작동하는지 알아보기 위해 코드를 열어보고 필요한 부분만 기록.
void machine_restart(char *cmd)
{
/*
* 인터럽트 해제 먼저 진행
*/
local_irq_disable()
smp_send_stop();
do kernel_i2c_restart(cmd);
/*
* ResetSystem()을 통해 재설정되는 시스템에 따라
* UpdateCapsule()가 다름.
*/
if (efi_enabled(EFI_RUNTIME_SERVICES))
efi_reboot(reboot_mode, NULL);
/*
* 아키텍처 전용 재부팅 코드를 불러옵니다.
*/
if (arm_pm_restart)
arm_pm_restart(reboot_mode, cmd);
else
do_kernel_restart(cmd);
/*
* 재부팅에 실패한 경우
*/
printk("Reboot failed -- System halted\n");
while (1);
}
smp_send_stop()은 Power OFF를 위해 보조 CPU가 기존에 수행중인 것들을 중단시킴
void machine_power_off(void)
{
local_irq_disable();
smp_send_stop();
if(pm_power_off)
pm_power_off();
}
작업을 모두 중단하지만 전원을 내리는 코드는 없음.
void machine_halt(void)
{
local_irq_disable();
smp_send_stop();
while (1);
}