diff options
Diffstat (limited to 'private/ntos/boot/bootcode/fat')
-rw-r--r-- | private/ntos/boot/bootcode/fat/i386/fatboot.asm | 426 | ||||
-rw-r--r-- | private/ntos/boot/bootcode/fat/i386/usa/bootfat.h | 37 | ||||
-rw-r--r-- | private/ntos/boot/bootcode/fat/i386/usa/fatboot.inc | 28 |
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 |