Academic Operating System

We are developing an operating system for my personal research and practical education. For the academic purpose, this motivation is similar to MINIX, but we do not focus on theories. Our main objective is to provide knowledges on hardware-related programming. This is one of the most difficult and complex parts when we start the development of operating system from scratch.

The source code is available at the public github repository.

Power off

Using APM

Advanced power management (APM) is a set of APIs implemented as BIOS calls (INT 15h with AH=53h) to manage the power management configuration. The following specification is cited from “PhoenixBIOS 4.0 Revision 6 User's Manual.”

  INT 15h
  AH=53 : for APM 1.0 and APM 1.1 BIOS Services

  AL = 01h Interface Connect
    Input
      BX = 0000h = Power Device ID (APM BIOS)

  AL = 0Eh APM Driver Version (APM 1.1 only)
    Input
      BX = 0000h = BIOS device
      CH : APM Driver major version number (BCD)
      CL : APM Driver minor version number (BCD)
    Output
      AH : APM Connection major version number (BCD)
      AL : APM Connection minor version number (BCD)

  AL = 08h Enable/disable power management
    Input
      BX : Power Device ID:
           0001h = All PM devices controlled by the BIOS
           FFFFh = All PM devices controlled by the BIOS (For compatibility with APM 1.0)

      CX : Function code:
           0000h = Disable power management
           0001h = Enable power management

  AL = 07h Set Power State
    Input
       BX : Power Device ID:
            0001h = All PM devices managed by the BIOS
            01XXh = Display
            02XXh = Secondary Storage
            03XXh = Parallel Ports
            04XXh = Serial Ports
            05XXh = Network Adapters
            06XXh = PCMCIA Sockets
            E000h-EFFFh = OEM-defined power-device IDs
                 where XXh = Unit Number (0 based)
                             Unit Number FFh = all units in this class
       CX : Power State:
            0000h = APM enabled
            0001h = Standby
            0002h = Suspend
            0003h = Off
            0004h = Last Request Processing Notification
            0005h = Last Request Rejected
            0006h-001Fh = Reserved system states
            0020h-003Fh = OEM-defined system states
            0040h-007Fh = OEM-defined device states
            0080-FFFFh = Reserved device states

The following code tries to power off the machine using the APM API. It should disable PIC not to receive interrupts from peripheral devices before the power off procedure (Line 1). The power off procedure comprises four steps using INT 15h; 1) connecting to APM interface using AL=01h function (Line 4–6), 2) setting the APM driver version to 1.2 using AL=0Eh function (Line 9–12), 3) enabling power management for all devices from software using AL=08h function (Line 15–18), and 4) changing power state to “off” using AL=07h function (Line 20–23). The third step may return an error of 0Ch (function not supported) in some buggy firmware and the fourth step will fail if it really fails, hence we ignore this error.

	call	disable_pic	/* Disable PIC */

	/* Power off with APM */
	movw	$0x5301,%ax	/* Connect APM interface */
	movw	$0x0,%bx	/* Specify system BIOS */
	int	$0x15		/* Return error code in %ah with CF */
	jc	1f		/* Error */

	movw	$0x530e,%ax	/* Set APM version */
	movw	$0x0,%bx	/* Specify system BIOS */
	movw	$0x102,%cx	/* Version 1.2 */
	int	$0x15		/* Return error code in %ah with CF */
	jc	1f		/* Error */

	movw	$0x5308,%ax	/* Enable power management */
	movw	$0x1,%bx	/* All devices managed by the system BIOS */
	movw	$0x1,%cx	/* Enable */
	int	$0x15		/* Ignore errors */

	movw	$0x5307,%ax	/* Set power state */
	movw	$0x1,%bx	/* All devices managed by the system BIOS */
	movw	$0x3,%cx	/* Off */
	int	$0x15

1:
	/* Implement an error handler here */

Using ACPI

This part will be written when ACPI power off code is described in the textbook.