I'm working on a modified version of the 2.6.35 kernel for Olinuxino, an ARM9 based platform. I'm trying to modify the power management driver (the architecture specific part).
The processor is a Freescale i.MX23. This processor has a "special" pin, called PSWITCH, that triggers an interrupt that is handled by the power management driver.
If the switch is pressed,the system goes to standby. This is done in the driver by calling pm_suspend(PM_SUSPEND_STANDBY)
.
Given my hardware setup, I'd like to, instead, shutdown the system. So my question is:
What is the preferred way for a kernel-space process to trigger a clean system halt/poweroff?
I suppose there's a nice little function call out there, but I couldn't find it so far.
My kernel code (the file I'm working on is arch/arm/mach-mx23/pm.c) can be found here: github.com/spairal/linux-for-lobster, though my question calls for a general Linux kernel approach.
Shut down the systemThe shutdown command features two options: --halt and --poweroff . The --halt option stops the operating system while the --poweroff option turns off the system. [ Free download: Advanced Linux commands cheat sheet. ]
▶ You need 2-4 MB of space for an embedded kernel ▶ User space can fit in a few hundreds of KB. ▶ With a not-too-complex user-space, 8-16 MB of storage can be sufficient.
shutdown does its job by signalling the init process, asking it to change the runlevel. Runlevel 0 is used to halt the system, runlevel 6 is used to reboot the system, and runlevel 1 is used to put the system into a state where administrative tasks can be performed (single-user mode).
The most general way would be for your driver to invoke shutdown
as a userspace helper:
static const char * const shutdown_argv[] =
{ "/sbin/shutdown", "-h", "-P", "now", NULL };
call_usermodehelper(shutdown_argv[0], shutdown_argv, NULL, UMH_NO_WAIT);
(Presuming you have a /sbin/shutdown
binary installed). This will shut userspace down cleanly, unmount filesystems and then request the kernel shutdown and power off.
However, you may be able to do better than this - for example if you can guarantee that there's no disk filesystems mounted read/write, you could tell a kernel thread to invoke the kernel_power_off()
function (it shouldn't be done from interrupt context).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With