[Newb question]How to shutdown and reboot the computer?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

[Newb question]How to shutdown and reboot the computer?

Post by zhiayang »

I understand I can clean up, stop interrupts, instruct the user that it's safe to press the power button, but that isn't friendly to me. I also understand I can forcefully triple-fault the cpu to reboot, but that's dirty. Anyone know how?
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: [Newb question]How to shutdown and reboot the computer?

Post by turdus »

requimrar wrote:I understand I can clean up, stop interrupts, instruct the user that it's safe to press the power button, but that isn't friendly to me. I also understand I can forcefully triple-fault the cpu to reboot, but that's dirty. Anyone know how?

Code: Select all

hardware_resetfunc:
		mov			al, 0FEh
		out			64h, al
		push		  word 0
		pop			ds
		mov			ax, 1234h
		mov			[0472], ax
		jmp			far 0FFFFh:0
It uses the keyboard method, and if it fails by any chance calls and restarts BIOS POST code. Real mode of course. As for shutdown, see RBIL APM section or osdev wiki for ACPI shutdown.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: [Newb question]How to shutdown and reboot the computer?

Post by zhiayang »

turdus wrote:
requimrar wrote:I understand I can clean up, stop interrupts, instruct the user that it's safe to press the power button, but that isn't friendly to me. I also understand I can forcefully triple-fault the cpu to reboot, but that's dirty. Anyone know how?

Code: Select all

hardware_resetfunc:
		mov			al, 0FEh
		out			64h, al
		push		  word 0
		pop			ds
		mov			ax, 1234h
		mov			[0472], ax
		jmp			far 0FFFFh:0
It uses the keyboard method, and if it fails by any chance calls and restarts BIOS POST code. Real mode of course. As for shutdown, see RBIL APM section or osdev wiki for ACPI shutdown.

Thanks for the references, i'll checkemout. as for the above restart code, is there anything for protected mode, or something on the wiki?
rdos
Member
Member
Posts: 3308
Joined: Wed Oct 01, 2008 1:55 pm

Re: [Newb question]How to shutdown and reboot the computer?

Post by rdos »

This works on all PCs I know about (protected mode, paging enabled):

Code: Select all

    cli
wait_gate1:
    in al,64h
    and al,2
    jnz wait_gate1
    mov al,0D1h
    out 64h,al
wait_gate2:
    in al,64h
    and al,2
    jnz wait_gate2
    mov al,0FEh
    out 60h,al              ; keyboard RESET
;
    xor eax,eax
    mov cr3,eax           ; tripple fault

reset_wait:
    jmp reset_wait
ACPI also has a reset register, but it is optional, so I wouldn't rely on it.
rdos
Member
Member
Posts: 3308
Joined: Wed Oct 01, 2008 1:55 pm

Re: [Newb question]How to shutdown and reboot the computer?

Post by rdos »

berkus wrote:
rdos wrote:This works on all PCs I know about (protected mode, paging enabled)
Please, try it on a macbook pro. I have doubts.
OK. All x86-based PCs. I have no interest in non-x86 PCs. :mrgreen:
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Re: [Newb question]How to shutdown and reboot the computer?

Post by Brynet-Inc »

rdos wrote:OK. All x86-based PCs. I have no interest in non-x86 PCs. :mrgreen:
All modern Apple systems use Intel processors, so, they're x86.

Your code wouldn't work on "legacy free" systems that only have USB keyboards.
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
rdos
Member
Member
Posts: 3308
Joined: Wed Oct 01, 2008 1:55 pm

Re: [Newb question]How to shutdown and reboot the computer?

Post by rdos »

Brynet-Inc wrote:
rdos wrote:OK. All x86-based PCs. I have no interest in non-x86 PCs. :mrgreen:
All modern Apple systems use Intel processors, so, they're x86.

Your code wouldn't work on "legacy free" systems that only have USB keyboards.
At least it works on computers that only has USB keyboards. The keyboard emulation hardware is available in the chipsets even if the physical connection to a PS/2 keyboard is not present on the mother board. One reason for this is probably that the keyboard port has other functions, like reset and A20 gate.

BTW, it would work if there is a loop-counter, like this:

Code: Select all

    xor cx,cx
    cli
wait_gate1:
    in al,64h
    and al,2
    jz gate1_ok
    loop wait_gate1
gate1_ok:
    mov al,0D1h
    out 64h,al
    xor cx,cx
wait_gate2:
    in al,64h
    and al,2
    jz gate2_ok
    loop wait_gate2
gate2_ok:
    mov al,0FEh
    out 60h,al              ; keyboard RESET
;
    xor eax,eax
    mov cr3,eax           ; tripple fault

reset_wait:
    jmp reset_wait
Then, if there is no legacy keyboard-port, it would tripple fault instead (which would fail if the tripple fault reset logic is not present on the motherboard).
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: [Newb question]How to shutdown and reboot the computer?

Post by Owen »

The correct* way to reset a BIOS-based x86 PC is as follows:
  1. Halt all cores except this one
  2. Write the ACPI reset vector (if present)
  3. If ACPI says there is an i8042, perform a keyboard-controller reset, otherwise, use a ~10µs delay
  4. Repeat step 2
  5. Repeat step 3
  6. Tell your user to restart their machine (as an "in case all else fails" method)
  7. Load a zero-length IDT and cause an exception, thereby invoking a triple fault, and hope this restarts the machine (It does sometimes, but we are here because we have given up all hope of resetting the machine properly anyway)
Note that if ACPI says there is no 8042, do not touch the 8042. You will hang many machines (such as the aforementioned MacBook pro, or indeed any x86 Mac). You must write the ACPI reset vector twice.

Now, some notes:
  • The 10µs delay is speculation, but probably necessary (because the way most of the ACPI reboot vectors work is a great big hack...).
  • If booted from EFI, probably add step 6.5: Invoke the EFI shutdown system API and hope it works. It does most of the time.
With any luck, you'll have rebooted by step 4 or 5. Probably because of the ACPI reset vector. I'm just going to quote Linux kernel hacker mjg59 on the subject of the keyboard controller:
mjg59 wrote: The original IBM PC had the CPU reset line tied to the keyboard controller. Writing the appropriate magic value pulses the line and the machine resets. This is all very straightforward, except for the fact that modern machines don't have keyboard controllers (they're actually part of the embedded controller) and even more modern machines don't even pretend to have a keyboard controller. Now, embedded controllers run software. And, as we all know, software is dreadful. But, worse, the software on the embedded controller has been written by BIOS authors. So clearly any pretence that this ever works is some kind of elaborate fiction. Some machines are very picky about hardware being in the exact state that Windows would program. Some machines work 9 times out of 10 and then lock up due to some odd timing issue. And others simply don't work at all. Hurrah!
* The way Windows does it. By extension, the way motherboard manufacturers expect you to do this. By extension, the only way that works on every machine. By extension, the way Linux, FreeBSD and everybody else does it.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: [Newb question]How to shutdown and reboot the computer?

Post by zhiayang »

Thanks guys, but what about shutting down? i'm mostly worried about shutting down.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: [Newb question]How to shutdown and reboot the computer?

Post by Owen »

For shutting down, you basically have three options
  • APM. APM is 32-bit only, ancient, fragile, and BIOS only. It is not present on modern machines. APM is best forgotten.
    Complexity: Relatively simple, but again, nobody supports it any more.
  • ACPI. You disable all wakeup events you have enabled and then enter something which looks a lot like an ACPI suspend state.
    Complexity: Hard, but works pretty much everywhere most people care about.
  • EFI. You invoke the EFI ShutdownSystem runtime service.
    Complexity: Easy. However, requires you to have been booted from EFI. Fortunately, works on most EFI systems
Yeah, no good answers...
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: [Newb question]How to shutdown and reboot the computer?

Post by DavidCooper »

Is there any danger of damaging something by just switching the machine off? (Obviously you wouldn't want to do this while anything's being written to a storage device.) At the moment I just switch it off and hope it's safe to do so.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: [Newb question]How to shutdown and reboot the computer?

Post by Owen »

DavidCooper wrote:Is there any danger of damaging something by just switching the machine off? (Obviously you wouldn't want to do this while anything's being written to a storage device.) At the moment I just switch it off and hope it's safe to do so.
Making sure all writes are complete and telling the user to turn off the computer is a valid method. It's just not a method users tend to be fond of.
rdos
Member
Member
Posts: 3308
Joined: Wed Oct 01, 2008 1:55 pm

Re: [Newb question]How to shutdown and reboot the computer?

Post by rdos »

Owen wrote:The correct* way to reset a BIOS-based x86 PC is as follows:
  1. Halt all cores except this one
  2. Write the ACPI reset vector (if present)
  3. If ACPI says there is an i8042, perform a keyboard-controller reset, otherwise, use a ~10µs delay
  4. Repeat step 2
  5. Repeat step 3
  6. Tell your user to restart their machine (as an "in case all else fails" method)
  7. Load a zero-length IDT and cause an exception, thereby invoking a triple fault, and hope this restarts the machine (It does sometimes, but we are here because we have given up all hope of resetting the machine properly anyway)
Note that if ACPI says there is no 8042, do not touch the 8042. You will hang many machines (such as the aforementioned MacBook pro, or indeed any x86 Mac). You must write the ACPI reset vector twice.

Now, some notes:
  • The 10µs delay is speculation, but probably necessary (because the way most of the ACPI reboot vectors work is a great big hack...).
  • If booted from EFI, probably add step 6.5: Invoke the EFI shutdown system API and hope it works. It does most of the time.
With any luck, you'll have rebooted by step 4 or 5. Probably because of the ACPI reset vector.
I wouldn't want to use this protocol because when a reset is requested, system state might already be unstable. To issue ACPI-commands, use delays, stop cores or anything like that would risk a hang instead of a RESET. I might append it after my usual reset sequence, but never use it like it is. A RESET sequence should always begin with things that can be coded directly (like the keyboard reset code), and which need no external parameters that might have become corrupted.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: [Newb question]How to shutdown and reboot the computer?

Post by Brendan »

Hi,
rdos wrote:I wouldn't want to use this protocol because when a reset is requested, system state might already be unstable.
When a reset is requested by the user (e.g. they close all their applications and ask the OS to reset the computer so they can boot a different OS); the system shouldn't be unstable. When a reset is requested by software (e.g. maybe some sort of kernel upgrade thing?) then the system still shouldn't be unstable.

The only case where the OS wouldn't be stable is if the OS was unstable before the reset was requested. For example, if your kernel crashes and the "kernel panic" requests a reboot. Hopefully this never happens in official releases because you're potentially screwed regardless of what you do.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: [Newb question]How to shutdown and reboot the computer?

Post by Owen »

rdos wrote:I wouldn't want to use this protocol because when a reset is requested, system state might already be unstable. To issue ACPI-commands, use delays, stop cores or anything like that would risk a hang instead of a RESET. I might append it after my usual reset sequence, but never use it like it is. A RESET sequence should always begin with things that can be coded directly (like the keyboard reset code), and which need no external parameters that might have become corrupted.
The ACPI reset vector is, guess what, an I/O port or memory write! You query ACPI for it at system startup and note it down.

However, you touch my nonexistent keyboard controller and you'll suddenly find that your code is no longer executing; indeed, you'll find yourself completely hung. After all, my machine doesn't have a keyboard controller, nor does it claim to, so if you don't note down whether ACPI said there was an 8042 or not you'll bork my machine.

So, really, there is no reason not to use the above-mentioned reset method.
Post Reply