Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

434 lines
9.6 KiB

;++
;
;Copyright (c) 1995 Microsoft Corporation
;
;Module Name:
;
; bioschk.asm
;
;Abstract:
;
; The code in this "image" is responsible for checking if is appropriate
; for us to start setupldr.bin. We consider this appropriate when we pass
; BIOS checkings. Setupldr.bin is binary appended at the end of this image.
;
;Author:
;
; Calin Negreanu (calinn) 16-Dec-1999
;
;Environment:
;
; Real mode
; Case 1:
; Complete image has been loaded at 2000:0000 by the boot code
; DL = meaningfull data
; Case 2:
; First 512 bytes of this image has been loaded at 2000:000 by the boot code
; BX = meaningfull data
; DL = meaningfull data
; DS:SI -> points to a structure containing meaningfull data
; DS:DI -> points to a structure containing meaningfull data
;
;Revision History:
;
;--
page ,132
title boot - BIOS check
name bioschk
.8086
CODE SEGMENT
ASSUME CS:CODE,DS:CODE,SS:NOTHING,ES:NOTHING
ORG 0000H
_BiosChk label byte
BiosChkDestSeg EQU 1000h
SetupLdrDestSeg EQU 2000h
MaxCodeSize EQU 0800h ;number of paragraphs (32k)
MaxSetupLdrSize EQU 4000h ;number of paragraphs (256k)
StackSeg EQU 1000h ;stack goes from here
MAXREAD EQU 10000h
MAXSECTORS EQU MAXREAD/0200h
DoubleWord struc
lsw dw ?
msw dw ?
DoubleWord ends
SHARED struc
ReadClusters dd ?
ReadSectors dd ?
SectorBase dd ?
SHARED ends
BPB struc
BytesPerSector dw ?
SectorsPerCluster db ?
ReservedSectors dw ?
Fats db ?
DirectoryEntries dw ?
Sectors dw ?
Media db ?
FatSectors dw ?
SectorsPerTrack dw ?
Heads dw ?
HiddenSectors dd ?
SectorsLong dd ?
BootDriveNumber db ?
BPB ends
JMPFAR MACRO DestOfs,DestSeg
db 0eah
dw OFFSET DestOfs
dw DestSeg
endm
START:
; If we boot from FAT drives, the next instruction is not executed.
jmp RealStart
FatBegin:
.386
;
; If we're here, we've booted off a FAT system and we must load the rest
; of the binary image at 2000:0200 (right behind this sector).
;
;
; Save away meaningfull data
;
push dx
push bx
.386
push 06000h
.8086
pop es
xor bx,bx
mov cx,ds:[si].ReservedSectors
mov ds:[di].SectorBase.msw,0
mov ds:[di].SectorBase.lsw,cx
mov ax,ds:[si].FatSectors
cmp ax,080h
jbe FatLt64k
push cx
mov ax,080h
call ds:[di].ReadSectors
pop cx
.386
push 07000h
.8086
pop es
xor bx,bx
mov ax,ds:[si].FatSectors
sub ax,080h
add cx,080h
mov ds:[di].SectorBase.lsw,cx
adc ds:[di].SectorBase.msw,0
FatLt64k:
call ds:[di].ReadSectors
pop dx
xor bx,bx
.386
mov ax,6000h
mov fs,ax
mov ax,7000h
mov gs,ax
.8086
push cs
pop es
mov ah,MAXSECTORS
FatLoop:
push dx
mov al,ds:[si].SectorsPerCluster
sub ah,ds:[si].SectorsPerCluster
cmp dx,0ffffh
jne Fat10
pop dx
pop dx
jmp RealStart
Fat10:
mov cx,dx
call NextFatEntry
inc cx
cmp dx,cx
jne LncLoad
cmp ah,0
jne Lnc20
mov ah,MAXSECTORS
jmp short LncLoad
Lnc20:
add al,ds:[si].SectorsPerCluster
sub ah,ds:[si].SectorsPerCluster
jmp short Fat10
LncLoad:
pop cx
push dx
mov dx,cx
mov cx,10
FatRetry:
push bx
push ax
push dx
push cx
call [di].ReadClusters
jnc ReadOk
mov ax,01h
mov al,ds:[si].BootDriveNumber
int 13h
xor ax,ax
mov al,ds:[si].BootDriveNumber
int 13h
xor ax,ax
FatPause:
dec ax
jnz FatPause
pop cx
pop dx
pop ax
pop bx
dec cx
jnz FatRetry
push cs
pop ds
mov si,offset FAT_ERROR
FatErrPrint:
lodsb
or al,al
jz FatErrDone
mov ah,14
mov bx,7
int 10h
jmp FatErrPrint
FatErrDone:
jmp $
FAT_ERROR db 13,10,"Disk I/O error",0dh,0ah,0
ReadOk:
pop cx
pop dx
pop ax
pop bx
pop dx
.386
mov cl,al
xor ch,ch
shl cx,9
.8086
add bx,cx
jz FatLoopDone
jmp FatLoop
FatLoopDone:
mov ax,es
add ax,01000h
mov es,ax
mov ah,MAXSECTORS
jmp FatLoop
NextFatEntry proc near
push bx
call IsFat12
jnc Next16Fat
Next12Fat:
mov bx,dx
shr dx,1
pushf
add bx,dx
.386
mov dx,fs:[bx]
.8086
popf
jc shift
and dx,0fffh
jmp short N12Tail
shift:
.386
shr dx,4
.8086
N12Tail:
cmp dx,0ff8h
jb NfeDone
mov dx,0ffffh
jmp short NfeDone
Next16Fat:
add dx,dx
jc N16high
mov bx,dx
.386
mov dx,fs:[bx]
.8086
jmp short N16Tail
N16high:
mov bx,dx
.386
mov dx,gs:[bx]
.8086
N16Tail:
cmp dx,0fff8h
jb NfeDone
mov dx,0ffffh
NfeDone:
pop bx
ret
NextFatEntry endp
IsFat12 proc near
.386
push eax
push ebx
push ecx
push edx
movzx ecx, ds:[si].Sectors
or cx,cx
jnz if10
mov ecx, ds:[si].SectorsLong
if10:
movzx ebx, byte ptr ds:[si].Fats
movzx eax, word ptr ds:[si].FatSectors
mul ebx
sub ecx,eax
movzx eax, word ptr ds:[si].DirectoryEntries
shl eax, 5
mov edx,eax
and edx,0ffff0000h
div word ptr ds:[si].BytesPerSector
sub ecx,eax
movzx eax, word ptr ds:[si].ReservedSectors
sub ecx, eax
mov eax, ecx
movzx ecx, byte ptr ds:[si].SectorsPerCluster
xor edx,edx
div ecx
cmp eax, 4087
jae if20
stc
jmp short if30
if20:
clc
if30:
pop edx
pop ecx
pop ebx
pop eax
ret
.8086
IsFat12 endp
Free EQU 512-($-Start)
if Free lt 0
%out FATAL PROBLEM: FAT-specific startup code is greater than
%out 512 bytes. Fix it!
.err
endif
RealStart:
;
; we are completely done with the boot sector, we can party on it's memory as we like.
; set up the stack
;
mov ax,StackSeg
mov ss,ax
xor sp,sp
mov ax,cs
mov ds,ax
mov es,ax
;
; save setupldr data
;
mov Preserve, dl
; move ourselves from 2000:0000 to 1000:0000, one paragraph at a time.
mov ax, BiosChkDestSeg
mov es, ax
mov dx, MaxCodeSize
cld
Again1:
xor di, di
xor si, si
mov cx, 10h
rep movsb
mov ax, ds
inc ax
mov ds, ax
mov ax, es
inc ax
mov es, ax
dec dx
jnz Again1
mov ax, BiosChkDestSeg
mov ds, ax
mov es, ax
JMPFAR Continue1, BiosChkDestSeg
Continue1:
; insert your BIOS check code here
; instead of a real BIOS check we will check if the user holds down CTRL.
; If yes, we will behave like BIOS check failed
mov ah,02h
int 16h
and al,00000100b
jz MoveSetupLdr
; at this point, the BIOS check failed. You can add whatever code you want here
; to give a message or to make the computer crash. If you don't do anything, the
; code will jump to 2000:0000 so an infinite loop is going to happen.
jmp Continue2
MoveSetupLdr:
; move Setupldr code from 2000+MaxCodeSize:0000 to 2000:0000, one paragraph at a time.
push ds
push es
mov ax, SetupLdrDestSeg
mov es, ax
add ax, MaxCodeSize
mov ds, ax
mov dx, MaxSetupLdrSize
cld
Again2:
xor di, di
xor si, si
mov cx, 10h
rep movsb
mov ax, ds
inc ax
mov ds, ax
mov ax, es
inc ax
mov es, ax
dec dx
jnz Again2
pop es
pop ds
Continue2:
mov dl, Preserve
JMPFAR 0,SetupLdrDestSeg
Preserve db ?
.errnz ($-_BiosChk) GT (MaxCodeSize*16 - 2) ;FATAL: BiosChk code is too large
org MaxCodeSize*16 - 2
db 55h,0aah
CODE ENDS
END START