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