2 ; ** Copyright 1998 Brian J. Swetland
3 ; ** All rights reserved.
5 ; ** Redistribution and use in source and binary forms, with or without
6 ; ** modification, are permitted provided that the following conditions
8 ; ** 1. Redistributions of source code must retain the above copyright
9 ; ** notice, this list of conditions, and the following disclaimer.
10 ; ** 2. Redistributions in binary form must reproduce the above copyright
11 ; ** notice, this list of conditions, and the following disclaimer in the
12 ; ** documentation and/or other materials provided with the distribution.
13 ; ** 3. The name of the author may not be used to endorse or promote products
14 ; ** derived from this software without specific prior written permission.
16 ; ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 ; ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 ; ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 ; ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 ; ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 ; ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 ; ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 ; ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 ; ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 ; ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 ; ** Copyright 2001-2004, Travis Geiselbrecht. All rights reserved.
29 ; ** Distributed under the terms of the NewOS License.
33 ; ** Reviewed, documented and some minor modifications and bug-fixes
34 ; ** applied by Michael Noisternig on 2001-09-02.
37 %define VESA_X_TARGET
640
38 %define VESA_Y_TARGET
480
39 %define VESA_BIT_DEPTH_TARGET
16
43 ORG 0x7c00 ; start code at 0x7c00
45 sectors
dw 800 ; this is interpreted as data (bytes 3 and 4)
46 ; and patched from outside to the size of the bootcode (in sectors)
48 cli ; no interrupts please
51 mov ss,ax ; setup stack from 0 - 0x7c00
52 mov sp,0x7c00 ; stack pointer to top of stack
53 call enable_a20
; enable a20 gate
54 lgdt [ss:gdt
] ; load global descriptor table
55 mov eax,cr0
; switch to protected mode
56 or al,0x1 ; by setting 'protected mode enable' bit
57 mov cr0
,eax ; and writing back
58 jmp dword 0x8:unreal32
; do the actual switch into protected mode
59 ; The switch into protected mode and back is to get the processor into 'unreal' mode
60 ; where it is in 16-bit mode but with segments that are larger than 64k.
61 ; this way, the floppy code can load the image directly into memory >1Mb.
63 mov bx,0x10 ; load all of the data segments with large 32-bit segment
67 and al,0xfe ; switch back to real mode
69 jmp 0x7c0:unreal
-0x7c00 ; actually go back to 16-bit
71 xor ax,ax ; load NULL-descriptor (base 0) into ds, es, ss
72 mov es,ax ; the processor doesn't clear the internal high size bits on these descriptors
73 mov ds,ax ; so the descriptors can now reference 4Gb of memory, with size extensions
76 ; read in the second half of this stage of the bootloader
77 xor dx,dx ; start at head 0
78 mov bx,0x2 ; start at sector 2 for the second half of this loader
80 mov edi,0x7e00 ; right after this one
84 ; read in the rest of the disk
85 mov edi,0x100000 ; destination buffer (at 1 MB) for sector reading in load_floppy
86 mov bx,0x3 ; start at sector 3 (and cylinder 0)
87 mov cx,[sectors
] ; read that much sectors
88 xor dx,dx ; start at head 0
92 call load_floppy
; read remaining sectors at address edi
93 call disable_floppy_motor
98 ; uncomment the next line to enable the VESA mode switch
102 call find_mem_size_real
104 ; mov ebx,[dword 0x100074] ; load dword at rel. address 0x74 from read-destination-buffer
105 ; add ebx,0x101000 ; for stage2 entry
107 mov [ds:gdt
+14],al ; set desc. 1 and 2
108 mov [ds:gdt
+22],al ; to 32-bit segment
109 lgdt [ds:gdt
] ; load global descriptor table
112 mov cr0
,eax ; enter protected mode
113 jmp dword 0x8:code32
; flush prefetch queue
116 mov ax,0x10 ; load descriptor 2 in all segment selectors (except cs)
133 mov al,[ext_mem_count
]
137 mov eax,[ext_mem_info
]
144 push eax ; should be loaded with zero
148 call find_mem_size_probe
153 call ebx ; jump to stage1 entry
156 ; find memory size by testing
157 ; OUT: eax = memory size
159 mov eax,0x31323738 ; test value
160 mov esi,0x100ff0 ; start above conventional mem + HMA = 1 MB + 1024 Byte
162 mov edx,[esi] ; read value
163 mov [esi],eax ; write test value
164 mov ecx,[esi] ; read it again
165 mov [esi],edx ; write back old value
167 jnz _fms_loop_out
; read value != test value -> above mem limit
168 add esi,0x1000 ; test next page (4 K)
177 ; read sectors into memory
178 ; IN: bx = sector # to start with: should be 2 as sector 1 (bootsector) was read by BIOS
179 ; cx = # of sectors to read
185 mov al,0x13 ; read a maximum of 18 sectors
186 sub al,bl ; substract first sector (to prevent wrap-around ???)
188 xor ah,ah ; TK: don't read more then required, VMWare doesn't like that
194 mov cx,bx ; -> sector/cylinder # to read from
195 mov bx,0x8000 ; buffer address
196 mov ah,0x2 ; command 'read sectors'
199 pop ax ; TK: should return number of transferred sectors in al
200 ; but VMWare 3 clobbers it, so we (re-)load al manually
201 jnc okok
; no error -> proceed as usual
204 xor ah,ah ; reset disk controller
208 mov byte [retrycnt
], 3 ; reload retrycnt
211 mov esi,0x8000 ; source
213 mov cl,al ; copy # of read sectors (al)
214 shl cx,0x7 ; of size 128*4 bytes
215 rep a32
movsd ; to destination (edi) setup before func3 was called
218 xor dh,0x1 ; read: next head
220 inc bh ; read: next cylinder
222 mov bl,0x1 ; read: sector 1
224 sub cx,ax ; substract # of read sectors
225 jg load_floppy
; sectors left to read ?
228 disable_floppy_motor:
230 mov dx,0x3f2 ; disable floppy motor
234 ; prints message in reg. si
249 ; print errormsg, wait for keypress and reboot
257 ; enables the a20 gate
258 ; the usual keyboard-enable-a20-gate-stuff
279 loadmsg
db "Loading",0
280 errormsg
db 0x0a,0x0d,"Error reading disk.",0x0a,0x0d,0
281 okmsg
db "OK",0x0a,0x0d,0
284 ; the first entry serves 2 purposes: as the GDT header and as the first descriptor
285 ; note that the first descriptor (descriptor 0) is always a NULL-descriptor
286 db 0xFF ; full size of GDT used
287 db 0xff ; which means 8192 descriptors * 8 bytes = 2^16 bytes
288 dw gdt
; address of GDT (dword)
291 dd 0x0000ffff ; base - limit: 0 - 0xfffff * 4K
292 dd 0x008f9a00 ; type: 16 bit, exec-only conforming, <present>, privilege 0
294 dd 0x0000ffff ; base - limit: 0 - 0xfffff * 4K
295 dd 0x008f9200 ; type: 16 bit, data read/write, <present>, privilege 0
303 times
510-($
-$$
) db 0 ; filler for boot sector
304 dw 0xaa55 ; magic number for boot sector
306 ; Starting here is the second sector of the boot code
310 ; use int 0x15, EAX=0xe820 to test for memory
314 mov edi,0x7000 ; the extended memory structures will go at 0x7000
315 mov [ext_mem_info
],edi
319 mov edx,'PAMS' ; 'SMAP' in the correct order
323 jc done_mem_real
; if carry is set, it wasn't supported
325 inc byte [ext_mem_count
] ; increment the count of the number
327 cmp ebx,0x0 ; test if we're done
330 add edi,0x20 ; increment the buffer by 0x20
336 ; fool around with vesa mode
338 ; put the VBEInfo struct at 0x30000
347 ; check the return code
353 ; check the signature on the data structure
355 cmp eax,0x41534556 ; 'VESA'
357 cmp eax,0x32454256 ; 'VBE2'
361 ; scan through each mode and grab the info on them
362 les bx,[es:14] ; calculate the pointer to the mode list
363 mov di,0x200 ; push the buffer up a little to be past the VBEInfo struct
366 mov cx,[es:bx] ; grab the next mode in the list
373 ; if it's 1024x768x32, go for it
375 test ax,0x1 ; test the supported bit
377 test ax,0x08 ; test the linear frame mode bit
380 cmp ax,VESA_X_TARGET
; x
383 cmp ax,VESA_Y_TARGET
; y
386 cmp al,VESA_BIT_DEPTH_TARGET
; bit_depth
389 ; looks good, switch into it
392 or bx,0x4000 ; add the linear mode bit
397 ; get ready to try the next mode
410 times
1024-($
-$$
) db 0 ; filler for second sector of the loader