2

I am not asking how to shut down. I am asking how to cut of the power.

What is the function in Linux kernel code do the action of cutting of the power? And please explain the code.

  • What are you trying to accomplish by cutting the power directly? – eyoung100 Oct 22 '14 at 16:08
  • @eyoung100 I wonder why and how the action of powering off can be done by software, rather than physical action (such as pressing the power button). – Victor Oct 22 '14 at 16:12
  • possible duplicate of Is there a fastest way to shutdown the system? – goldilocks Oct 22 '14 at 16:29
  • @goldilocks absolutely not the same, I am asking the principle of power driver or power interruption, rather than the operation of power off. – Victor Oct 22 '14 at 16:31
  • The operation of "power off" is the most software can accomplish, but I've removed my close vote since an answer involving kernel hacking would be appropriate here but not there. – goldilocks Oct 22 '14 at 16:36
3

The actual kernel code depends on the arch of your system. For x86 systems, they are located in arch/x86/kernel/reboot.c

Halt will stop the machine, and leave it in power-on state. So it just stops the kernel, but usually does not power it off.

static void native_machine_halt(void)
{
  /* Stop other cpus and apics */
  machine_shutdown();

  tboot_shutdown(TB_SHUTDOWN_HALT);

  stop_this_cpu(NULL);
}

While power_off will also cut off the electric source from APM / ACPI pm_power_off()

static void native_machine_power_off(void)
{
  if (pm_power_off) {
    if (!reboot_force)
      machine_shutdown();
    pm_power_off();
  }
  /* A fallback in case there is no PM info available */
  tboot_shutdown(TB_SHUTDOWN_HALT);
}

machine_shutdown() is an infinite loop

tboot_shutdown() (arch/x86/kernel/tboot.c)

stop_this_cpu(NULL) (arch/x86/kernel/process.c) disables the IRQs of the CPU, set the CPU offline,

pm_power_off() (arch/x86/kernel/apm_32.c) is a function pointer to apm_power_off()

As you can see, all the job depends on the arch. In all cases, it's done with ASM calls.

For apm_power_off(), the Bios is called with code APT_STATE_OFF (0x0003).

apm_bios_call_simple(APM_FUNC_SET_STATE, APM_DEVICE_ALL, APM_STATE_OFF, eax, err);

For native_halt() (arch/x86/include/asm/irqflags.h) this calls is used :

asm volatile("hlt": : :"memory");

Choose your poison :)

  • Choose my "poison"? Do you mean "position"? – Victor Oct 23 '14 at 0:38
-1

Traditionally Software can control the Power Level by passing commands to a Shell or Subshell. You must be nice to users when using this approach and give them time to respond properly. Depending on your init system, you pass the init system a level. Following is a Table of Levels

+-------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------+
| Sysvinit Runlevel |                    Systemd Target                     |                                            Notes                                             |
+-------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------+
| 0                 | runlevel0.target, poweroff.target                     | Halt the system.                                                                             |
| 1, s, single      | runlevel1.target, rescue.target                       | Single user mode.                                                                            |
| 2, 4              | runlevel2.target, runlevel4.target, multi-user.target | User-defined/Site-specific runlevels. By default, identical to 3.                            |
| 3                 | runlevel3.target, multi-user.target                   | Multi-user, non-graphical. Users can usually login via multiple consoles or via the network. |
| 5                 | runlevel5.target, graphical.target                    | Multi-user, graphical. Usually has all the services of runlevel 3 plus a graphical login.    |
| 6                 | runlevel6.target, reboot.target                       | Reboot                                                                                       |
| emergency         | emergency.target                                      | Emergency shell                                                                              |
+-------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------+

The reason I say to be nice, is because you cannot do this without warning. If a user is working on a multi-user system, and another user with proper permissions uses your software, the user working will be summarily kicked off the system(and consequently lose all work) until it is rebooted etc.

As Goldilocks states, this is the closest you will get using a userspace method. All other code is stored in the kernel, which I can't find at the moment, but here is the Document Related to Driver Power Management, at the Linux Kernel Archive

  • I know the "init" level in Linux. I am asking the implementation in kernel programming. – Victor Oct 23 '14 at 0:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.