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