VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-bootsector.asm@ 60335

Last change on this file since 60335 was 60319, checked in by vboxsync, 9 years ago

bs3kit: 386 and 486 fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1; $Id: bs3-bootsector.asm 60319 2016-04-04 22:02:21Z vboxsync $
2;; @file
3; Generic bootsector for BS3.
4;
5; This sets up stack at %fff0 and loads the next sectors from the floppy at
6; %10000 (1000:0000 in real mode), then starts executing at cs:ip=1000:0000.
7;
8
9;
10; Copyright (C) 2007-2015 Oracle Corporation
11;
12; This file is part of VirtualBox Open Source Edition (OSE), as
13; available from http://www.virtualbox.org. This file is free software;
14; you can redistribute it and/or modify it under the terms of the GNU
15; General Public License (GPL) as published by the Free Software
16; Foundation, in version 2 as it comes in the "COPYING" file of the
17; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19;
20; The contents of this file may alternatively be used under the terms
21; of the Common Development and Distribution License Version 1.0
22; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23; VirtualBox OSE distribution, in which case the provisions of the
24; CDDL are applicable instead of those of the GPL.
25;
26; You may elect to license modified versions of this file under the
27; terms and conditions of either the GPL or the CDDL or both.
28;
29
30
31
32;*********************************************************************************************************************************
33;* Header Files *
34;*********************************************************************************************************************************
35%include "bs3kit.mac"
36%include "iprt/asmdefs.mac"
37%include "iprt/x86.mac"
38
39
40%ifdef __YASM__
41[map all]
42%endif
43
44;
45; Start with a jump just to follow the convention.
46; Also declare all segments/sections to establish them and their order.
47;
48 ORG 07c00h
49
50BITS 16
51start:
52 jmp short bs3InitCode
53 db 0ah ; Should be nop, but this looks better.
54g_OemId: ; 003h
55 db 'BS3Kit', 0ah, 0ah
56
57;
58; DOS 4.0 Extended Bios Parameter Block:
59;
60g_cBytesPerSector: ; 00bh
61 dw 512
62g_cSectorsPerCluster: ; 00dh
63 db 1
64g_cReservedSectors: ; 00eh
65 dw 1
66g_cFATs: ; 010h
67 db 0
68g_cRootDirEntries: ; 011h
69 dw 0
70g_cTotalSectors: ; 013h
71 dw 0
72g_bMediaDescriptor: ; 015h
73 db 0
74g_cSectorsPerFAT: ; 016h
75 dw 0
76g_cPhysSectorsPerTrack: ; 018h
77 dw 18
78g_cHeads: ; 01ah
79 dw 2
80g_cHiddentSectors: ; 01ch
81 dd 1
82g_cLargeTotalSectors: ; 020h - We (ab)use this to indicate the number of sectors to load.
83 dd 0
84g_bBootDrv: ; 024h
85 db 80h
86g_bFlagsEtc: ; 025h
87 db 0
88g_bExtendedSignature: ; 026h
89 db 0x29
90g_dwSerialNumber: ; 027h
91 dd 0x0a458634
92g_abLabel: ; 02bh
93 db 'VirtualBox', 0ah
94g_abFSType: ; 036h
95 db 'RawCode', 0ah
96g_BpbEnd: ; 03ch
97
98
99;
100; Where to real init code starts.
101;
102bs3InitCode:
103 cli
104
105 ; save the registers.
106 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.rax], ax
107 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.rsp], sp
108 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.rbp], bp
109 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.ss], ss
110 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.ds], ds
111 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.es], es
112
113 ; set up the segment reisters and stack.
114 mov ax, 0
115 mov ds, ax
116 mov es, ax
117 mov ss, ax
118 mov sp, BS3_ADDR_STACK
119 mov bp, sp
120 mov [bp], ax ; clear the first 8 bytes (terminates the ebp chain)
121 mov [bp + 02h], ax
122 mov [bp + 04h], ax
123 mov [bp + 06h], ax
124
125 ; Save flags now that we know that there's a valid stack.
126 pushf
127
128 ;
129 ; Clear the register area.
130 ;
131 push cx
132 push di
133 mov di, BS3_ADDR_REG_SAVE
134 mov cx, BS3REGCTX_size/2
135 cld
136 rep stosw
137 pop di
138 pop cx
139
140 ;
141 ; Do basic CPU detection.
142 ;
143
144 ; 1. bit 15-bit was fixed to 1 in pre-286 CPUs, and fixed to 0 in 286+.
145 mov ax, [bp - 2]
146 test ah, 080h ; always set on pre 286, clear on 286 and later
147 jnz .pre_80286
148
149 ; 2. On a 286 you cannot popf IOPL and NT from real mode.
150 or ah, (X86_EFL_IOPL | X86_EFL_NT) >> 8
151 push ax
152 popf
153 pushf
154 pop ax
155 test ah, (X86_EFL_IOPL | X86_EFL_NT) >> 8
156 jz .is_80286
157 ; 386 or later.
158
159
160 ; Save 386 registers. We can now skip the CS prefix as DS is flat.
161 shr eax, 16
162 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rax+2], ax
163 mov eax, esp
164 shr eax, 16
165 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rsp+2], ax
166 mov eax, ebp
167 shr eax, 16
168 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rbp+2], ax
169 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.fs], fs
170 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.gs], gs
171 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rbx], ebx
172 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rcx], ecx
173 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rdx], edx
174 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rsi], esi
175 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rdi], edi
176 mov eax, cr2
177 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.cr2], eax
178 mov eax, cr3
179 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.cr3], eax
180 mov byte [BS3_ADDR_REG_SAVE + BS3REGCTX.bMode], BS3_MODE_RM
181 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.cs], cs
182 xor eax, eax
183 mov ax, start
184 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.rip], eax
185
186 ; Pentium/486+: CR4 requires VME/CPUID, so we need to detect that before accessing it.
187 mov [cs:BS3_ADDR_REG_SAVE + BS3REGCTX.cr4], eax
188 popf
189 pushfd
190 pop eax
191 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rflags], eax
192 xor eax, X86_EFL_ID
193 push eax
194 popfd
195 pushfd
196 pop ebx
197 cmp ebx, eax
198 jne .no_cr4
199 mov eax, cr4
200 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.cr4], eax
201.no_cr4:
202 ; Make sure caching is enabled and alignment is off.
203 mov eax, cr0
204 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.cr0], eax
205 and eax, ~(X86_CR0_NW | X86_CR0_CD | X86_CR0_AM)
206 mov cr0, eax
207 jmp .do_load
208
209.is_80286:
210 smsw [BS3_ADDR_REG_SAVE + BS3REGCTX.cr0]
211.pre_80286:
212 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rbx], bx
213 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rcx], cx
214 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rdx], dx
215 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rsi], si
216 mov [BS3_ADDR_REG_SAVE + BS3REGCTX.rdi], di
217
218 ; Load all the code.
219.do_load
220 mov [g_bBootDrv], dl
221 call bs3InitLoadImage
222
223 ;
224 ; Call the user 'main' procedure (shouldn't return).
225 ;
226 cld
227 call BS3_SEL_TEXT16:0000h
228
229 ; Panic/hang.
230Bs3Panic:
231 cli
232 ;hlt
233 jmp Bs3Panic
234
235
236;;
237; Loads the image off the floppy.
238;
239; This uses g_cLargeTotalSectors to figure out how much to load.
240;
241; Clobbers everything except ebp and esp. Panics on failure.
242;
243; @param dl The boot drive number (from BIOS).
244; @uses ax, cx, bx, esi, di
245;
246BEGINPROC bs3InitLoadImage
247 push bp
248 mov bp, sp
249 push es
250%define bSavedDiskNo byte [bp - 04h]
251 push dx
252%define bMaxSector byte [bp - 06h]
253 push 0
254%define bMaxHead byte [bp - 08h]
255 push 0
256%define bMaxCylinder byte [bp - 0ah]
257 push 0
258
259 ;
260 ; Try figure the geometry.
261 ;
262 mov ah, 08h
263 int 13h
264 jc .failure
265 mov bMaxSector, cl
266 mov bMaxHead, dh
267 mov bMaxCylinder, ch
268 mov dl, bSavedDiskNo
269
270 ;
271 ; Reload all the sectors one at a time (avoids problems).
272 ;
273 mov si, [g_cLargeTotalSectors] ; 16-bit sector count ==> max 512 * 65 535 = 33 553 920 bytes.
274 dec si
275 mov di, BS3_ADDR_LOAD / 16 ; The current load segment.
276 mov cx, 0002h ; ch/cylinder=0 (0-based); cl/sector=2 (1-based)
277 xor dh, dh ; dh/head=0
278.the_load_loop:
279 xor bx, bx
280 mov es, di ; es:bx -> buffer
281 mov ax, 0201h ; al=1 sector; ah=read function
282 int 13h
283 jc .failure
284
285 ; advance to the next sector/head/cylinder.
286 inc cl
287 cmp cl, bMaxSector
288 jbe .adv_addr
289
290 mov cl, 1
291 inc dh
292 cmp dh, bMaxHead
293 jbe .adv_addr
294
295 mov dh, 0
296 inc ch
297
298.adv_addr:
299 add di, 512 / 16
300 dec si
301 jnz .the_load_loop
302
303 add sp, 3*2
304 pop dx
305 pop es
306 leave
307 ret
308
309 ;
310 ; Something went wrong, display a message.
311 ;
312.failure:
313 pusha
314
315 ; print message
316 mov si, .s_szErrMsg
317.failure_next_char:
318 lodsb
319 mov ah, 0eh
320 mov bx, 0ff00h
321 int 10h
322 cmp si, .s_szErrMsgEnd
323 jb .failure_next_char
324
325 ; panic
326 popa
327 call Bs3Panic
328.s_szErrMsg:
329 db 13, 10, 'read error!'
330.s_szErrMsgEnd:
331;ENDPROC bs3InitLoadImage - don't want the padding.
332
333
334;
335; Pad the remainder of the sector with int3's and end it with the DOS signature.
336;
337bs3Padding:
338 times ( 510 - ( (bs3Padding - start) % 512 ) ) db 0cch
339 db 055h, 0aah
340
Note: See TracBrowser for help on using the repository browser.

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