VirtualBox

Ticket #10164: biosreboot.S

File biosreboot.S, 6.2 KB (added by Greg A. Woods, 13 years ago)

example code (from NetBSD) with lots of new comments explaining what I've learned

Line 
1/* $NetBSD: biosreboot.S,v 1.4 2005/12/11 12:17:48 christos Exp $ */
2
3/*
4 * Copyright (c) 1997
5 * Perry E. Metzger. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgements:
17 * This product includes software developed for the NetBSD Project
18 * by Perry E. Metzger.
19 * 4. The names of the authors may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35
36#include <machine/asm.h>
37
38 .text
39
40 .set BDA_BOOT,0x472 /* Boot howto flag location */
41
42/*
43 * Reboot the system via the BIOS.
44 */
45ENTRY(reboot)
46 pushl %ebp
47 movl %esp,%ebp
48 pushl %ebx
49 push %esi
50 push %edi
51
52 call _C_LABEL(prot_to_real)
53 .code16
54
55 /*
56 * We don't want to use INT 19 for reboot because it isn't
57 * guaranteed to work, and besides it is what the BIOS itself
58 * calls _after_ a successful completion of the POST routines.
59 *
60 * From the IBM PC BIOS documentation:
61 *
62 * "INT 19 - SYSTEM - BOOTSTRAP LOADER
63 *
64 * "This interrupt reboots the system without clearing memory
65 * or restoring interrupt vectors. Because interrupt vectors
66 * are preserved, this interrupt usually causes a system hang
67 * if any TSRs have hooked vectors from 00h through 1Ch,
68 * particularly INT 08.
69 *
70 * "To accomplish a warm boot equivalent to Ctrl-Alt-Del,
71 * store 1234h in 0040h:0072h and jump to FFFFh:0000h. For a
72 * cold boot equivalent to a reset, store 0000h at 0040h:0072h
73 * before jumping."
74 *
75 * Note: Unfortunately both warm and cold boot on VirtualBox
76 * (since at least 4.0.4 through to at least 4.1.8) hang the
77 * (virtual) system. What does seem to work on VirtualBox,
78 * from the kernel, is the PC/AT Control Port A Fast Reset.
79 * (PCI-bus system & CPU reset does not work.)
80 *
81 * From the Linux kernel:
82 *
83 * "Write zero to CMOS register number 0x0f, which the BIOS
84 * POST routine will recognize as telling it to do a proper
85 * reboot. (Well that's what this book in front of me says --
86 * it may only apply to the Phoenix BIOS though, it's not
87 * clear). At the same time, disable NMIs by setting the top
88 * bit in the CMOS address register, as we're about to do
89 * peculiar things to the CPU."
90 *
91 * outb_p (0x8f, 0x70);
92 * outb_p (0x00, 0x71);
93 *
94 * For now we will try what the BIOS folks call a "cold boot"
95 * (it's actually a form of warm boot, since it does not
96 * trigger a hardware reset) since this will ensure the most
97 * complete reset of system state is done without actually
98 * causing a hardware reset.
99 */
100 movw $0x0000, BDA_BOOT /* set cold boot (clear warm boot flag) */
101 /*
102 * XXX apparently this would only be correct for an original 8086:
103 *
104 ljmp $0xffff, $0x0000
105 */
106 /*
107 * "however in various literature it is mentioned that
108 * $0xf000,$0xfff0 is bound to work better..."
109 *
110 * http://unix.derkeiler.com/Mailing-Lists/FreeBSD/hackers/2003-11/0205.html
111 *
112 * "Apparently CPUs haven't started with the CS:IP combination
113 * FFFF:0000 since the 8086. The 80286 changed this to
114 * F000:FFF0.
115 *
116 * "32-bit CPUs start up in what is colloquially known as
117 * unreal mode. Even though the initial value of the CS
118 * register after reset is F000, the segment descriptor
119 * associated with that register initially holds FFFF0000 as
120 * its base address. So the physical address that initially
121 * corresponds to the the 16:16 CS:IP address F000:FFF0 is in
122 * fact, and has been since the days of the 80386, FFFFFFF0.
123 * And that's where the machine firmware is principally mapped
124 * into physical address space on 32-bit and 64-bit x86
125 * machines."
126 *
127 * http://superuser.com/questions/336021/is-bios-read-from-the-bios-chip-or-copied-into-ram-on-startup
128 *
129 * Since we are in 16-bit "real" mode, we can use the 16:16
130 * address here.
131 *
132 * There's also a story that one should never try to reset the
133 * CPU without enabling CPU A20 to the address BUS.
134 *
135 * http://www.rcollins.org/Productivity/A20Reset.html
136 *
137 * See here for doing this:
138 *
139 * http://www.brokenthorn.com/Resources/OSDev9.html
140 *
141 * However others say "the CPU restart vector on 286 and above
142 * processors is not F000:FFF0. These CPUs actually execute
143 * out of the very top of their physical address space, which
144 * in some cases is occupied by a [special] boot loader...
145 * Even though the CPU is executing out of memory above the
146 * 1MB address mark, it is still executing in real mode, not
147 * protected mode (really, real mode). Once the CS register is
148 * reloaded with any value, the CPU disables the upper address
149 * lines and, typically, continues to execute at the
150 * 8086-compatible reboot address, F000:FFF0".
151 *
152 * NOTE: Apparently on some machines there will be an INT 19h
153 * instruction here, while others will jump to the main BIOS
154 * entry point (e.g. f000:e05b).
155 *
156 * Jump to the BIOS "Power On Reset Vector":
157 */
158 ljmp $0xf000, $0xfff0
159
160 /* NOTE: We will never get here.... */
161
162 calll _C_LABEL(real_to_prot)
163 .code32
164
165 movl %ebx, %eax
166
167 pop %edi
168 pop %esi
169 popl %ebx
170 popl %ebp
171 ret

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy