summaryrefslogtreecommitdiffstats
path: root/private/ntos/boot/bootcode/fat/i386
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/boot/bootcode/fat/i386')
-rw-r--r--private/ntos/boot/bootcode/fat/i386/fatboot.asm426
-rw-r--r--private/ntos/boot/bootcode/fat/i386/usa/bootfat.h37
-rw-r--r--private/ntos/boot/bootcode/fat/i386/usa/fatboot.inc28
3 files changed, 491 insertions, 0 deletions
diff --git a/private/ntos/boot/bootcode/fat/i386/fatboot.asm b/private/ntos/boot/bootcode/fat/i386/fatboot.asm
new file mode 100644
index 000000000..b349538bd
--- /dev/null
+++ b/private/ntos/boot/bootcode/fat/i386/fatboot.asm
@@ -0,0 +1,426 @@
+;++
+;
+;Copyright (c) 1991 Microsoft Corporation
+;
+;Module Name:
+;
+; fatboot.asm
+;
+;Abstract:
+;
+; The ROM in the IBM PC starts the boot process by performing a hardware
+; initialization and a verification of all external devices. If all goes
+; well, it will then load from the boot drive the sector from track 0, head 0,
+; sector 1. This sector is placed at physical address 07C00h.
+;
+; The code in this sector is responsible for locating NTLDR, loading the
+; first sector of NTLDR into memory at 2000:0000, and branching to it. The
+; first sector of NTLDR is special code which knows enough about FAT and
+; BIOS to load the rest of NTLDR into memory.
+;
+; There are only two errors possible during execution of this code.
+; 1 - NTLDR does not exist
+; 2 - BIOS read error
+;
+; In both cases, a short message is printed, and the user is prompted to
+; reboot the system.
+;
+; At the beginning of the boot sector, there is a table which describes the
+; structure of the media. This is equivalent to the BPB with some
+; additional information describing the physical layout of the driver (heads,
+; tracks, sectors)
+;
+;
+;Author:
+;
+; John Vert (jvert) 31-Aug-1991
+;
+;Environment:
+;
+; Sector has been loaded at 7C0:0000 by BIOS.
+; Real mode
+; FAT file system
+;
+;Revision History:
+;
+;--
+ page ,132
+ title boot - NTLDR FAT loader
+ name fatboot
+
+DIR_ENT struc
+ Filename db 11 dup(?)
+ Attribute db ?
+ Reserved db 10 dup(?)
+ Time dw 2 dup(?)
+ StartCluster dw ?
+ FileSize dd ?
+DIR_ENT ends
+
+;
+; This is the structure used to pass all shared data between the boot sector
+; and NTLDR.
+;
+
+SHARED struc
+ ReadClusters dd ? ; function pointer
+ ReadSectors dd ? ; function pointer
+ SectorBase dd ? ; starting sector
+SHARED ends
+
+
+
+DoubleWord struc
+lsw dw ?
+msw dw ?
+DoubleWord ends
+
+SectorSize equ 512 ; sector size
+
+BootSeg segment at 07c0h
+BootSeg ends
+
+DirSeg segment at 1000h
+DirSeg ends
+
+NtLdrSeg segment at 2000h
+NtLdrSeg ends
+
+BootCode segment ;would like to use BootSeg here, but LINK flips its lid
+ ASSUME CS:BootCode,DS:NOTHING,ES:NOTHING,SS:NOTHING
+
+ public FATBOOT
+FATBOOT proc far
+
+ jmp Start
+
+;
+; THE FOLLOWING DATA CONFIGURES THE BOOT PROGRAM
+; FOR ANY TYPE OF DRIVE OR HARDFILE
+;
+; Note that this data is just a place-holder here. The actual values will
+; be filled in by FORMAT or SYS. When installing the boot sector, only the
+; code following the BPB (from Start to the end) should be copied into the
+; first sector.
+;
+
+Version db "MSDOS5.0"
+BPB label byte
+BytesPerSector dw SectorSize ; Size of a physical sector
+SectorsPerCluster db 8 ; Sectors per allocation unit
+ReservedSectors dw 1 ; Number of reserved sectors
+Fats db 2 ; Number of fats
+DirectoryEntries dw 512 ; Number of directory entries
+Sectors dw 4*17*305-1 ; No. of sectors - no. of hidden sectors
+Media db 0F8H ; Media byte
+FatSectors dw 8 ; Number of fat sectors
+SectorsPerTrack dw 17 ; Sectors per track
+Heads dw 4 ; Number of surfaces
+HiddenSectors dd 1 ; Number of hidden sectors
+SectorsLong dd 0 ; Number of sectors iff Sectors = 0
+
+;
+; The following byte is NOT part of the BPB but is set by SYS and format
+; We should NOT change its position.
+;
+
+; keep order of DriveNumber and CurrentHead!
+DriveNumber db 80h ; Physical drive number (0 or 80h)
+CurrentHead db ? ; Unitialized
+
+Signature db 41 ; Signature Byte for bootsector
+BootID dd ? ; Boot ID field.
+Boot_Vol_Label db 11 dup (?)
+Boot_System_ID db 'FAT ' ;"FAT " or "OTHER_FS"
+
+
+Start:
+ xor ax,ax ; Setup the stack to a known good spot
+ mov ss,ax
+ mov sp,7c00h
+
+.386
+ push BootSeg
+.8086
+ pop ds
+assume DS:BootCode
+
+; The system is now prepared for us to begin reading. First, determine
+; logical sector numbers of the start of the directory and the start of the
+; data area.
+;
+ MOV AL,Fats ;Determine sector root directory starts on
+ MUL FatSectors
+;##### what if result > 65535 ?????
+ ADD AX,ReservedSectors
+;##### what if result > 65535 ?????
+ PUSH AX ; AX = Fats*FatSectors + ReservedSectors + HiddenSectors
+ XCHG CX,AX ; (CX) = start of DIR
+;
+; Take into account size of directory (only know number of directory entries)
+;
+ MOV AX,size DIR_ENT ; bytes per directory entry
+ MUL DirectoryEntries ; convert to bytes in directory
+ MOV BX,BytesPerSector ; add in sector size
+ ADD AX,BX
+ DEC AX ; decrement so that we round up
+ DIV BX ; convert to sector number
+ ADD CX,AX
+ MOV ClusterBase,CX ; save it for later
+;
+; Load in the root directory.
+;
+.386
+ push DirSeg ; es:bx -> directory segment
+.8086
+ pop es
+ASSUME ES:DirSeg
+ xor bx,bx
+ pop Arguments.SectorBase.lsw
+ mov Arguments.SectorBase.msw,bx
+
+;
+; DoRead does a RETF, but LINK pukes if we do a FAR call in a /tiny program.
+;
+; (al) = # of sectors to read
+;
+ push cs
+ call DoRead
+ jc BootErr$he
+
+; Now we scan for the presence of NTLDR
+
+ xor bx,bx
+ mov cx,DirectoryEntries
+L10:
+ mov di,bx
+ push cx
+ mov cx,11
+ mov si, offset LOADERNAME
+ repe cmpsb
+ pop cx
+ jz L10end
+
+ add bx,size DIR_ENT
+ loop L10
+L10end:
+
+ jcxz BootErr$bnf
+
+ mov dx,es:[bx].StartCluster ; (dx) = starting cluster number
+ push dx
+ mov ax,1 ; (al) = sectors to read
+;
+; Now, go read the file
+;
+
+.386
+ push NtLdrSeg
+.8086
+ pop es
+ ASSUME ES:NtLdrSeg
+ xor bx,bx ; (es:bx) -> start of NTLDR
+
+
+;
+; LINK barfs if we do a FAR call in a TINY program, so we have to fake it
+; out by pushing CS.
+;
+
+ push cs
+ call ClusterRead
+ jc BootErr$he
+
+;
+; NTLDR requires:
+; BX = Starting Cluster Number of NTLDR
+; DL = INT 13 drive number we booted from
+; DS:SI -> the boot media's BPB
+; DS:DI -> argument structure
+; 1000:0000 - entire FAT is loaded
+;
+
+ pop BX ; (bx) = Starting Cluster Number
+ lea si,BPB ; ds:si -> BPB
+ lea di,Arguments ; ds:di -> Arguments
+
+ push ds
+ pop [di].ReadClusters.msw
+ mov [di].ReadClusters.lsw, offset ClusterRead
+ push ds
+ pop [di].ReadSectors.msw
+ mov [di].ReadSectors.lsw, offset DoRead
+ MOV dl,DriveNumber ; dl = boot drive
+
+;
+; FAR JMP to 2000:0003. This is hand-coded, because I can't figure out
+; how to make MASM do this for me. By entering NTLDR here, we skip the
+; initial jump and execute the FAT-specific code to load the rest of
+; NTLDR.
+;
+ db 0EAh ; JMP FAR PTR
+ dw 3 ; 2000:3
+ dw 02000h
+FATBOOT endp
+
+; BootErr - print error message and hang the system.
+;
+BootErr proc
+BootErr$bnf:
+ MOV SI,OFFSET MSG_NO_NTLDR
+ jmp short BootErr2
+BootErr$he:
+ MOV SI,OFFSET MSG_READ_ERROR
+BootErr2:
+ call BootErrPrint
+ MOV SI,OFFSET MSG_REBOOT_ERROR
+ call BootErrPrint
+ sti
+ jmp $ ;Wait forever
+
+BootErrPrint:
+ LODSB ; Get next character
+ or al,al
+ jz BEdone
+
+ MOV AH,14 ; Write teletype
+ MOV BX,7 ; Attribute
+ INT 10H ; Print it
+ jmp BootErrPrint
+BEdone:
+
+ ret
+BootErr endp
+
+; ClusterRead - read AL sectors into ES:BX starting from
+; cluster DX
+;
+ClusterRead proc
+ push ax ; (TOS) = # of sectors to read
+ dec dx
+ dec dx ; adjust for reserved clusters 0 and 1
+ mov al,SectorsPerCluster
+ xor ah,ah
+ mul dx ; DX:AX = starting sector number
+ add ax,ClusterBase ; adjust for FATs, root dir, boot sec.
+ adc dx,0
+ mov Arguments.SectorBase.lsw,ax
+ mov Arguments.SectorBase.msw,dx
+ pop ax ; (al) = # of sectors to read
+
+;
+; Now we've converted the cluster number to a SectorBase, so just fall
+; through into DoRead
+;
+
+ClusterRead endp
+
+
+;
+; DoRead - read AL sectors into ES:BX starting from sector
+; SectorBase.
+;
+DoRead proc
+
+ mov SectorCount,AL
+DRloop:
+ MOV AX,Arguments.SectorBase.lsw ; Starting sector
+ MOV DX,Arguments.SectorBase.msw ; Starting sector
+;
+; DoDiv - convert logical sector number in AX to physical Head/Track/Sector
+; in CurrentHead/CurrentTrack/CurrentSector.
+;
+ ADD AX,HiddenSectors.lsw ;adjust for partition's base sector
+ ADC DX,HiddenSectors.msw
+ DIV SectorsPerTrack
+ INC DL ; sector numbers are 1-based
+ MOV CurrentSector,DL
+ XOR DX,DX
+ DIV Heads
+ MOV CurrentHead,DL
+ MOV CurrentTrack,AX
+;
+;DoDiv endp
+;
+
+
+; CurrentHead is the head for this next disk request
+; CurrentTrack is the track for this next request
+; CurrentSector is the beginning sector number for this request
+
+; Compute the number of sectors that we may be able to read in a single ROM
+; request.
+
+ MOV AX,SectorsPerTrack
+ SUB AL,CurrentSector
+ INC AX
+ cmp al,SectorCount
+ jbe DoCall
+ mov al,SectorCount
+ xor ah,ah
+
+; AX is the number of sectors that we may read.
+
+;
+; DoCall - call ROM BIOS to read AL sectors into ES:BX.
+;
+DoCall:
+ PUSH AX
+ MOV AH,2
+ MOV cx,CurrentTrack
+.386
+ SHL ch,6
+.8086
+ OR ch,CurrentSector
+ XCHG CH,CL
+ MOV DX,WORD PTR DriveNumber
+ INT 13H
+;
+;DoCall endp
+;
+
+.386
+ jnc DcNoErr
+ add sp,2
+ stc
+ retf
+.8086
+
+DcNoErr:
+ POP AX
+ SUB SectorCount,AL ; Are we finished?
+ jbe DRdone
+ ADD Arguments.SectorBase.lsw,AX ; increment logical sector position
+ ADC Arguments.SectorBase.msw,0
+ MUL BytesPerSector ; determine next offset for read
+ ADD BX,AX ; (BX)=(BX)+(SI)*(Bytes per sector)
+
+ jmp DRloop
+DRdone:
+ mov SectorCount,al
+ clc
+ retf
+DoRead endp
+
+ include fatboot.inc ;suck in the message text
+
+LOADERNAME DB "NTLDR "
+
+ .errnz ($-FATBOOT) GT 510,<FATAL PROBLEM: boot sector is too large>
+
+ org 510
+ db 55h,0aah
+
+BootSectorEnd label dword
+
+BootCode ends
+
+;Unitialized variables go here--beyond the end of the boot sector in free memory
+CurrentTrack equ word ptr BootSectorEnd + 4 ; current track
+CurrentSector equ byte ptr BootSectorEnd + 6 ; current sector
+SectorCount equ byte ptr BootSectorEnd + 7 ; number of sectors to read
+ClusterBase equ word ptr BootSectorEnd + 8 ; first sector of cluster # 2
+Retries equ byte ptr BootSectorEnd + 10
+Arguments equ byte ptr BootSectorEnd + 11 ; structure passed to NTLDR
+
+ END FATBOOT
diff --git a/private/ntos/boot/bootcode/fat/i386/usa/bootfat.h b/private/ntos/boot/bootcode/fat/i386/usa/bootfat.h
new file mode 100644
index 000000000..9ccbd1a4a
--- /dev/null
+++ b/private/ntos/boot/bootcode/fat/i386/usa/bootfat.h
@@ -0,0 +1,37 @@
+#define FATBOOTCODE_SIZE 512
+
+
+unsigned char FatBootCode[] = {
+235,60,144,77,83,68,79,83,53,46,48,0,2,8,1,0,
+2,0,2,3,81,248,8,0,17,0,4,0,1,0,0,0,
+0,0,0,0,128,0,41,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,70,65,84,32,32,32,32,32,51,192,
+142,208,188,0,124,104,192,7,31,160,16,0,247,38,22,0,
+3,6,14,0,80,145,184,32,0,247,38,17,0,139,30,11,
+0,3,195,72,247,243,3,200,137,14,8,2,104,0,16,7,
+51,219,143,6,19,2,137,30,21,2,14,232,144,0,114,87,
+51,219,139,14,17,0,139,251,81,185,11,0,190,220,1,243,
+166,89,116,5,131,195,32,226,237,227,55,38,139,87,26,82,
+184,1,0,104,0,32,7,51,219,14,232,72,0,114,40,91,
+141,54,11,0,141,62,11,2,30,143,69,2,199,5,245,0,
+30,143,69,6,199,69,4,14,1,138,22,36,0,234,3,0,
+0,32,190,134,1,235,3,190,162,1,232,9,0,190,193,1,
+232,3,0,251,235,254,172,10,192,116,9,180,14,187,7,0,
+205,16,235,242,195,80,74,74,160,13,0,50,228,247,226,3,
+6,8,2,131,210,0,163,19,2,137,22,21,2,88,162,7,
+2,161,19,2,139,22,21,2,3,6,28,0,19,22,30,0,
+247,54,24,0,254,194,136,22,6,2,51,210,247,54,26,0,
+136,22,37,0,163,4,2,161,24,0,42,6,6,2,64,58,
+6,7,2,118,5,160,7,2,50,228,80,180,2,139,14,4,
+2,192,229,6,10,46,6,2,134,233,139,22,36,0,205,19,
+15,131,5,0,131,196,2,249,203,88,40,6,7,2,118,17,
+1,6,19,2,131,22,21,2,0,247,38,11,0,3,216,235,
+144,162,7,2,248,203,66,79,79,84,58,32,67,111,117,108,
+100,110,39,116,32,102,105,110,100,32,78,84,76,68,82,13,
+10,0,66,79,79,84,58,32,73,47,79,32,101,114,114,111,
+114,32,114,101,97,100,105,110,103,32,100,105,115,107,13,10,
+0,80,108,101,97,115,101,32,105,110,115,101,114,116,32,97,
+110,111,116,104,101,114,32,100,105,115,107,0,78,84,76,68,
+82,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,85,170
+};
diff --git a/private/ntos/boot/bootcode/fat/i386/usa/fatboot.inc b/private/ntos/boot/bootcode/fat/i386/usa/fatboot.inc
new file mode 100644
index 000000000..5ef7d5185
--- /dev/null
+++ b/private/ntos/boot/bootcode/fat/i386/usa/fatboot.inc
@@ -0,0 +1,28 @@
+;++
+;
+;Copyright (c) 1991 Microsoft Corporation
+;
+;Module Name:
+;
+; fatboot.inc
+;
+;Abstract:
+;
+; This contains the message text that the boot sector prints out on
+; error conditions
+;
+;Author:
+;
+; John Vert (jvert) 31-Aug-1991
+;
+;Revision History:
+;
+;--
+
+MSG_NO_NTLDR db "BOOT: Couldn't find NTLDR"
+ db 0dh, 0ah, 0
+MSG_READ_ERROR db "BOOT: I/O error reading disk"
+ db 0dh, 0ah, 0
+MSG_REBOOT_ERROR db "Please insert another disk"
+ db 0
+ \ No newline at end of file