Rebooting from loader causes a "fault" in VMware Workstation
John Baldwin
jhb at freebsd.org
Mon Apr 22 16:07:05 UTC 2013
On Saturday, April 20, 2013 7:51:06 am Joshua Isom wrote:
> On 4/19/2013 8:48 PM, Jeremy Chadwick wrote:
> > I'm happy to open up a ticket with VMware about the issue as I'm a
> > customer, but I find it a little odd that other operating systems do not
> > exhibit this problem, including another BSD. Ones which reboot just
> > fine from their bootloaders:
> >
> > - Linux -- so many that I don't know where to begin: ArchLinux
> > 2012.10.06, CentOS 6.3, Debian 6.0.7, Finnix 1.0.5, Knoppix 7.0.4,
> > Slackware 14.0, and Ubuntu 11.10
> > - OpenBSD 5.2
> > - OpenIndiana -- build 151a7 (server version)
> >
> > So when you say "Blame VMware", I'd be happy to, except there must be
> > something FreeBSD's bootstraps are doing differently than everyone else
> > that causes this oddity. Would you not agree?
>
> A triple fault is standard practice as a fail safe guarantee of reboot.
> It's used either as a reboot, switch to real mode(IBM OS/2), or
> catastrophic unrecoverable failure.
>
> By the looks of grub(Linux and Solaris), it either jumps to it's own
> instruction, hoping the bios catches it("tell the BIOS a boot failure,
> which may result in no effect"), or jumps to a location that I can't yet
> determine what code exists there. I can't seem to find OpenBSD's reboot
> method from OpenBSD's cvsweb, only an exit but not where that exit leads
> to. The native operating system is irrelevant, only the boot loader so
> all the Linux distributions and Solaris forks all count as "grub." Many
> other bootloaders don't even have the reboot option, just "fail."
> Here's barebox, a Das U-Boot fork:
>
> /** How to reset the machine? */
> while(1)
>
> In any case, it's a bag of tricks, finding something that works and is
> "nice." We're talking 30 years of legacy. A triple fault, assuming the
> mbr and loader ignores or zeroes previous memory, is guaranteed and
> doesn't hang.
Actually, the traditional reboot method in real-mode (e.g. in DOS) is
to jump to 0xffff:0. The BIOS is supposed to have a restart routine
at that location. I've also seen jumps to 0xf000:fff0.
For example, BTX (the mini-kernel that "hosts" the loader and boot2)
uses the latter:
/*
* Reboot or await reset.
*/
sti # Enable interrupts
testb $0x1,btx_hdr+0x7 # Reboot?
exit.3: jz exit.3 # No
movw $0x1234, BDA_BOOT # Do a warm boot
ljmp $0xf000,$0xfff0 # reboot the machine
And in fact, when the loader calls __exit() that is precisely where it
ends up. The int 0x30 ends up here in btx.S:
/*
* System calls.
*/
.set SYS_EXIT,0x0 # Exit
.set SYS_EXEC,0x1 # Exec
...
/*
* System Call.
*/
intx30: cmpl $SYS_EXEC,%eax # Exec system call?
jne intx30.1 # No
...
intx30.1: orb $0x1,%ss:btx_hdr+0x7 # Flag reboot
jmp exit # Exit
And the 'exit' label eventually ends up at the 'exit.3' code I quoted
above. If the BIOS VMWare exports a reboot routine VMWare doesn't like
then VMWare needs to fix its BIOS. :)
The operations we try on x86 to shutdown from protected mode is quite a bit
longer (not including the ACPI bits). You can look at cpu_reset_real() in
sys/i386/i386/vm_machdep.c.
--
John Baldwin
More information about the freebsd-hackers
mailing list