Search code examples
coperating-systemkernelsystem-shutdown

Shutdown computer, how operating systems achieve it? (C Kernel development)


I've been developing an OS lately in C. But how can I shutdown the computer? By saying 'shutdown the computer', I mean a force shutdown.

How can I do that in C kernel development?
Any help would be appreciated.


Solution

  • To sum up all the comments in an answer so it stays:

    The modern way (circa 2020) to handle power management and shutdown is to use the Advanced Configuration and Power Interface (ACPI), see for example Getting Started With ACPI and OS Shutdown.

    History of ACPI

    ACPI was developed through collaboration between Intel, Microsoft, Toshiba, HP, and Phoenix in the mid-1990s. Before the development of ACPI, operating systems (OS) primarily used BIOS (Basic Input/Output System) interfaces for power management and device discovery and configuration. This power management approach used the OS’s ability to call the system BIOS natively for power management. The BIOS was also used to discover system devices and load drivers based on probing input/output (I/O) and attempting to match the correct driver to the correct device (plug and play). The location of devices could also be hard coded within the BIOS because the platform itself was non-enumerable.These solutions were problematic in three key ways. First, the behavior of OS applications could be negatively affected by the BIOS-configured power management settings, causing systems to go to sleep during presentations or other inconvenient times. Second, the power management interface was proprietary on each system. This required developers to learn how to configure power management for each individual system. Finally, the default settings for various devices could also conflict with each other, causing devices to crash, behave erratically, or become undiscoverable.ACPI was developed to solve these problems and others.

    What is ACPI?

    ACPI can first be understood as an architecture-independent power management and configuration framework that forms a subsystem within the host OS. This framework establishes a hardware register set to define power states (sleep, hibernate, wake, etc). The hardware register set can accommodate operations on dedicated hardware and general purpose hardware.The primary intention of the standard ACPI framework and the hardware register set is to enable power management and system configuration without directly calling firmware natively from the OS. ACPI serves as an interface layer between the system firmware (BIOS) and the OS, as shown in Figure0-1 and Figure0-2, with certain restrictions and rules.

    ACPI overview

    Source: Advanced Configuration and Power Interface (ACPI) Specification, Version 6.3 January 2019

    This answer provides the historical background on the problem of OS controlling computer power and shutdown, and why it has taken so long to achieve some standard. Quoting:

    Some history...

    Before 1995 and the adoption of the ATX standard, the vast majority of desktop PCs had power switches which were directly connected to the power supply, and acted as mechanical switches only, interrupting the electric circuit when opened. It was therefore impossible for software to control the state of the power supply. But that wasn’t much of a problem initially: when the IBM PC was designed, storage media (including hard drives) had no caches, so when the hardware told the operating system that a write was finished, it really was. Under DOS, the kernel and shell worked together to ensure that when the DOS prompt was displayed, all the buffers were flushed; when software caches appeared, they adhered to this too (at least, the well-behaved ones did). Users were taught to exit programs, wait for the prompt, and wait for drive lights to switch off before powering the system down. (They might also need to PARK the drive heads but that’s another story.) Even with pre-95 versions Windows, users exited to DOS before switching the system off.

    Windows 95 and other multi-tasking operating systems changed the picture: they didn’t “exit to DOS” on shutdown (either because they weren’t supposed to, or because there was no DOS to return to), so users couldn’t wait for a prompt to appear before switching off. In most truly multi-tasking systems there’s never really a quiescent state where the system is safe to power off, in normal operation; so most multi-tasking operating systems have a way for the user to say “I want to power the system down, prepare to do so”, and the operating system then needs to tell the user when it’s safe to power off. This ensures that all applications have finished writing the user’s files to disk, and that the system is in a consistent state (ignoring hard drive caches here...).

    Shutting down PCs

    Two features brought system power under operating system control: APM on the one hand, and ATX on the other. APM, which was designed for laptops initially, provided mechanisms for software to request changes in the system’s power state: fully on, in standby, suspended, or off. ATX changed the physical connections in the system so that power control became possible everywhere: it required that the power button no longer be a switch directly connected to the power supply, but instead that it be connected to the motherboard, and that the motherboard control the power supply itself. The power supply was also changed so that it would supply a small amount of current all the time, allowing the system to be left in “soft off” status, i.e. with enough capabilities to turn itself back on again when requested to do so.

    You can see an example of the use of APM to power off a PC in Shutdown, a small assembly-language program written for DOS. Operating systems such as Windows 95 (with the APM drivers installed) would do the same thing.

    It was quite exciting (to me anyway) to see APM and ATX roll out progressively in the second half of the nineties, and see systems suddenly acquire the ability to turn themselves off without human intervention, and to turn themselves back on at the press of a key on some systems. This was yet another sign of PCs “growing up” (“real” computers, i.e. Unix workstations in my mind at the time, had had the ability for a while, as had Macs).

    Why did it take so long?

    All this doesn’t address the actual question:

    Was it really that hard to implement a self shut-off? What is the reason it took quite long for computers to feature this.

    If you design it in from the start, it’s not all that hard to implement self shut-off, and many systems existed with this ability quite a few years before the PC acquired it.

    [..]In the early nineties, surprising as it may seem now, there was a fair amount of uncertainty as to what the computing future held. Apple was making its comeback with cheaper Macs, workstation manufacturers were releasing lower-priced systems (or rather, not-so-expensive systems), a variety of operating systems and platforms were vying for attention (Be, RiscPC...), IBM was still pushing OS/2 and Taligent, Microsoft was pushing Windows NT, etc.

    Eventually an alliance of companies took it upon itself to “remedy” this situation: Intel and Microsoft (referred to at the time as Wintel). This started in the early nineties, but wasn’t a done deal for quite a while; when ATX was published in 1995 (by Intel on its own), pundits liked it but weren’t sure it would convince the industry, although they were proved wrong fairly quickly. Windows 95 sealed the deal though and Intel and Microsoft became the definers of the PC platform (with the PC System Design Guide in particular).

    Here is a Microsoft patent from the 90's for software-controlled computer hibernation which is related to software-controlled power management.

    Effectively, software-controlled shutdown is a kind of simulation of shutdown, as real shutdown takes place when hardware power is actually switched off. Soft shutdown effectively is to make computer do absolutely nothing and consume as less power as possible. So OS makes sure to end all processes and make the CPU go to specific OS routines that simulate a shutdown (note: this state usually cannot be reversed except by a hardware interrupt of restart). Whether the OS routines that make soft-shutdown use ACPI or some other method/interface to simulate is another issue.

    This post describes, roughly in outline, the shutdown process of the linux kernel, to get an idea.

    [..]Anyways in there we have basically three functions that sketch the process of shutting down the system

    void kernel_halt(void) // which ends with a system in halt state
    void kernel_power_off(void) // which ends with a system powered off
    void kernel_restart(char *cmd) // which ends the system to yet restart it
    

    Those functions are very brief and can be hence pasted here in complete. Their code best shows what steps are taken on the way to shutdown in the kernel. (the comments are by me and might not be 100% ideal and correct, check yourself for being sure. It is simple a try.

    void kernel_halt(void)
    {
        // 1st step does:
        // a) call functions/callback registered to run at reboot/shutdown
        // b) set system_sate to SYSTEM_HALT
        // c) stop the userspacetool interaction
        // d) call device_shutdown() function
        kernel_shutdown_prepare(SYSTEM_HALT);
    
        // 2nd step: I think this is mostly a necessity for multi-cpu systems
        migrate_to_reboot_cpu();
    
        // 3rd step:
        // syscore_shutdown - Execute all the registered system core shutdown callbacks 
        syscore_shutdown();
    
        // 4th messages
        pr_emerg("System halted\n");
        kmsg_dump(KMSG_DUMP_HALT);
    
        // 5th call arch specific cpu-halt-code
        machine_halt();
    }