Shutdown
In order to shutdown the computer, you need to use some sort of power management. Either APM or ACPI.
Contents |
BIOS shutdown
You can do shutdown with BIOS interrupt 15h:
shutdown: mov ax, 0x1000 mov ax, ss mov sp, 0xf000 mov ax, 0x5307 mov bx, 0x0001 mov cx, 0x0003 int 0x15 ret ;if interrupt doesnt work
APM
This is the basic sequence of APM commands that must be given in order to shut down a computer. For details on exactly how to implement these steps, see the APM article.
- Perform an installation check.
- Check if the APM version is at least 1.1
- Disconnect any existing APM interface.
- Connect the Real Mode interface.
- Tell the APM that your driver supports version 1.1
- Enable power management for all devices.
- Set the power state for all devices to "Off" (03h).
If the APM version is 1.0 (or the APM isn't told that your code supports version 1.1, so it will run as 1.0 for legacy purposes) it isn't possible to set the power state for all devices (maybe it's possible to shut each device down individually)
ACPI
ACPI Shutdown code with good explanation in C
A summary of ACPI shutdown from the above forum post:
The ACPI shutdown is technically a really simple thing all that is needed is aoutw(PM1a_CNT, SLP_TYPa | SLP_EN );
and the computer is powered off. The problem lies in the gathering of these values especialy since theSLP_TYPa
is in the\_S5
object which is in theDSDT
and therefore AML encoded.
Emulator-specific methods
In some cases (such as testing), you may want a poweroff method, but not need it to work on real hardware.
In Bochs, and older versions of QEMU(than 2.0), you can do the following:
outw(0xB004, 0x2000);
In newer versions of QEMU, you can do shutdown with:
outw(0x604, 0x2000);
In Virtualbox, you can do shutdown with:
outw(0x4004, 0x3400);