Reboot: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
No edit summary
Line 1: Line 1:
There are several methods for rebooting, including
There are several methods for rebooting, including


# ACPI Reset command
# load a 0-sized IDT and issue an interrupt (that'll triple fault and reset)
# load a 0-sized IDT and issue an interrupt (that'll triple fault and reset)
# Use the 8042 keyboard controller to pulse the CPU's RESET pin
# Use the 8042 keyboard controller to pulse the CPU's RESET pin

== ACPI reset command ==
See [http://superuser.com/questions/294681/how-does-a-computer-restart-itself How does a computer restart itself]


== Short code to do a 8042 reset ==
== Short code to do a 8042 reset ==

Revision as of 01:11, 18 February 2013

There are several methods for rebooting, including

  1. ACPI Reset command
  2. load a 0-sized IDT and issue an interrupt (that'll triple fault and reset)
  3. Use the 8042 keyboard controller to pulse the CPU's RESET pin

ACPI reset command

See How does a computer restart itself

Short code to do a 8042 reset

void reboot()
{
    uint8_t good = 0x02;
    while (good & 0x02)
        good = inb(0x64);
    outb(0x64, 0xFE);
    halt();
}


Annotated code for reboot()

/* keyboard interface IO port: data and control
   READ:   status port
   WRITE:  control register */
#define KBRD_INTRFC 0x64

/* keyboard interface bits */
#define KBRD_BIT_KDATA 0 /* keyboard data is in buffer (output buffer is empty) (bit 0) */
#define KBRD_BIT_UDATA 1 /* user data is in buffer (command buffer is empty) (bit 1) */

#define KBRD_IO 0x60 /* keyboard IO port */
#define KBRD_RESET 0xFE /* reset CPU command */

#define bit(n) (1<<(n)) /* Set bit n to 1 */

/* Check if bit n in flags is set */
#define check_flag(flags, n) ((flags) & bit(n))

void reboot()
{
    uint8_t temp;

    asm volatile ("cli"); /* disable all interrupts */

    /* Clear all keyboard buffers (output and command buffers) */
    do
    {
        temp = inb(KBRD_INTRFC); /* empty user data */
        if (check_flag(temp, KBRD_BIT_KDATA) != 0)
            inb(KBRD_IO); /* empty keyboard data */
    } while (check_flag(temp, KBRD_BIT_UDATA) != 0);

    outb(KBRD_INTRFC, KBRD_RESET); /* pulse CPU reset line */
    loop:
    asm volatile ("hlt"); /* if that didn't work, halt the CPU */
    goto loop; /* But if a non maskable interrupt is received, halt again */
}