ARM64 기반 리눅스 종료 시퀀스

d3fau1t·2021년 12월 5일
0

Embedded

목록 보기
4/6

ARM64 기반 리눅스 시스템을 종료할 때 어떤 작업이 진행되는지 알아보던 중 커널 코드를 확인한 기억이 나는데.. 나중에 다시 확인하기 위해 문서로 남겨둔다.

kernel/reboot.c

구현된 기능중 일부 내용 기록
자세한 내용은 리눅스 커널의 kernel/reboot.c 코드 참조

Restart

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);

OFF

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)

Halt

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);

arch/arm64/process.c

Linux Kernel의 arch디렉터리를 보면 각 하드웨어(아키텍처)에 의존적인 코드가 들어있음.

kernel/reboot.c에서 사용하는 아키텍처 의존적인 일부 함수가 어떻게 작동하는지 알아보기 위해 코드를 열어보고 필요한 부분만 기록.

Restart

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);
}

Power OFF

smp_send_stop()은 Power OFF를 위해 보조 CPU가 기존에 수행중인 것들을 중단시킴

void machine_power_off(void)
{
  local_irq_disable();
  smp_send_stop();
  if(pm_power_off)
    pm_power_off();
}

Machine Halt

작업을 모두 중단하지만 전원을 내리는 코드는 없음.

void machine_halt(void)
{
  local_irq_disable();
  smp_send_stop();
  while (1);
}
profile
웹 백엔드 합니다.

0개의 댓글

관련 채용 정보