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.

Victor
  • 382
  • 1
  • 3
  • 16
  • 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?](http://unix.stackexchange.com/questions/163370/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
  • BTW: If you want "assembly instruction", that has nothing to do with operating systems or their drivers, it has to do with specific platform architecture and this is not an appropriate place to ask about that. However, if you want to know about things on a slightly higher level -- e.g., what functions in the linux kernel accomplish this -- then here is as good a place as any. Note **you will not be able to do this with userspace code**. – goldilocks Oct 22 '14 at 16:39
  • @goldilocks OK, function name is enough. I'll try to read the code. I realize it is kernel code. – Victor Oct 22 '14 at 16:45
  • See Answer. I know this is partial, but it may help get you started. – eyoung100 Oct 22 '14 at 17:06
  • This seems to be a programming question. Migration suggested. – Torger597 Oct 22 '14 at 22:43
  • @Torger597 Yes, it is a programming question. – Victor Oct 23 '14 at 00:35

2 Answers2

4

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

Adrien M.
  • 3,466
  • 1
  • 17
  • 17
-2

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

eyoung100
  • 5,717
  • 21
  • 50