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.
Does anyone knows how to reboot the pc in protected-mode?
I've searched this forum and the FAQ, used google, searched at BonaFide, peeked at linux kernel (v1.0 and even v0.01) etc, and the closest source code I found was:
@Nelson
That's an idea But for most incredibly it may sound, I don't know how to cause a triple fault..
[hr]
@GLneo
Thanks, but I can't get your code to work.. do I have to prepare something before calling the reboot() function?
Check the debugger log of Bochs I've attached, and go to line 2036:
00167067762d[CPU0 ] Enter Protected Mode
00167067959i[KBD ] io write 0x64: command 0xfe: reset cpu
00167067959i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00167067959i[APIC0] local apic in CPU apicid=00 initializing
00167072123i[BIOS ] rombios.c,v 1.138 2005/05/07 15:55:26 vruppert Exp $
00167386060i[KBD ] reset-disable command received
00167488279i[VBIOS]
VGABios $Id: vgabios.c,v 1.61 2005/05/24 16:50:50 vruppert Exp $
marcio.f wrote:
Now I did and it works but shouldn't it run on Bochs too?
There are lots of things Bochs does differently from a "real" PC. Optimum is, of course, if it works on both, but sometimes you just have to accept that Bochs is an approximation, not more.
PS: Why not add the code for reboot() in the OSFAQ?
Just go ahead and add it, that's why we made the FAQ a Wiki.
Every good solution is obvious once you've found it.
typedef unsigned char uchar;
typedef uchar byte;
#define bit(n) (1<<(n)) /* Set to 1 bit n */
#define halt() asm volatile ("HLT") /* halt cpu */
#define disable() asm volatile ("CLI") /* disable interrupts */
/* keyboard interface IO port: data and control
READ: status port
WRITE: control register */
#define KBRD_INTRFC 0x64
/* keyboard interface bits */
#define KBRD_KDATA bit(0) /* keyboard data is (not) in buffer (bit 0) */
#define KBRD_UDATA bit(1) /* user data is (not) in buffer (bit 1) */
#define KBRD_IO 0x60 /* keyboard IO port */
#define KBRD_RESET 0xFE /* reset CPU command */
void reboot()
{
byte temp;
disable(); /* disable all interrupts */
do /* empty user data in buffer */
{
temp = inb(KBRD_INTRFC);
if ((temp & KBRD_KDATA) != 0)
inb(KBRD_IO); /* empty keyboard data in buffer */
} while ((temp & KBRD_UDATA) != 0);
outb(KBRD_INTRFC, KBRD_RESET); /* pulse CPU reset line */
halt(); /* if that didn't work, halt the CPU */
}
I've modified a bit the code; it might be ?big? but I think almost everything is explained, just as it should be
Please correct me if it's anything wrong.
I have a function that works in both Bochs and on the real pc. Don't have it on me at the moment (at work), but will post it here.
(I don't know how to post on Wiki yet . Will figure out how to do it and post it there too)
my code works on bochs, have you reset the a20 adderessing line ???, also to shut off the computer is very hard (i think) you have to go to real mode or something then comunicate with some protical api something.
GLneo wrote:
my code works on bochs, have you reset the a20 adderessing line ???
I don't think I did, but that's why I asked you in an early post if you did something before calling the reboot() function. If you want, take a look at the bochs log.
also to shut off the computer is very hard (i think) you have to go to real mode or something then comunicate with some protical api something.
p.s. there was a thead about it... somewhere
If there is I haven't found it because I searched the forum before creating this thread
KEYBOARD_BUSY equ 0x02
_reset_pc:
push ebp
mov ebp,esp
push eax
cli
call _wait_keyboard
mov al,0xFE ;send command to read output port to keyboard
out 0x64,al
sti
pop eax
mov esp,ebp
pop ebp
ret
_wait_keyboard:
push eax
.wait:
in al,0x64 ;wait for keyboard to be ready for next command
test al,KEYBOARD_BUSY
jnz .wait
pop eax
ret