Try this in kernel mode:
uint64_t null_idtr = 0;
asm("xor %%eax, %%eax; lidt %0; int3" :: "m" (null_idtr));
This can be quite helpful when doing operating system development on an i386/x86_64 system. You can use this for the regular restart case or when a kernel panic is supposed to restart immediately and you cannot make any assumptions on what is still working in the system.
You can also use this for debugging very low-level code if you don’t have a serial port or even an LED to report the most basic information: First make sure your code is reached by putting the reset code there. Then remove it again and put this code in:
if (condition)
reset();
else
for(;;);
The system will either hang or reset, depending on the condition.
What’s the purpose of the xor %eax,%eax?
You’re giving away all my secrets!
The infamous triple fault exception… I used this back in the old DOS days in a small TSR to reboot the machine in when you pressed a certain key combo. It even worked in cases where the regular ctrl-alt-del was caught by some other program :)
-Darkstar
xor %eax,%eax will zero eax register. I guess it’s faster than moving immediate data into register.
Ed.
Eldito:
Um, what I wanted to know was why %eax needs to be zero in this case.
Won’t the following be enough, or did I miss something?
uint64_t null_idtr = 0;
asm(“lidt %0; int3″ :: “m” (null_idtr));
I was wondering about that, too. And after consulting my old trusty ia32 assembly reference (actually the “Turbo Assembler 2.0 Reference manual”), I think it can indeed be left out: lidt works only on the memory reference given, and int3 definitely doesn’t need it….
Maybe some side-effect that I’m missing?
That trick is actually quite old. It was used by memory managers for DOS on 286 boxes back then: A reset was the only way to get the CPU back from protected mode to real mode and the “official” way to reset the CPU was too slow (it involved messing around with the keyboard controller, IIRC). The triple fault trick, however, was convenient and fast.