diff --git a/reactos/boot/freeldr/bootsect/fat.S b/reactos/boot/freeldr/bootsect/fat.S index 913c50dfff7..c589a20b86c 100644 --- a/reactos/boot/freeldr/bootsect/fat.S +++ b/reactos/boot/freeldr/bootsect/fat.S @@ -43,15 +43,15 @@ #define BP_REL(x) [bp+x-offset start] -DataAreaStartHigh = 2 -DataAreaStartLow = 4 -BiosCHSDriveSizeHigh = 6 -BiosCHSDriveSizeLow = 8 -BiosCHSDriveSize = 8 -ReadSectorsOffset = 10 -ReadClusterOffset = 12 -PutCharsOffset = 14 -BootSectorStackTop = HEX(7c00) - 16 +DataAreaStartHigh = 2 +DataAreaStartLow = 4 +BiosCHSDriveSizeHigh = 6 +BiosCHSDriveSizeLow = 8 +BiosCHSDriveSize = 8 +ReadSectorsOffset = 10 +ReadClusterOffset = 12 +PutCharsOffset = 14 +BootSectorStackTop = HEX(7c00) - 16 // org 7c00h @@ -105,21 +105,21 @@ main: xor ax, ax mov ss, ax mov bp, HEX(7c00) - mov sp, BootSectorStackTop // Setup a stack - mov ds, ax // Make DS correct - mov es, ax // Make ES correct + mov sp, BootSectorStackTop // Setup a stack + mov ds, ax // Make DS correct + mov es, ax // Make ES correct - cmp byte ptr BP_REL(BootDrive), HEX(0ff) // If they have specified a boot drive then use it + cmp byte ptr BP_REL(BootDrive), HEX(0ff) // If they have specified a boot drive then use it jne GetDriveParameters - mov byte ptr BP_REL(BootDrive), dl // Save the boot drive + mov byte ptr BP_REL(BootDrive), dl // Save the boot drive GetDriveParameters: mov ah, 8 - mov dl, byte ptr BP_REL(BootDrive) // Get boot drive in dl - int HEX(13) // Request drive parameters from the bios - jnc CalcDriveSize // If the call succeeded then calculate the drive size + mov dl, byte ptr BP_REL(BootDrive) // Get boot drive in dl + int HEX(13) // Request drive parameters from the bios + jnc CalcDriveSize // If the call succeeded then calculate the drive size // If we get here then the call to the BIOS failed // so just set CHS equal to the maximum addressable @@ -151,26 +151,26 @@ CalcDriveSize: // Now we must find our way to the first sector of the root directory xor ax, ax xor cx, cx - mov al, byte ptr BP_REL(NumberOfFats) // Number of fats - mul word ptr BP_REL(SectorsPerFat) // Times sectors per fat + mov al, byte ptr BP_REL(NumberOfFats) // Number of fats + mul word ptr BP_REL(SectorsPerFat) // Times sectors per fat add ax, word ptr BP_REL(HiddenSectors) adc dx, word ptr BP_REL(HiddenSectors+2) // Add the number of hidden sectors - add ax, word ptr BP_REL(ReservedSectors) // Add the number of reserved sectors - adc dx, cx // Add carry bit - mov word ptr [bp - DataAreaStartLow], ax // Save the starting sector of the root directory - mov word ptr [bp - DataAreaStartHigh], dx // Save it in the first 4 bytes before the boot sector - mov si, word ptr BP_REL(MaxRootEntries) // Get number of root dir entries in SI - pusha // Save 32-bit logical start sector of root dir + add ax, word ptr BP_REL(ReservedSectors) // Add the number of reserved sectors + adc dx, cx // Add carry bit + mov word ptr [bp - DataAreaStartLow], ax // Save the starting sector of the root directory + mov word ptr [bp - DataAreaStartHigh], dx // Save it in the first 4 bytes before the boot sector + mov si, word ptr BP_REL(MaxRootEntries) // Get number of root dir entries in SI + pusha // Save 32-bit logical start sector of root dir // DX:AX now has the number of the starting sector of the root directory // Now calculate the size of the root directory xor dx, dx - mov ax, 32 // Size of dir entry - mul si // Times the number of entries + mov ax, 32 // Size of dir entry + mul si // Times the number of entries mov bx, word ptr BP_REL(BytesPerSector) add ax, bx dec ax - div bx // Divided by the size of a sector + div bx // Divided by the size of a sector // AX now has the number of root directory sectors add word ptr [bp - DataAreaStartLow], ax // Add the number of sectors of the root directory to our other value @@ -178,49 +178,49 @@ CalcDriveSize: popa // Restore root dir logical sector start to DX:AX LoadRootDirSector: - mov bx, HEX(7e0) // We will load the root directory sector - mov es, bx // Right after the boot sector in memory - xor bx, bx // We will load it to [0000:7e00h] - xor cx, cx // Zero out CX - inc cx // Now increment it to 1, we are reading one sector - xor di, di // Zero out di - push es // Save ES because it will get incremented by 20h - call ReadSectors // Read the first sector of the root directory - pop es // Restore ES (ES:DI = 07E0:0000) + mov bx, HEX(7e0) // We will load the root directory sector + mov es, bx // Right after the boot sector in memory + xor bx, bx // We will load it to [0000:7e00h] + xor cx, cx // Zero out CX + inc cx // Now increment it to 1, we are reading one sector + xor di, di // Zero out di + push es // Save ES because it will get incremented by 20h + call ReadSectors // Read the first sector of the root directory + pop es // Restore ES (ES:DI = 07E0:0000) SearchRootDirSector: - cmp byte ptr es:[di], ch // If the first byte of the directory entry is zero then we have - jz ErrBoot // reached the end of the directory and FREELDR.SYS is not here so reboot - pusha // Save all registers - mov cl, 11 // Put 11 in cl (length of filename in directory entry) - mov si, offset filename // Put offset of filename string in DS:SI - repe cmpsb // Compare this directory entry against 'FREELDR SYS' - popa // Restore all the registers - jz FoundFreeLoader // If we found it then jump - dec si // SI holds MaxRootEntries, subtract one - jz ErrBoot // If we are out of root dir entries then reboot - add di, 32 // Increment DI by the size of a directory entry - cmp di, HEX(0200) // Compare DI to 512 (DI has offset to next dir entry, make sure we haven't gone over one sector) - jc SearchRootDirSector // If DI is less than 512 loop again - jmp short LoadRootDirSector // Didn't find FREELDR.SYS in this directory sector, try again + cmp byte ptr es:[di], ch // If the first byte of the directory entry is zero then we have + jz ErrBoot // reached the end of the directory and FREELDR.SYS is not here so reboot + pusha // Save all registers + mov cl, 11 // Put 11 in cl (length of filename in directory entry) + mov si, offset filename // Put offset of filename string in DS:SI + repe cmpsb // Compare this directory entry against 'FREELDR SYS' + popa // Restore all the registers + jz FoundFreeLoader // If we found it then jump + dec si // SI holds MaxRootEntries, subtract one + jz ErrBoot // If we are out of root dir entries then reboot + add di, 32 // Increment DI by the size of a directory entry + cmp di, HEX(0200) // Compare DI to 512 (DI has offset to next dir entry, make sure we haven't gone over one sector) + jc SearchRootDirSector // If DI is less than 512 loop again + jmp short LoadRootDirSector // Didn't find FREELDR.SYS in this directory sector, try again FoundFreeLoader: // We found freeldr.sys on the disk // so we need to load the first 512 // bytes of it to 0000:F800 // ES:DI has dir entry (ES:DI == 07E0:XXXX) - mov ax, word ptr es:[di + HEX(1a)] // Get start cluster - push ax // Save start cluster - push FREELDR_BASE / 16 // Put load segment on the stack and load it - pop es // Into ES so that we load the cluster at 0000:F800 - call ReadCluster // Read the cluster - pop ax // Restore start cluster of FreeLoader + mov ax, word ptr es:[di + HEX(1a)] // Get start cluster + push ax // Save start cluster + push FREELDR_BASE / 16 // Put load segment on the stack and load it + pop es // Into ES so that we load the cluster at 0000:F800 + call ReadCluster // Read the cluster + pop ax // Restore start cluster of FreeLoader // Save the addresses of needed functions so // the helper code will know where to call them. - mov word ptr [bp-ReadSectorsOffset], offset ReadSectors // Save the address of ReadSectors - mov word ptr [bp-ReadClusterOffset], offset ReadCluster // Save the address of ReadCluster - mov word ptr [bp-PutCharsOffset], offset PutChars // Save the address of PutChars + mov word ptr [bp-ReadSectorsOffset], offset ReadSectors // Save the address of ReadSectors + mov word ptr [bp-ReadClusterOffset], offset ReadCluster // Save the address of ReadCluster + mov word ptr [bp-PutCharsOffset], offset PutChars // Save the address of PutChars // Now AX has start cluster of FreeLoader and we // have loaded the helper code in the first 512 bytes @@ -236,12 +236,12 @@ FoundFreeLoader: // Displays an error message // And reboots ErrBoot: - mov si, offset msgFreeLdr // FreeLdr not found message - call PutChars // Display it + mov si, offset msgFreeLdr // FreeLdr not found message + call PutChars // Display it Reboot: -// mov si, offset msgAnyKey // Press any key message -// call PutChars // Display it +// mov si, offset msgAnyKey // Press any key message +// call PutChars // Display it xor ax, ax int HEX(16) // Wait for a keypress int HEX(19) // Reboot @@ -260,8 +260,8 @@ Done: // Displays a bad boot message // And reboots BadBoot: - mov si, offset msgDiskError // Bad boot disk message - call PutChars // Display it + mov si, offset msgDiskError // Bad boot disk message + call PutChars // Display it jmp short Reboot @@ -269,17 +269,17 @@ BadBoot: // Reads cluster number in AX into [ES:0000] ReadCluster: // StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors; - dec ax // Adjust start cluster by 2 - dec ax // Because the data area starts on cluster 2 + dec ax // Adjust start cluster by 2 + dec ax // Because the data area starts on cluster 2 xor ch, ch mov cl, byte ptr BP_REL(SectsPerCluster) - mul cx // Times sectors per cluster - add ax, [bp-DataAreaStartLow] // Add start of data area - adc dx, [bp-DataAreaStartHigh] // Now we have DX:AX with the logical start sector of OSLOADER.SYS - xor bx, bx // We will load it to [ES:0000], ES loaded before function call - //mov cl,BYTE [BYTE bp+SectsPerCluster]// Sectors per cluster still in CX - //call ReadSectors - //ret + mul cx // Times sectors per cluster + add ax, [bp-DataAreaStartLow] // Add start of data area + adc dx, [bp-DataAreaStartHigh] // Now we have DX:AX with the logical start sector of FREELDR.SYS + xor bx, bx // We will load it to [ES:0000], ES loaded before function call +// mov cl,BYTE [BYTE bp+SectsPerCluster]// Sectors per cluster still in CX +// call ReadSectors +// ret @@ -296,63 +296,63 @@ ReadSectors: add ax, cx adc dx, 0 - cmp dx, word ptr [bp-BiosCHSDriveSizeHigh] // Check if they are reading a sector within CHS range - ja ReadSectorsLBA // No - go to the LBA routine - jb ReadSectorsCHS // Yes - go to the old CHS routine - cmp ax, word ptr [bp-BiosCHSDriveSizeLow] // Check if they are reading a sector within CHS range - jbe ReadSectorsCHS // Yes - go to the old CHS routine + cmp dx, word ptr [bp-BiosCHSDriveSizeHigh] // Check if they are reading a sector within CHS range + ja ReadSectorsLBA // No - go to the LBA routine + jb ReadSectorsCHS // Yes - go to the old CHS routine + cmp ax, word ptr [bp-BiosCHSDriveSizeLow] // Check if they are reading a sector within CHS range + jbe ReadSectorsCHS // Yes - go to the old CHS routine ReadSectorsLBA: popa ReadSectorsLBALoop: - pusha // Save logical sector number & sector count + pusha // Save logical sector number & sector count push 0 push 0 - push dx // Put 64-bit logical - push ax // block address on stack - push es // Put transfer segment on stack - push bx // Put transfer offset on stack - push 1 // Set transfer count to 1 sector - push HEX(10) // Set size of packet to 10h - mov si,sp // Setup disk address packet on stack + push dx // Put 64-bit logical + push ax // block address on stack + push es // Put transfer segment on stack + push bx // Put transfer offset on stack + push 1 // Set transfer count to 1 sector + push HEX(10) // Set size of packet to 10h + mov si,sp // Setup disk address packet on stack // We are so totally out of space here that I am forced to // comment out this very beautifully written piece of code // It would have been nice to have had this check... -//CheckInt13hExtensions: // Now make sure this computer supports extended reads -// mov ah,0x41 // AH = 41h -// mov bx,0x55aa // BX = 55AAh -// mov dl,[BYTE bp+BootDrive] // DL = drive (80h-FFh) -// int 13h // IBM/MS INT 13 Extensions - INSTALLATION CHECK -// jc PrintDiskError // CF set on error (extensions not supported) -// cmp bx,0xaa55 // BX = AA55h if installed -// jne PrintDiskError -// test cl,1 // CX = API subset support bitmap -// jz PrintDiskError // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported +//CheckInt13hExtensions: // Now make sure this computer supports extended reads +// mov ah,0x41 // AH = 41h +// mov bx,0x55aa // BX = 55AAh +// mov dl,[BYTE bp+BootDrive] // DL = drive (80h-FFh) +// int 13h // IBM/MS INT 13 Extensions - INSTALLATION CHECK +// jc PrintDiskError // CF set on error (extensions not supported) +// cmp bx,0xaa55 // BX = AA55h if installed +// jne PrintDiskError +// test cl,1 // CX = API subset support bitmap +// jz PrintDiskError // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - // Good, we're here so the computer supports LBA disk access - // So finish the extended read - mov dl, byte ptr BP_REL(BootDrive) // Drive number - mov ah, HEX(42) // Int 13h, AH = 42h - Extended Read - int HEX(13) // Call BIOS - jc BadBoot // If the read failed then abort + // Good, we're here so the computer supports LBA disk access + // So finish the extended read + mov dl, byte ptr BP_REL(BootDrive) // Drive number + mov ah, HEX(42) // Int 13h, AH = 42h - Extended Read + int HEX(13) // Call BIOS + jc BadBoot // If the read failed then abort - add sp, 16 // Remove disk address packet from stack + add sp, 16 // Remove disk address packet from stack - popa // Restore sector count & logical sector number + popa // Restore sector count & logical sector number - inc ax // Increment Sector to Read + inc ax // Increment Sector to Read adc dx, 0 push bx mov bx, es - add bx, HEX(20) // Increment read buffer for next sector + add bx, HEX(20) // Increment read buffer for next sector mov es, bx pop bx - loop ReadSectorsLBALoop // Read next sector + loop ReadSectorsLBALoop // Read next sector ret @@ -370,26 +370,26 @@ ReadSectorsCHSLoop: xor dx, dx div word ptr BP_REL(SectorsPerTrack) xchg ax, cx - div word ptr BP_REL(SectorsPerTrack) // Divide logical by SectorsPerTrack - inc dx // Sectors numbering starts at 1 not 0 + div word ptr BP_REL(SectorsPerTrack) // Divide logical by SectorsPerTrack + inc dx // Sectors numbering starts at 1 not 0 xchg cx, dx - div word ptr BP_REL(NumberOfHeads) // Number of heads - mov dh, dl // Head to DH, drive to DL - mov dl, byte ptr BP_REL(BootDrive) // Drive number - mov ch, al // Cylinder in CX - ror ah, 2 // Low 8 bits of cylinder in CH, high 2 bits - // in CL shifted to bits 6 & 7 - or cl, ah // Or with sector number + div word ptr BP_REL(NumberOfHeads) // Number of heads + mov dh, dl // Head to DH, drive to DL + mov dl, byte ptr BP_REL(BootDrive) // Drive number + mov ch, al // Cylinder in CX + ror ah, 2 // Low 8 bits of cylinder in CH, high 2 bits + // in CL shifted to bits 6 & 7 + or cl, ah // Or with sector number mov ax, HEX(0201) int HEX(13) // DISK - READ SECTORS INTO MEMORY // AL = number of sectors to read, CH = track, CL = sector - // DH = head, DL = drive, ES:BX -> buffer to fill - // Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read + // DH = head, DL = drive, ES:BX -> buffer to fill + // Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read jc BadBoot popa - inc ax //Increment Sector to Read + inc ax // Increment Sector to Read jnz NoCarryCHS inc dx @@ -400,8 +400,8 @@ NoCarryCHS: add bx, HEX(20) mov es, bx pop bx - // Increment read buffer for next sector - loop ReadSectorsCHSLoop // Read next sector + // Increment read buffer for next sector + loop ReadSectorsCHSLoop // Read next sector ret @@ -409,10 +409,11 @@ NoCarryCHS: msgDiskError: .ascii "Disk error", CR, LF, NUL msgFreeLdr: - .ascii "ldr not found", CR, LF, NUL + .ascii "Ldr not found", CR, LF, NUL // Sorry, need the space... -//msgAnyKey: +// msgAnyKey: // .ascii "Press any key to restart", CR, LF, NUL +// .ascii "Press a key", CR, LF, NUL filename: .ascii "FREELDR SYS" @@ -422,7 +423,7 @@ BootPartition: .byte 0 BootSignature: - .word HEX(0aa55) // BootSector signature + .word HEX(0aa55) // BootSector signature .endcode16 diff --git a/reactos/boot/freeldr/bootsect/fat.asm b/reactos/boot/freeldr/bootsect/fat.asm index 0e803a58500..4cb4da64a02 100644 --- a/reactos/boot/freeldr/bootsect/fat.asm +++ b/reactos/boot/freeldr/bootsect/fat.asm @@ -39,15 +39,15 @@ ; boots dramatically. -BootSectorStackTop equ 0x7bf2 -DataAreaStartHigh equ 0x2 -DataAreaStartLow equ 0x4 -BiosCHSDriveSizeHigh equ 0x6 -BiosCHSDriveSizeLow equ 0x8 -BiosCHSDriveSize equ 0x8 -ReadSectorsOffset equ 0xa -ReadClusterOffset equ 0xc -PutCharsOffset equ 0xe +BootSectorStackTop equ 0x7bf2 +DataAreaStartHigh equ 0x2 +DataAreaStartLow equ 0x4 +BiosCHSDriveSizeHigh equ 0x6 +BiosCHSDriveSizeLow equ 0x8 +BiosCHSDriveSize equ 0x8 +ReadSectorsOffset equ 0xa +ReadClusterOffset equ 0xc +PutCharsOffset equ 0xe org 7c00h @@ -84,136 +84,136 @@ main: xor ax,ax mov ss,ax mov bp,7c00h - mov sp,BootSectorStackTop ; Setup a stack - mov ds,ax ; Make DS correct - mov es,ax ; Make ES correct + mov sp,BootSectorStackTop ; Setup a stack + mov ds,ax ; Make DS correct + mov es,ax ; Make ES correct - cmp BYTE [BYTE bp+BootDrive],BYTE 0xff ; If they have specified a boot drive then use it - jne GetDriveParameters + cmp BYTE [BYTE bp+BootDrive],BYTE 0xff ; If they have specified a boot drive then use it + jne GetDriveParameters - mov [BYTE bp+BootDrive],dl ; Save the boot drive + mov [BYTE bp+BootDrive],dl ; Save the boot drive GetDriveParameters: - mov ah,08h - mov dl,[BYTE bp+BootDrive] ; Get boot drive in dl - int 13h ; Request drive parameters from the bios - jnc CalcDriveSize ; If the call succeeded then calculate the drive size + mov ah,08h + mov dl,[BYTE bp+BootDrive] ; Get boot drive in dl + int 13h ; Request drive parameters from the bios + jnc CalcDriveSize ; If the call succeeded then calculate the drive size - ; If we get here then the call to the BIOS failed - ; so just set CHS equal to the maximum addressable - ; size - mov cx,0ffffh - mov dh,cl + ; If we get here then the call to the BIOS failed + ; so just set CHS equal to the maximum addressable + ; size + mov cx,0ffffh + mov dh,cl CalcDriveSize: - ; Now that we have the drive geometry - ; lets calculate the drive size - mov bl,ch ; Put the low 8-bits of the cylinder count into BL - mov bh,cl ; Put the high 2-bits in BH - shr bh,6 ; Shift them into position, now BX contains the cylinder count - and cl,3fh ; Mask off cylinder bits from sector count - ; CL now contains sectors per track and DH contains head count - movzx eax,dh ; Move the heads into EAX - movzx ebx,bx ; Move the cylinders into EBX - movzx ecx,cl ; Move the sectors per track into ECX - inc eax ; Make it one based because the bios returns it zero based - inc ebx ; Make the cylinder count one based also - mul ecx ; Multiply heads with the sectors per track, result in edx:eax - mul ebx ; Multiply the cylinders with (heads * sectors) [stored in edx:eax already] + ; Now that we have the drive geometry + ; lets calculate the drive size + mov bl,ch ; Put the low 8-bits of the cylinder count into BL + mov bh,cl ; Put the high 2-bits in BH + shr bh,6 ; Shift them into position, now BX contains the cylinder count + and cl,3fh ; Mask off cylinder bits from sector count + ; CL now contains sectors per track and DH contains head count + movzx eax,dh ; Move the heads into EAX + movzx ebx,bx ; Move the cylinders into EBX + movzx ecx,cl ; Move the sectors per track into ECX + inc eax ; Make it one based because the bios returns it zero based + inc ebx ; Make the cylinder count one based also + mul ecx ; Multiply heads with the sectors per track, result in edx:eax + mul ebx ; Multiply the cylinders with (heads * sectors) [stored in edx:eax already] - ; We now have the total number of sectors as reported - ; by the bios in eax, so store it in our variable - mov [BYTE bp-BiosCHSDriveSize],eax + ; We now have the total number of sectors as reported + ; by the bios in eax, so store it in our variable + mov [BYTE bp-BiosCHSDriveSize],eax ; Now we must find our way to the first sector of the root directory xor ax,ax - xor cx,cx - mov al,[BYTE bp+NumberOfFats] ; Number of fats - mul WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat + xor cx,cx + mov al,[BYTE bp+NumberOfFats] ; Number of fats + mul WORD [BYTE bp+SectorsPerFat] ; Times sectors per fat add ax,WORD [BYTE bp+HiddenSectors] - adc dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors - add ax,WORD [BYTE bp+ReservedSectors] ; Add the number of reserved sectors - adc dx,cx ; Add carry bit - mov WORD [BYTE bp-DataAreaStartLow],ax ; Save the starting sector of the root directory - mov WORD [BYTE bp-DataAreaStartHigh],dx ; Save it in the first 4 bytes before the boot sector - mov si,WORD [BYTE bp+MaxRootEntries] ; Get number of root dir entries in SI - pusha ; Save 32-bit logical start sector of root dir + adc dx,WORD [BYTE bp+HiddenSectors+2] ; Add the number of hidden sectors + add ax,WORD [BYTE bp+ReservedSectors] ; Add the number of reserved sectors + adc dx,cx ; Add carry bit + mov WORD [BYTE bp-DataAreaStartLow],ax ; Save the starting sector of the root directory + mov WORD [BYTE bp-DataAreaStartHigh],dx ; Save it in the first 4 bytes before the boot sector + mov si,WORD [BYTE bp+MaxRootEntries] ; Get number of root dir entries in SI + pusha ; Save 32-bit logical start sector of root dir ; DX:AX now has the number of the starting sector of the root directory ; Now calculate the size of the root directory - xor dx,dx - mov ax,0020h ; Size of dir entry - mul si ; Times the number of entries + xor dx,dx + mov ax,0020h ; Size of dir entry + mul si ; Times the number of entries mov bx,[BYTE bp+BytesPerSector] add ax,bx dec ax - div bx ; Divided by the size of a sector - ; AX now has the number of root directory sectors + div bx ; Divided by the size of a sector + ; AX now has the number of root directory sectors - add [BYTE bp-DataAreaStartLow],ax ; Add the number of sectors of the root directory to our other value - adc [BYTE bp-DataAreaStartHigh],cx ; Now the first 4 bytes before the boot sector contain the starting sector of the data area - popa ; Restore root dir logical sector start to DX:AX + add [BYTE bp-DataAreaStartLow],ax ; Add the number of sectors of the root directory to our other value + adc [BYTE bp-DataAreaStartHigh],cx ; Now the first 4 bytes before the boot sector contain the starting sector of the data area + popa ; Restore root dir logical sector start to DX:AX LoadRootDirSector: - mov bx,7e0h ; We will load the root directory sector - mov es,bx ; Right after the boot sector in memory - xor bx,bx ; We will load it to [0000:7e00h] - xor cx,cx ; Zero out CX - inc cx ; Now increment it to 1, we are reading one sector - xor di,di ; Zero out di - push es ; Save ES because it will get incremented by 20h - call ReadSectors ; Read the first sector of the root directory - pop es ; Restore ES (ES:DI = 07E0:0000) + mov bx,7e0h ; We will load the root directory sector + mov es,bx ; Right after the boot sector in memory + xor bx,bx ; We will load it to [0000:7e00h] + xor cx,cx ; Zero out CX + inc cx ; Now increment it to 1, we are reading one sector + xor di,di ; Zero out di + push es ; Save ES because it will get incremented by 20h + call ReadSectors ; Read the first sector of the root directory + pop es ; Restore ES (ES:DI = 07E0:0000) SearchRootDirSector: - cmp [es:di],ch ; If the first byte of the directory entry is zero then we have - jz ErrBoot ; reached the end of the directory and FREELDR.SYS is not here so reboot - pusha ; Save all registers - mov cl,0xb ; Put 11 in cl (length of filename in directory entry) - mov si,filename ; Put offset of filename string in DS:SI - repe cmpsb ; Compare this directory entry against 'FREELDR SYS' - popa ; Restore all the registers - jz FoundFreeLoader ; If we found it then jump - dec si ; SI holds MaxRootEntries, subtract one - jz ErrBoot ; If we are out of root dir entries then reboot - add di,BYTE +0x20 ; Increment DI by the size of a directory entry - cmp di,0200h ; Compare DI to 512 (DI has offset to next dir entry, make sure we haven't gone over one sector) - jc SearchRootDirSector ; If DI is less than 512 loop again - jmp short LoadRootDirSector ; Didn't find FREELDR.SYS in this directory sector, try again + cmp [es:di],ch ; If the first byte of the directory entry is zero then we have + jz ErrBoot ; reached the end of the directory and FREELDR.SYS is not here so reboot + pusha ; Save all registers + mov cl,0xb ; Put 11 in cl (length of filename in directory entry) + mov si,filename ; Put offset of filename string in DS:SI + repe cmpsb ; Compare this directory entry against 'FREELDR SYS' + popa ; Restore all the registers + jz FoundFreeLoader ; If we found it then jump + dec si ; SI holds MaxRootEntries, subtract one + jz ErrBoot ; If we are out of root dir entries then reboot + add di,BYTE +0x20 ; Increment DI by the size of a directory entry + cmp di,0200h ; Compare DI to 512 (DI has offset to next dir entry, make sure we haven't gone over one sector) + jc SearchRootDirSector ; If DI is less than 512 loop again + jmp short LoadRootDirSector ; Didn't find FREELDR.SYS in this directory sector, try again FoundFreeLoader: - ; We found freeldr.sys on the disk - ; so we need to load the first 512 - ; bytes of it to 0000:8000 + ; We found freeldr.sys on the disk + ; so we need to load the first 512 + ; bytes of it to 0000:8000 ; ES:DI has dir entry (ES:DI == 07E0:XXXX) - mov ax,WORD [es:di+1ah] ; Get start cluster - push ax ; Save start cluster - push WORD 800h ; Put 800h on the stack and load it - pop es ; Into ES so that we load the cluster at 0000:8000 - call ReadCluster ; Read the cluster - pop ax ; Restore start cluster of FreeLoader + mov ax,WORD [es:di+1ah] ; Get start cluster + push ax ; Save start cluster + push WORD 800h ; Put 800h on the stack and load it + pop es ; Into ES so that we load the cluster at 0000:8000 + call ReadCluster ; Read the cluster + pop ax ; Restore start cluster of FreeLoader - ; Save the addresses of needed functions so - ; the helper code will know where to call them. - mov WORD [BYTE bp-ReadSectorsOffset],ReadSectors ; Save the address of ReadSectors - mov WORD [BYTE bp-ReadClusterOffset],ReadCluster ; Save the address of ReadCluster - mov WORD [BYTE bp-PutCharsOffset],PutChars ; Save the address of PutChars + ; Save the addresses of needed functions so + ; the helper code will know where to call them. + mov WORD [BYTE bp-ReadSectorsOffset],ReadSectors ; Save the address of ReadSectors + mov WORD [BYTE bp-ReadClusterOffset],ReadCluster ; Save the address of ReadCluster + mov WORD [BYTE bp-PutCharsOffset],PutChars ; Save the address of PutChars - ; Now AX has start cluster of FreeLoader and we - ; have loaded the helper code in the first 512 bytes - ; of FreeLoader to 0000:8000. Now transfer control - ; to the helper code. Skip the first three bytes - ; because they contain a jump instruction to skip - ; over the helper code in the FreeLoader image. - ;jmp 0000:9003h - push 0 ; push segment (0x0000) - mov bx, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax - add bx, 0x8003 ; RVA -> VA and skip 3 bytes (jump to fathelper code) - push bx ; push offset - retf ; Transfer control to FreeLoader + ; Now AX has start cluster of FreeLoader and we + ; have loaded the helper code in the first 512 bytes + ; of FreeLoader to 0000:8000. Now transfer control + ; to the helper code. Skip the first three bytes + ; because they contain a jump instruction to skip + ; over the helper code in the FreeLoader image. + ;jmp 0000:9003h + push 0 ; push segment (0x0000) + mov bx, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax + add bx, 0x8003 ; RVA -> VA and skip 3 bytes (jump to fathelper code) + push bx ; push offset + retf ; Transfer control to FreeLoader @@ -248,23 +248,23 @@ BadBoot: mov si,msgDiskError ; Bad boot disk message call PutChars ; Display it - jmp short Reboot + jmp short Reboot ; Reads cluster number in AX into [ES:0000] ReadCluster: - ; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors; - dec ax ; Adjust start cluster by 2 - dec ax ; Because the data area starts on cluster 2 + ; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors; + dec ax ; Adjust start cluster by 2 + dec ax ; Because the data area starts on cluster 2 xor ch,ch mov cl,BYTE [BYTE bp+SectsPerCluster] - mul cx ; Times sectors per cluster - add ax,[BYTE bp-DataAreaStartLow] ; Add start of data area - adc dx,[BYTE bp-DataAreaStartHigh] ; Now we have DX:AX with the logical start sector of OSLOADER.SYS - xor bx,bx ; We will load it to [ES:0000], ES loaded before function call - ;mov cl,BYTE [BYTE bp+SectsPerCluster]; Sectors per cluster still in CX - ;call ReadSectors - ;ret + mul cx ; Times sectors per cluster + add ax,[BYTE bp-DataAreaStartLow] ; Add start of data area + adc dx,[BYTE bp-DataAreaStartHigh] ; Now we have DX:AX with the logical start sector of FREELDR.SYS + xor bx,bx ; We will load it to [ES:0000], ES loaded before function call + ;mov cl,BYTE [BYTE bp+SectsPerCluster]; Sectors per cluster still in CX + ;call ReadSectors + ;ret @@ -272,71 +272,71 @@ ReadCluster: ; DX:AX has logical sector number to read ; CX has number of sectors to read ReadSectors: - - ; We can't just check if the start sector is - ; in the BIOS CHS range. We have to check if - ; the start sector + length is in that range. - pusha - dec cx - add ax,cx - adc dx,byte 0 + + ; We can't just check if the start sector is + ; in the BIOS CHS range. We have to check if + ; the start sector + length is in that range. + pusha + dec cx + add ax,cx + adc dx,byte 0 - cmp dx,WORD [BYTE bp-BiosCHSDriveSizeHigh] ; Check if they are reading a sector within CHS range - ja ReadSectorsLBA ; No - go to the LBA routine - jb ReadSectorsCHS ; Yes - go to the old CHS routine - cmp ax,WORD [BYTE bp-BiosCHSDriveSizeLow] ; Check if they are reading a sector within CHS range - jbe ReadSectorsCHS ; Yes - go to the old CHS routine + cmp dx,WORD [BYTE bp-BiosCHSDriveSizeHigh] ; Check if they are reading a sector within CHS range + ja ReadSectorsLBA ; No - go to the LBA routine + jb ReadSectorsCHS ; Yes - go to the old CHS routine + cmp ax,WORD [BYTE bp-BiosCHSDriveSizeLow] ; Check if they are reading a sector within CHS range + jbe ReadSectorsCHS ; Yes - go to the old CHS routine ReadSectorsLBA: - popa + popa ReadSectorsLBALoop: - pusha ; Save logical sector number & sector count + pusha ; Save logical sector number & sector count - o32 push byte 0 - push dx ; Put 64-bit logical - push ax ; block address on stack - push es ; Put transfer segment on stack - push bx ; Put transfer offset on stack - push byte 1 ; Set transfer count to 1 sector - push byte 0x10 ; Set size of packet to 10h - mov si,sp ; Setup disk address packet on stack + o32 push byte 0 + push dx ; Put 64-bit logical + push ax ; block address on stack + push es ; Put transfer segment on stack + push bx ; Put transfer offset on stack + push byte 1 ; Set transfer count to 1 sector + push byte 0x10 ; Set size of packet to 10h + mov si,sp ; Setup disk address packet on stack ; We are so totally out of space here that I am forced to ; comment out this very beautifully written piece of code ; It would have been nice to have had this check... -;CheckInt13hExtensions: ; Now make sure this computer supports extended reads -; mov ah,0x41 ; AH = 41h -; mov bx,0x55aa ; BX = 55AAh -; mov dl,[BYTE bp+BootDrive] ; DL = drive (80h-FFh) -; int 13h ; IBM/MS INT 13 Extensions - INSTALLATION CHECK -; jc PrintDiskError ; CF set on error (extensions not supported) -; cmp bx,0xaa55 ; BX = AA55h if installed -; jne PrintDiskError -; test cl,1 ; CX = API subset support bitmap -; jz PrintDiskError ; Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported +;CheckInt13hExtensions: ; Now make sure this computer supports extended reads +; mov ah,0x41 ; AH = 41h +; mov bx,0x55aa ; BX = 55AAh +; mov dl,[BYTE bp+BootDrive] ; DL = drive (80h-FFh) +; int 13h ; IBM/MS INT 13 Extensions - INSTALLATION CHECK +; jc PrintDiskError ; CF set on error (extensions not supported) +; cmp bx,0xaa55 ; BX = AA55h if installed +; jne PrintDiskError +; test cl,1 ; CX = API subset support bitmap +; jz PrintDiskError ; Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - ; Good, we're here so the computer supports LBA disk access - ; So finish the extended read - mov dl,[BYTE bp+BootDrive] ; Drive number - mov ah,42h ; Int 13h, AH = 42h - Extended Read - int 13h ; Call BIOS - jc BadBoot ; If the read failed then abort + ; Good, we're here so the computer supports LBA disk access + ; So finish the extended read + mov dl,[BYTE bp+BootDrive] ; Drive number + mov ah,42h ; Int 13h, AH = 42h - Extended Read + int 13h ; Call BIOS + jc BadBoot ; If the read failed then abort - add sp,byte 0x10 ; Remove disk address packet from stack + add sp,byte 0x10 ; Remove disk address packet from stack - popa ; Restore sector count & logical sector number + popa ; Restore sector count & logical sector number - inc ax ; Increment Sector to Read - adc dx,byte 0 + inc ax ; Increment Sector to Read + adc dx,byte 0 push bx mov bx,es - add bx,byte 20h ; Increment read buffer for next sector + add bx,byte 20h ; Increment read buffer for next sector mov es,bx pop bx - - loop ReadSectorsLBALoop ; Read next sector + + loop ReadSectorsLBALoop ; Read next sector ret @@ -346,7 +346,7 @@ ReadSectorsLBALoop: ; CX has number of sectors to read ; CarryFlag set on error ReadSectorsCHS: - popa + popa ReadSectorsCHSLoop: pusha xchg ax,cx @@ -367,8 +367,8 @@ ReadSectorsCHSLoop: mov ax,0201h int 13h ; DISK - READ SECTORS INTO MEMORY ; AL = number of sectors to read, CH = track, CL = sector - ; DH = head, DL = drive, ES:BX -> buffer to fill - ; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read + ; DH = head, DL = drive, ES:BX -> buffer to fill + ; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read jc BadBoot @@ -391,16 +391,16 @@ NoCarryCHS: msgDiskError db 'Disk error',0dh,0ah,0 -msgFreeLdr db 'ldr not found',0dh,0ah,0 +msgFreeLdr db 'Ldr not found',0dh,0ah,0 ; Sorry, need the space... ;msgAnyKey db 'Press any key to restart',0dh,0ah,0 -msgAnyKey db 'Press a key',0dh,0ah,0 +;msgAnyKey db 'Press a key',0dh,0ah,0 filename db 'FREELDR SYS' times 509-($-$$) db 0 ; Pad to 509 bytes BootPartition: - db 0 + db 0 BootSignature: dw 0aa55h ; BootSector signature diff --git a/reactos/boot/freeldr/bootsect/fat32.S b/reactos/boot/freeldr/bootsect/fat32.S index b8d7173ff1d..7fb91e21ccc 100644 --- a/reactos/boot/freeldr/bootsect/fat32.S +++ b/reactos/boot/freeldr/bootsect/fat32.S @@ -3,7 +3,7 @@ * PROJECT: ReactOS Bootsector * FILE: boot/freeldr/bootsect/fat32.S * PURPOSE: - * PROGRAMMERS: ? + * PROGRAMMERS: Brian Palmer */ /* INCLUDES ******************************************************************/ @@ -32,13 +32,13 @@ ReservedSectors: NumberOfFats: .byte 2 MaxRootEntries: - .word 0 // Always zero for FAT32 volumes + .word 0 // Always zero for FAT32 volumes TotalSectors: - .word 0 // Always zero for FAT32 volumes + .word 0 // Always zero for FAT32 volumes MediaDescriptor: .byte HEX(0f8) SectorsPerFat: - .word 0 // Always zero for FAT32 volumes + .word 0 // Always zero for FAT32 volumes SectorsPerTrack: .word 0 NumberOfHeads: @@ -82,33 +82,33 @@ main: xor ax,ax // Setup segment registers mov ds,ax // Make DS correct mov es,ax // Make ES correct - mov ss,ax // Make SS correct + mov ss,ax // Make SS correct mov bp, HEX(7c00) mov sp, HEX(7c00) // Setup a stack - cmp byte ptr BP_REL(BootDrive), HEX(0ff) // If they have specified a boot drive then use it + cmp byte ptr BP_REL(BootDrive), HEX(0ff) // If they have specified a boot drive then use it jne CheckSectorsPerFat - mov byte ptr BP_REL(BootDrive), dl // Save the boot drive + mov byte ptr BP_REL(BootDrive), dl // Save the boot drive CheckSectorsPerFat: - cmp word ptr BP_REL(SectorsPerFat), 0 // Check the old 16-bit value of SectorsPerFat - jnz CheckFailed // If it is non-zero then exit with an error -CheckTotalSectors: // Check the old 16-bit value of TotalSectors & MaxRootEntries - cmp dword ptr BP_REL(MaxRootEntries), 0// by comparing the DWORD at offset MaxRootEntries to zero - jnz CheckFailed // If it is non-zero then exit with an error + cmp word ptr BP_REL(SectorsPerFat), 0 // Check the old 16-bit value of SectorsPerFat + jnz CheckFailed // If it is non-zero then exit with an error +CheckTotalSectors: // Check the old 16-bit value of TotalSectors & MaxRootEntries + cmp dword ptr BP_REL(MaxRootEntries), 0 // by comparing the DWORD at offset MaxRootEntries to zero + jnz CheckFailed // If it is non-zero then exit with an error CheckFileSystemVersion: - cmp word ptr BP_REL(FSVersion), 0 // Check the file system version word - jna GetDriveParameters // It is zero, so continue + cmp word ptr BP_REL(FSVersion), 0 // Check the file system version word + jna GetDriveParameters // It is zero, so continue CheckFailed: - jmp PrintFileSystemError // If it is not zero then exit with an error + jmp PrintFileSystemError // If it is not zero then exit with an error GetDriveParameters: mov ax, HEX(0800) - mov dl, byte ptr BP_REL(BootDrive) // Get boot drive in dl - int HEX(13) // Request drive parameters from the bios - jnc CalcDriveSize // If the call succeeded then calculate the drive size + mov dl, byte ptr BP_REL(BootDrive) // Get boot drive in dl + int HEX(13) // Request drive parameters from the bios + jnc CalcDriveSize // If the call succeeded then calculate the drive size // If we get here then the call to the BIOS failed // so just set CHS equal to the maximum addressable @@ -119,18 +119,18 @@ GetDriveParameters: CalcDriveSize: // Now that we have the drive geometry // lets calculate the drive size - mov bl, ch // Put the low 8-bits of the cylinder count into BL - mov bh, cl // Put the high 2-bits in BH - shr bh, 6 // Shift them into position, now BX contains the cylinder count - and cl, HEX(3f) // Mask off cylinder bits from sector count + mov bl, ch // Put the low 8-bits of the cylinder count into BL + mov bh, cl // Put the high 2-bits in BH + shr bh, 6 // Shift them into position, now BX contains the cylinder count + and cl, HEX(3f) // Mask off cylinder bits from sector count // CL now contains sectors per track and DH contains head count - movzx eax, dh // Move the heads into EAX - movzx ebx, bx // Move the cylinders into EBX - movzx ecx, cl // Move the sectors per track into ECX - inc eax // Make it one based because the bios returns it zero based - inc ebx // Make the cylinder count one based also - mul ecx // Multiply heads with the sectors per track, result in edx:eax - mul ebx // Multiply the cylinders with (heads * sectors) [stored in edx:eax already] + movzx eax, dh // Move the heads into EAX + movzx ebx, bx // Move the cylinders into EBX + movzx ecx, cl // Move the sectors per track into ECX + inc eax // Make it one based because the bios returns it zero based + inc ebx // Make the cylinder count one based also + mul ecx // Multiply heads with the sectors per track, result in edx:eax + mul ebx // Multiply the cylinders with (heads * sectors) [stored in edx:eax already] // We now have the total number of sectors as reported // by the bios in eax, so store it in our variable @@ -140,10 +140,10 @@ LoadExtraBootCode: // First we have to load our extra boot code at // sector 14 into memory at [0000:7e00h] mov eax, HEX(0e) - add eax, dword ptr BP_REL(HiddenSectors) // Add the number of hidden sectors + add eax, dword ptr BP_REL(HiddenSectors) // Add the number of hidden sectors mov cx, 1 xor bx, bx - mov es, bx // Read sector to [0000:7e00h] + mov es, bx // Read sector to [0000:7e00h] mov bx, HEX(7e00) call ReadSectors jmp StartSearch @@ -154,64 +154,64 @@ LoadExtraBootCode: // CX has number of sectors to read ReadSectors: push es - cmp eax, dword ptr ds:[BiosCHSDriveSize] // Check if they are reading a sector outside CHS range - jae ReadSectorsLBA // Yes - go to the LBA routine + cmp eax, dword ptr ds:[BiosCHSDriveSize] // Check if they are reading a sector outside CHS range + jae ReadSectorsLBA // Yes - go to the LBA routine // If at all possible we want to use LBA routines because // They are optimized to read more than 1 sector per read - pushad // Save logical sector number & sector count + pushad // Save logical sector number & sector count -CheckInt13hExtensions: // Now check if this computer supports extended reads +CheckInt13hExtensions: // Now check if this computer supports extended reads mov ah, HEX(41) // AH = 41h - mov bx, HEX(55aa) // BX = 55AAh - mov dl, byte ptr BP_REL(BootDrive) // DL = drive (80h-FFh) + mov bx, HEX(55aa) // BX = 55AAh + mov dl, byte ptr BP_REL(BootDrive) // DL = drive (80h-FFh) int HEX(13) // IBM/MS INT 13 Extensions - INSTALLATION CHECK - jc ReadSectorsCHS // CF set on error (extensions not supported) - cmp bx, HEX(0aa55) // BX = AA55h if installed + jc ReadSectorsCHS // CF set on error (extensions not supported) + cmp bx, HEX(0aa55) // BX = AA55h if installed jne ReadSectorsCHS - test cl,1 // CX = API subset support bitmap - jz ReadSectorsCHS // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported + test cl,1 // CX = API subset support bitmap + jz ReadSectorsCHS // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - popad // Restore sector count & logical sector number + popad // Restore sector count & logical sector number ReadSectorsLBA: - pushad // Save logical sector number & sector count + pushad // Save logical sector number & sector count - cmp cx, 64 // Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64 - jbe ReadSectorsSetupDiskAddressPacket // If we are reading less than 65 sectors then just do the read - mov cx, 64 // Otherwise read only 64 sectors on this loop iteration + cmp cx, 64 // Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64 + jbe ReadSectorsSetupDiskAddressPacket // If we are reading less than 65 sectors then just do the read + mov cx, 64 // Otherwise read only 64 sectors on this loop iteration ReadSectorsSetupDiskAddressPacket: mov word ptr ds:[LBASectorsRead],cx push 0 push 0 push eax // Put 64-bit logical block address on stack - push es // Put transfer segment on stack - push bx // Put transfer offset on stack - push cx // Set transfer count - push 16 // Set size of packet to 10h - mov si, sp // Setup disk address packet on stack + push es // Put transfer segment on stack + push bx // Put transfer offset on stack + push cx // Set transfer count + push 16 // Set size of packet to 10h + mov si, sp // Setup disk address packet on stack - mov dl, byte ptr BP_REL(BootDrive) // Drive number - mov ah, HEX(42) // Int 13h, AH = 42h - Extended Read - int HEX(13) // Call BIOS - jc PrintDiskError // If the read failed then abort + mov dl, byte ptr BP_REL(BootDrive) // Drive number + mov ah, HEX(42) // Int 13h, AH = 42h - Extended Read + int HEX(13) // Call BIOS + jc PrintDiskError // If the read failed then abort - add sp, 16 // Remove disk address packet from stack + add sp, 16 // Remove disk address packet from stack - popad // Restore sector count & logical sector number + popad // Restore sector count & logical sector number push bx mov ebx, dword ptr ds:[LBASectorsRead] - add eax, ebx // Increment sector to read + add eax, ebx // Increment sector to read shl ebx, 5 mov dx, es - add dx, bx // Setup read buffer for next sector + add dx, bx // Setup read buffer for next sector mov es, dx pop bx sub cx, word ptr ds:[LBASectorsRead] - jnz ReadSectorsLBA // Read next sector + jnz ReadSectorsLBA // Read next sector pop es ret @@ -231,57 +231,57 @@ ReadSectorsCHSLoop: xor edx, edx movzx ecx, word ptr BP_REL(SectorsPerTrack) div ecx // Divide logical by SectorsPerTrack - inc dl // Sectors numbering starts at 1 not 0 - mov cl, dl // Sector in CL + inc dl // Sectors numbering starts at 1 not 0 + mov cl, dl // Sector in CL mov edx, eax shr edx, 16 - div word ptr BP_REL(NumberOfHeads) // Divide logical by number of heads - mov dh, dl // Head in DH - mov dl, byte ptr BP_REL(BootDrive) // Drive number in DL - mov ch, al // Cylinder in CX - ror ah, 1 // Low 8 bits of cylinder in CH, high 2 bits - ror ah, 1 // in CL shifted to bits 6 & 7 - or cl, ah // Or with sector number + div word ptr BP_REL(NumberOfHeads) // Divide logical by number of heads + mov dh, dl // Head in DH + mov dl, byte ptr BP_REL(BootDrive) // Drive number in DL + mov ch, al // Cylinder in CX + ror ah, 1 // Low 8 bits of cylinder in CH, high 2 bits + ror ah, 1 // in CL shifted to bits 6 & 7 + or cl, ah // Or with sector number mov ax, HEX(0201) int HEX(13) // DISK - READ SECTORS INTO MEMORY // AL = number of sectors to read, CH = track, CL = sector - // DH = head, DL = drive, ES:BX -> buffer to fill - // Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read + // DH = head, DL = drive, ES:BX -> buffer to fill + // Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read - jc PrintDiskError // If the read failed then abort + jc PrintDiskError // If the read failed then abort popad inc eax // Increment Sector to Read mov dx, es - add dx, 32 // Increment read buffer for next sector + add dx, 32 // Increment read buffer for next sector mov es, dx - loop ReadSectorsCHSLoop // Read next sector + loop ReadSectorsCHSLoop // Read next sector ret // Displays a disk error message // And reboots PrintDiskError: - mov si, offset msgDiskError // Bad boot disk message - call PutChars // Display it + mov si, offset msgDiskError // Bad boot disk message + call PutChars // Display it jmp Reboot // Displays a file system error message // And reboots PrintFileSystemError: - mov si, offset msgFileSystemError // FreeLdr not found message - call PutChars // Display it + mov si, offset msgFileSystemError // FreeLdr not found message + call PutChars // Display it Reboot: - mov si, offset msgAnyKey // Press any key message - call PutChars // Display it + mov si, offset msgAnyKey // Press any key message + call PutChars // Display it xor ax, ax - int HEX(16) // Wait for a keypress - int HEX(19) // Reboot + int HEX(16) // Wait for a keypress + int HEX(19) // Reboot PutChars: lodsb @@ -311,7 +311,7 @@ BootPartition: .byte 0 BootSignature: - .word HEX(0aa55) // BootSector signature + .word HEX(0aa55) // BootSector signature // End of bootsector // @@ -330,7 +330,7 @@ StartSearch: // Now we must get the first cluster of the root directory mov eax, dword ptr BP_REL(RootDirStartCluster) cmp eax, HEX(0ffffff8) // Check to see if this is the last cluster in the chain - jb ContinueSearch // If not continue, if so then we didn't find freeldr.sys + jb ContinueSearch // If not continue, if so then we didn't find freeldr.sys jmp PrintFileNotFound ContinueSearch: @@ -339,16 +339,16 @@ ContinueSearch: call ReadCluster // Read the cluster // Now we have to find our way through the root directory to - // The OSLOADER.SYS file + // The FREELDR.SYS file xor bx,bx mov bl, byte ptr BP_REL(SectsPerCluster) - shl bx, 4 // BX = BX * 512 / 32 + shl bx, 4 // BX = BX * 512 / 32 mov ax, HEX(2000) // We loaded at 2000:0000 mov es, ax xor di, di mov si, offset filename mov cx, 11 - repe cmpsb // Compare filenames + repe cmpsb // Compare filenames jz FoundFile // If same we found it dec bx jnz FindFile @@ -357,11 +357,11 @@ ContinueSearch: FindFile: mov ax, es // We didn't find it in the previous dir entry add ax, 2 // So lets move to the next one - mov es, ax // And search again + mov es, ax // And search again xor di, di mov si, offset filename mov cx, 11 - repe cmpsb // Compare filenames + repe cmpsb // Compare filenames jz FoundFile // If same we found it dec bx // Keep searching till we run out of dir entries jnz FindFile // Last entry? @@ -377,51 +377,51 @@ FoundFile: mov si, offset msgLoading // Loading message call PutChars // Display it - xor di, di // ES:DI has dir entry + xor di, di // ES:DI has dir entry xor dx, dx - mov ax, word ptr es:[di+20] // Get start cluster high word + mov ax, word ptr es:[di+20] // Get start cluster high word shl eax, 16 - mov ax, word ptr es:[di+26] // Get start cluster low word + mov ax, word ptr es:[di+26] // Get start cluster low word CheckStartCluster: - cmp eax, 2 // Check and see if the start cluster starts at cluster 2 or above - jnb CheckEndCluster // If so then continue - jmp PrintFileSystemError // If not exit with error + cmp eax, 2 // Check and see if the start cluster starts at cluster 2 or above + jnb CheckEndCluster // If so then continue + jmp PrintFileSystemError // If not exit with error CheckEndCluster: - cmp eax, HEX(0ffffff8) // Check and see if the start cluster is and end of cluster chain indicator - jb InitializeLoadSegment // If not then continue - jmp PrintFileSystemError // If so exit with error + cmp eax, HEX(0ffffff8) // Check and see if the start cluster is and end of cluster chain indicator + jb InitializeLoadSegment // If not then continue + jmp PrintFileSystemError // If so exit with error InitializeLoadSegment: mov bx, FREELDR_BASE / 16 mov es, bx LoadFile: - cmp eax, HEX(0ffffff8) // Check to see if this is the last cluster in the chain - jae LoadFileDone // If so continue, if not then read the next one + cmp eax, HEX(0ffffff8) // Check to see if this is the last cluster in the chain + jae LoadFileDone // If so continue, if not then read the next one push eax - xor bx, bx // Load ROSLDR starting at 0000:8000h + xor bx, bx // Load ROSLDR starting at 0000:8000h push es call ReadCluster pop es xor bx, bx mov bl, byte ptr BP_REL(SectsPerCluster) - shl bx, 5 // BX = BX * 512 / 16 - mov ax, es // Increment the load address by - add ax, bx // The size of a cluster + shl bx, 5 // BX = BX * 512 / 16 + mov ax, es // Increment the load address by + add ax, bx // The size of a cluster mov es, ax pop eax push es - call GetFatEntry // Get the next entry + call GetFatEntry // Get the next entry pop es - jmp LoadFile // Load the next cluster (if any) + jmp LoadFile // Load the next cluster (if any) LoadFileDone: - mov dl, byte ptr BP_REL(BootDrive) // Load boot drive into DL - mov dh, byte ptr ds:[BootPartition] // Load boot partition into DH + mov dl, byte ptr BP_REL(BootDrive) // Load boot drive into DL + mov dh, byte ptr ds:[BootPartition] // Load boot partition into DH /* Transfer execution to the bootloader */ ljmp16 0, FREELDR_BASE @@ -431,43 +431,43 @@ LoadFileDone: // On return EAX has FAT entry for that cluster GetFatEntry: - shl eax, 2 // EAX = EAX * 4 (since FAT32 entries are 4 bytes) - mov ecx, eax // Save this for later in ECX + shl eax, 2 // EAX = EAX * 4 (since FAT32 entries are 4 bytes) + mov ecx, eax // Save this for later in ECX xor edx, edx movzx ebx, word ptr BP_REL(BytesPerSector) push ebx - div ebx // FAT Sector Number = EAX / BytesPerSector + div ebx // FAT Sector Number = EAX / BytesPerSector movzx ebx, word ptr BP_REL(ReservedSectors) - add eax, ebx // FAT Sector Number += ReservedSectors + add eax, ebx // FAT Sector Number += ReservedSectors mov ebx, dword ptr BP_REL(HiddenSectors) - add eax, ebx // FAT Sector Number += HiddenSectors + add eax, ebx // FAT Sector Number += HiddenSectors pop ebx dec ebx - and ecx,ebx // FAT Offset Within Sector = ECX % BytesPerSector - // EAX holds logical FAT sector number - // ECX holds FAT entry offset + and ecx,ebx // FAT Offset Within Sector = ECX % BytesPerSector + // EAX holds logical FAT sector number + // ECX holds FAT entry offset - // Now we have to check the extended flags - // to see which FAT is the active one - // and use it, or if they are mirrored then - // no worries - movzx ebx, word ptr BP_REL(ExtendedFlags) // Get extended flags and put into ebx - and bx, HEX(0f) // Mask off upper 8 bits, now we have active fat in bl - jz LoadFatSector // If fat is mirrored then skip fat calcs - cmp bl, byte ptr BP_REL(NumberOfFats) // Compare bl to number of fats + // Now we have to check the extended flags + // to see which FAT is the active one + // and use it, or if they are mirrored then + // no worries + movzx ebx, word ptr BP_REL(ExtendedFlags) // Get extended flags and put into ebx + and bx, HEX(0f) // Mask off upper 8 bits, now we have active fat in bl + jz LoadFatSector // If fat is mirrored then skip fat calcs + cmp bl, byte ptr BP_REL(NumberOfFats) // Compare bl to number of fats jb GetActiveFatOffset - jmp PrintFileSystemError // If bl is bigger than numfats exit with error + jmp PrintFileSystemError // If bl is bigger than numfats exit with error GetActiveFatOffset: - push eax // Save logical FAT sector number - mov eax, dword ptr BP_REL(SectorsPerFatBig) // Get the number of sectors occupied by one fat in eax - mul ebx // Multiplied by the active FAT index we have in ebx - pop edx // Get logical FAT sector number - add eax, edx // Add the current FAT sector offset + push eax // Save logical FAT sector number + mov eax, dword ptr BP_REL(SectorsPerFatBig) // Get the number of sectors occupied by one fat in eax + mul ebx // Multiplied by the active FAT index we have in ebx + pop edx // Get logical FAT sector number + add eax, edx // Add the current FAT sector offset LoadFatSector: push ecx - mov bx, HEX(9000) // We will load it to [9000:0000h] + mov bx, HEX(9000) // We will load it to [9000:0000h] mov es, bx // EAX holds logical FAT sector number @@ -482,18 +482,18 @@ LoadFatSector: LoadFatSectorAlreadyLoaded: pop ecx - mov eax, dword ptr es:[ecx] // Get FAT entry - and eax, HEX(0fffffff) // Mask off reserved bits + mov eax, dword ptr es:[ecx] // Get FAT entry + and eax, HEX(0fffffff) // Mask off reserved bits ret -FatSectorInCache: // This variable tells us which sector we currently have in memory - .long HEX(0ffffffff) // There is no need to re-read the same sector if we don't have to +FatSectorInCache: // This variable tells us which sector we currently have in memory + .long HEX(0ffffffff) // There is no need to re-read the same sector if we don't have to // Reads cluster number in EAX into [ES:0000] ReadCluster: - // StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors// + // StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors; dec eax dec eax @@ -508,7 +508,7 @@ ReadCluster: add eax, ebx add eax, dword ptr BP_REL(HiddenSectors) pop ebx - add eax, ebx // EAX now contains the logical sector number of the cluster + add eax, ebx // EAX now contains the logical sector number of the cluster xor bx, bx // We will load it to [ES:0000], ES loaded before function call movzx cx, byte ptr BP_REL(SectsPerCluster) call ReadSectors @@ -517,10 +517,10 @@ ReadCluster: // Displays a file not found error message // And reboots PrintFileNotFound: - mov si, offset msgFreeLdr // FreeLdr not found message - call PutChars // Display it - mov si, offset msgAnyKey // Press any key message - call PutChars // Display it + mov si, offset msgFreeLdr // FreeLdr not found message + call PutChars // Display it + mov si, offset msgAnyKey // Press any key message + call PutChars // Display it jmp Reboot diff --git a/reactos/boot/freeldr/bootsect/fat32.asm b/reactos/boot/freeldr/bootsect/fat32.asm index 787a2fc6091..3f3ba02ac78 100644 --- a/reactos/boot/freeldr/bootsect/fat32.asm +++ b/reactos/boot/freeldr/bootsect/fat32.asm @@ -12,109 +12,109 @@ start: jmp short main nop -OEMName db 'FrLdr1.0' -BytesPerSector dw 512 -SectsPerCluster db 0 -ReservedSectors dw 32 -NumberOfFats db 2 -MaxRootEntries dw 0 ; Always zero for FAT32 volumes -TotalSectors dw 0 ; Always zero for FAT32 volumes -MediaDescriptor db 0f8h -SectorsPerFat dw 0 ; Always zero for FAT32 volumes -SectorsPerTrack dw 0 -NumberOfHeads dw 0 -HiddenSectors dd 0 -TotalSectorsBig dd 0 +OEMName db 'FrLdr1.0' +BytesPerSector dw 512 +SectsPerCluster db 0 +ReservedSectors dw 32 +NumberOfFats db 2 +MaxRootEntries dw 0 ; Always zero for FAT32 volumes +TotalSectors dw 0 ; Always zero for FAT32 volumes +MediaDescriptor db 0f8h +SectorsPerFat dw 0 ; Always zero for FAT32 volumes +SectorsPerTrack dw 0 +NumberOfHeads dw 0 +HiddenSectors dd 0 +TotalSectorsBig dd 0 ; FAT32 Inserted Info -SectorsPerFatBig dd 0 -ExtendedFlags dw 0 -FSVersion dw 0 -RootDirStartCluster dd 0 -FSInfoSector dw 0 -BackupBootSector dw 6 -Reserved1 times 12 db 0 +SectorsPerFatBig dd 0 +ExtendedFlags dw 0 +FSVersion dw 0 +RootDirStartCluster dd 0 +FSInfoSector dw 0 +BackupBootSector dw 6 +Reserved1 times 12 db 0 ; End FAT32 Inserted Info -BootDrive db 0 -Reserved db 0 -ExtendSig db 29h -SerialNumber dd 00000000h -VolumeLabel db 'NO NAME ' -FileSystem db 'FAT32 ' +BootDrive db 0 +Reserved db 0 +ExtendSig db 29h +SerialNumber dd 00000000h +VolumeLabel db 'NO NAME ' +FileSystem db 'FAT32 ' main: xor ax,ax ; Setup segment registers mov ds,ax ; Make DS correct mov es,ax ; Make ES correct - mov ss,ax ; Make SS correct - mov bp,7c00h + mov ss,ax ; Make SS correct + mov bp,7c00h mov sp,7c00h ; Setup a stack - cmp BYTE [BYTE bp+BootDrive],BYTE 0xff ; If they have specified a boot drive then use it - jne CheckSectorsPerFat + cmp BYTE [BYTE bp+BootDrive],BYTE 0xff ; If they have specified a boot drive then use it + jne CheckSectorsPerFat - mov [BYTE bp+BootDrive],dl ; Save the boot drive + mov [BYTE bp+BootDrive],dl ; Save the boot drive CheckSectorsPerFat: - cmp WORD [BYTE bp+SectorsPerFat],byte 0x00 ; Check the old 16-bit value of SectorsPerFat - jnz CheckFailed ; If it is non-zero then exit with an error -CheckTotalSectors: ; Check the old 16-bit value of TotalSectors & MaxRootEntries - cmp DWORD [BYTE bp+MaxRootEntries],byte 0x00; by comparing the DWORD at offset MaxRootEntries to zero - jnz CheckFailed ; If it is non-zero then exit with an error + cmp WORD [BYTE bp+SectorsPerFat],byte 0x00 ; Check the old 16-bit value of SectorsPerFat + jnz CheckFailed ; If it is non-zero then exit with an error +CheckTotalSectors: ; Check the old 16-bit value of TotalSectors & MaxRootEntries + cmp DWORD [BYTE bp+MaxRootEntries],byte 0x00; by comparing the DWORD at offset MaxRootEntries to zero + jnz CheckFailed ; If it is non-zero then exit with an error CheckFileSystemVersion: - cmp WORD [BYTE bp+FSVersion],byte 0x00 ; Check the file system version word - jna GetDriveParameters ; It is zero, so continue + cmp WORD [BYTE bp+FSVersion],byte 0x00 ; Check the file system version word + jna GetDriveParameters ; It is zero, so continue CheckFailed: - jmp PrintFileSystemError ; If it is not zero then exit with an error + jmp PrintFileSystemError ; If it is not zero then exit with an error GetDriveParameters: - mov ax,0800h - mov dl,[BYTE bp+BootDrive] ; Get boot drive in dl - int 13h ; Request drive parameters from the bios - jnc CalcDriveSize ; If the call succeeded then calculate the drive size + mov ax,0800h + mov dl,[BYTE bp+BootDrive] ; Get boot drive in dl + int 13h ; Request drive parameters from the bios + jnc CalcDriveSize ; If the call succeeded then calculate the drive size - ; If we get here then the call to the BIOS failed - ; so just set CHS equal to the maximum addressable - ; size - mov cx,0ffffh - mov dh,cl + ; If we get here then the call to the BIOS failed + ; so just set CHS equal to the maximum addressable + ; size + mov cx,0ffffh + mov dh,cl CalcDriveSize: - ; Now that we have the drive geometry - ; lets calculate the drive size - mov bl,ch ; Put the low 8-bits of the cylinder count into BL - mov bh,cl ; Put the high 2-bits in BH - shr bh,6 ; Shift them into position, now BX contains the cylinder count - and cl,3fh ; Mask off cylinder bits from sector count - ; CL now contains sectors per track and DH contains head count - movzx eax,dh ; Move the heads into EAX - movzx ebx,bx ; Move the cylinders into EBX - movzx ecx,cl ; Move the sectors per track into ECX - inc eax ; Make it one based because the bios returns it zero based - inc ebx ; Make the cylinder count one based also - mul ecx ; Multiply heads with the sectors per track, result in edx:eax - mul ebx ; Multiply the cylinders with (heads * sectors) [stored in edx:eax already] + ; Now that we have the drive geometry + ; lets calculate the drive size + mov bl,ch ; Put the low 8-bits of the cylinder count into BL + mov bh,cl ; Put the high 2-bits in BH + shr bh,6 ; Shift them into position, now BX contains the cylinder count + and cl,3fh ; Mask off cylinder bits from sector count + ; CL now contains sectors per track and DH contains head count + movzx eax,dh ; Move the heads into EAX + movzx ebx,bx ; Move the cylinders into EBX + movzx ecx,cl ; Move the sectors per track into ECX + inc eax ; Make it one based because the bios returns it zero based + inc ebx ; Make the cylinder count one based also + mul ecx ; Multiply heads with the sectors per track, result in edx:eax + mul ebx ; Multiply the cylinders with (heads * sectors) [stored in edx:eax already] - ; We now have the total number of sectors as reported - ; by the bios in eax, so store it in our variable - mov [BiosCHSDriveSize],eax + ; We now have the total number of sectors as reported + ; by the bios in eax, so store it in our variable + mov [BiosCHSDriveSize],eax LoadExtraBootCode: - ; First we have to load our extra boot code at - ; sector 14 into memory at [0000:7e00h] - mov eax,0eh - add eax,DWORD [BYTE bp+HiddenSectors] ; Add the number of hidden sectors - mov cx,1 + ; First we have to load our extra boot code at + ; sector 14 into memory at [0000:7e00h] + mov eax,0eh + add eax,DWORD [BYTE bp+HiddenSectors] ; Add the number of hidden sectors + mov cx,1 xor bx,bx - mov es,bx ; Read sector to [0000:7e00h] - mov bx,7e00h - call ReadSectors - jmp StartSearch + mov es,bx ; Read sector to [0000:7e00h] + mov bx,7e00h + call ReadSectors + jmp StartSearch @@ -122,110 +122,110 @@ LoadExtraBootCode: ; EAX has logical sector number to read ; CX has number of sectors to read ReadSectors: - cmp eax,DWORD [BiosCHSDriveSize] ; Check if they are reading a sector outside CHS range - jae ReadSectorsLBA ; Yes - go to the LBA routine - ; If at all possible we want to use LBA routines because - ; They are optimized to read more than 1 sector per read + cmp eax,DWORD [BiosCHSDriveSize] ; Check if they are reading a sector outside CHS range + jae ReadSectorsLBA ; Yes - go to the LBA routine + ; If at all possible we want to use LBA routines because + ; They are optimized to read more than 1 sector per read - pushad ; Save logical sector number & sector count + pushad ; Save logical sector number & sector count -CheckInt13hExtensions: ; Now check if this computer supports extended reads - mov ah,0x41 ; AH = 41h - mov bx,0x55aa ; BX = 55AAh - mov dl,[BYTE bp+BootDrive] ; DL = drive (80h-FFh) - int 13h ; IBM/MS INT 13 Extensions - INSTALLATION CHECK - jc ReadSectorsCHS ; CF set on error (extensions not supported) - cmp bx,0xaa55 ; BX = AA55h if installed - jne ReadSectorsCHS - test cl,1 ; CX = API subset support bitmap - jz ReadSectorsCHS ; Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported +CheckInt13hExtensions: ; Now check if this computer supports extended reads + mov ah,0x41 ; AH = 41h + mov bx,0x55aa ; BX = 55AAh + mov dl,[BYTE bp+BootDrive] ; DL = drive (80h-FFh) + int 13h ; IBM/MS INT 13 Extensions - INSTALLATION CHECK + jc ReadSectorsCHS ; CF set on error (extensions not supported) + cmp bx,0xaa55 ; BX = AA55h if installed + jne ReadSectorsCHS + test cl,1 ; CX = API subset support bitmap + jz ReadSectorsCHS ; Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported - popad ; Restore sector count & logical sector number + popad ; Restore sector count & logical sector number ReadSectorsLBA: - pushad ; Save logical sector number & sector count + pushad ; Save logical sector number & sector count - cmp cx,64 ; Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64 - jbe ReadSectorsSetupDiskAddressPacket ; If we are reading less than 65 sectors then just do the read - mov cx,64 ; Otherwise read only 64 sectors on this loop iteration + cmp cx,64 ; Since the LBA calls only support 0x7F sectors at a time we will limit ourselves to 64 + jbe ReadSectorsSetupDiskAddressPacket ; If we are reading less than 65 sectors then just do the read + mov cx,64 ; Otherwise read only 64 sectors on this loop iteration ReadSectorsSetupDiskAddressPacket: - mov [LBASectorsRead],cx - o32 push byte 0 - push eax ; Put 64-bit logical block address on stack - push es ; Put transfer segment on stack - push bx ; Put transfer offset on stack - push cx ; Set transfer count - push byte 0x10 ; Set size of packet to 10h - mov si,sp ; Setup disk address packet on stack + mov [LBASectorsRead],cx + o32 push byte 0 + push eax ; Put 64-bit logical block address on stack + push es ; Put transfer segment on stack + push bx ; Put transfer offset on stack + push cx ; Set transfer count + push byte 0x10 ; Set size of packet to 10h + mov si,sp ; Setup disk address packet on stack - mov dl,[BYTE bp+BootDrive] ; Drive number - mov ah,42h ; Int 13h, AH = 42h - Extended Read - int 13h ; Call BIOS - jc PrintDiskError ; If the read failed then abort + mov dl,[BYTE bp+BootDrive] ; Drive number + mov ah,42h ; Int 13h, AH = 42h - Extended Read + int 13h ; Call BIOS + jc PrintDiskError ; If the read failed then abort - add sp,byte 0x10 ; Remove disk address packet from stack + add sp,byte 0x10 ; Remove disk address packet from stack - popad ; Restore sector count & logical sector number + popad ; Restore sector count & logical sector number - push bx - mov ebx,DWORD [LBASectorsRead] - add eax,ebx ; Increment sector to read - shl ebx,5 + push bx + mov ebx,DWORD [LBASectorsRead] + add eax,ebx ; Increment sector to read + shl ebx,5 mov dx,es - add dx,bx ; Setup read buffer for next sector + add dx,bx ; Setup read buffer for next sector mov es,dx - pop bx + pop bx - sub cx,[LBASectorsRead] - jnz ReadSectorsLBA ; Read next sector + sub cx,[LBASectorsRead] + jnz ReadSectorsLBA ; Read next sector ret LBASectorsRead: - dd 0 + dd 0 ; Reads logical sectors into [ES:BX] ; EAX has logical sector number to read ; CX has number of sectors to read ReadSectorsCHS: - popad ; Get logical sector number & sector count off stack + popad ; Get logical sector number & sector count off stack ReadSectorsCHSLoop: pushad xor edx,edx - movzx ecx,WORD [BYTE bp+SectorsPerTrack] - div ecx ; Divide logical by SectorsPerTrack - inc dl ; Sectors numbering starts at 1 not 0 - mov cl,dl ; Sector in CL - mov edx,eax - shr edx,16 - div WORD [BYTE bp+NumberOfHeads] ; Divide logical by number of heads - mov dh,dl ; Head in DH - mov dl,[BYTE bp+BootDrive] ; Drive number in DL - mov ch,al ; Cylinder in CX - ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits - ror ah,1 ; in CL shifted to bits 6 & 7 - or cl,ah ; Or with sector number + movzx ecx,WORD [BYTE bp+SectorsPerTrack] + div ecx ; Divide logical by SectorsPerTrack + inc dl ; Sectors numbering starts at 1 not 0 + mov cl,dl ; Sector in CL + mov edx,eax + shr edx,16 + div WORD [BYTE bp+NumberOfHeads] ; Divide logical by number of heads + mov dh,dl ; Head in DH + mov dl,[BYTE bp+BootDrive] ; Drive number in DL + mov ch,al ; Cylinder in CX + ror ah,1 ; Low 8 bits of cylinder in CH, high 2 bits + ror ah,1 ; in CL shifted to bits 6 & 7 + or cl,ah ; Or with sector number mov ax,0201h int 13h ; DISK - READ SECTORS INTO MEMORY ; AL = number of sectors to read, CH = track, CL = sector - ; DH = head, DL = drive, ES:BX -> buffer to fill - ; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read + ; DH = head, DL = drive, ES:BX -> buffer to fill + ; Return: CF set on error, AH = status (see AH=01h), AL = number of sectors read - jc PrintDiskError ; If the read failed then abort + jc PrintDiskError ; If the read failed then abort popad - inc eax ; Increment Sector to Read + inc eax ; Increment Sector to Read mov dx,es - add dx,byte 20h ; Increment read buffer for next sector + add dx,byte 20h ; Increment read buffer for next sector mov es,dx - loop ReadSectorsCHSLoop ; Read next sector + loop ReadSectorsCHSLoop ; Read next sector ret @@ -235,23 +235,23 @@ ReadSectorsCHSLoop: ; Displays a disk error message ; And reboots PrintDiskError: - mov si,msgDiskError ; Bad boot disk message - call PutChars ; Display it + mov si,msgDiskError ; Bad boot disk message + call PutChars ; Display it - jmp Reboot + jmp Reboot ; Displays a file system error message ; And reboots PrintFileSystemError: - mov si,msgFileSystemError ; FreeLdr not found message - call PutChars ; Display it + mov si,msgFileSystemError ; FreeLdr not found message + call PutChars ; Display it Reboot: - mov si,msgAnyKey ; Press any key message - call PutChars ; Display it + mov si,msgAnyKey ; Press any key message + call PutChars ; Display it xor ax,ax - int 16h ; Wait for a keypress - int 19h ; Reboot + int 16h ; Wait for a keypress + int 19h ; Reboot PutChars: lodsb @@ -268,14 +268,14 @@ Done: BiosCHSDriveSize dd 0 -msgDiskError db 'Disk error',0dh,0ah,0 -msgFileSystemError db 'File system error',0dh,0ah,0 -msgAnyKey db 'Press any key to restart',0dh,0ah,0 +msgDiskError db 'Disk error',0dh,0ah,0 +msgFileSystemError db 'File system error',0dh,0ah,0 +msgAnyKey db 'Press any key to restart',0dh,0ah,0 times 509-($-$$) db 0 ; Pad to 509 bytes BootPartition: - db 0 + db 0 BootSignature: dw 0aa55h ; BootSector signature @@ -295,22 +295,22 @@ BootSignature: StartSearch: ; Now we must get the first cluster of the root directory - mov eax,DWORD [BYTE bp+RootDirStartCluster] - cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain - jb ContinueSearch ; If not continue, if so then we didn't find freeldr.sys - jmp PrintFileNotFound + mov eax,DWORD [BYTE bp+RootDirStartCluster] + cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain + jb ContinueSearch ; If not continue, if so then we didn't find freeldr.sys + jmp PrintFileNotFound ContinueSearch: mov bx,2000h - mov es,bx ; Read cluster to [2000:0000h] + mov es,bx ; Read cluster to [2000:0000h] call ReadCluster ; Read the cluster ; Now we have to find our way through the root directory to - ; The OSLOADER.SYS file - xor bx,bx + ; The FREELDR.SYS file + xor bx,bx mov bl,[BYTE bp+SectsPerCluster] - shl bx,4 ; BX = BX * 512 / 32 - mov ax,2000h ; We loaded at 2000:0000 + shl bx,4 ; BX = BX * 512 / 32 + mov ax,2000h ; We loaded at 2000:0000 mov es,ax xor di,di mov si,filename @@ -333,157 +333,157 @@ FindFile: dec bx ; Keep searching till we run out of dir entries jnz FindFile ; Last entry? - ; Get the next root dir cluster and try again until we run out of clusters - mov eax,DWORD [BYTE bp+RootDirStartCluster] - call GetFatEntry - mov [BYTE bp+RootDirStartCluster],eax + ; Get the next root dir cluster and try again until we run out of clusters + mov eax,DWORD [BYTE bp+RootDirStartCluster] + call GetFatEntry + mov [BYTE bp+RootDirStartCluster],eax jmp StartSearch FoundFile: - ; Display "Loading FreeLoader..." message - mov si,msgLoading ; Loading message - call PutChars ; Display it + ; Display "Loading FreeLoader..." message + mov si,msgLoading ; Loading message + call PutChars ; Display it - xor di,di ; ES:DI has dir entry + xor di,di ; ES:DI has dir entry xor dx,dx mov ax,WORD [es:di+14h] ; Get start cluster high word - shl eax,16 + shl eax,16 mov ax,WORD [es:di+1ah] ; Get start cluster low word CheckStartCluster: - cmp eax,2 ; Check and see if the start cluster starts at cluster 2 or above - jnb CheckEndCluster ; If so then continue - jmp PrintFileSystemError ; If not exit with error + cmp eax,2 ; Check and see if the start cluster starts at cluster 2 or above + jnb CheckEndCluster ; If so then continue + jmp PrintFileSystemError ; If not exit with error CheckEndCluster: - cmp eax,0ffffff8h ; Check and see if the start cluster is and end of cluster chain indicator - jb InitializeLoadSegment ; If not then continue - jmp PrintFileSystemError ; If so exit with error + cmp eax,0ffffff8h ; Check and see if the start cluster is and end of cluster chain indicator + jb InitializeLoadSegment ; If not then continue + jmp PrintFileSystemError ; If so exit with error InitializeLoadSegment: mov bx,800h mov es,bx LoadFile: - cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain - jae LoadFileDone ; If so continue, if not then read the next one - push eax + cmp eax,0ffffff8h ; Check to see if this is the last cluster in the chain + jae LoadFileDone ; If so continue, if not then read the next one + push eax xor bx,bx ; Load ROSLDR starting at 0000:8000h - push es - call ReadCluster - pop es + push es + call ReadCluster + pop es - xor bx,bx + xor bx,bx mov bl,[BYTE bp+SectsPerCluster] - shl bx,5 ; BX = BX * 512 / 16 - mov ax,es ; Increment the load address by - add ax,bx ; The size of a cluster - mov es,ax + shl bx,5 ; BX = BX * 512 / 16 + mov ax,es ; Increment the load address by + add ax,bx ; The size of a cluster + mov es,ax - pop eax - push es - call GetFatEntry ; Get the next entry - pop es + pop eax + push es + call GetFatEntry ; Get the next entry + pop es - jmp LoadFile ; Load the next cluster (if any) + jmp LoadFile ; Load the next cluster (if any) LoadFileDone: - mov dl,[BYTE bp+BootDrive] ; Load boot drive into DL - mov dh,[BootPartition] ; Load boot partition into DH + mov dl,[BYTE bp+BootDrive] ; Load boot drive into DL + mov dh,[BootPartition] ; Load boot partition into DH - push 0 ; push segment (0x0000) - mov eax, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax - add eax, 0x8000 ; RVA -> VA - push ax ; push offset - retf ; Transfer control to FreeLoader + push 0 ; push segment (0x0000) + mov eax, [0x8000 + 0xA8] ; load the RVA of the EntryPoint into eax + add eax, 0x8000 ; RVA -> VA + push ax ; push offset + retf ; Transfer control to FreeLoader ; Returns the FAT entry for a given cluster number ; On entry EAX has cluster number ; On return EAX has FAT entry for that cluster GetFatEntry: - shl eax,2 ; EAX = EAX * 4 (since FAT32 entries are 4 bytes) - mov ecx,eax ; Save this for later in ECX - xor edx,edx - movzx ebx,WORD [BYTE bp+BytesPerSector] - push ebx - div ebx ; FAT Sector Number = EAX / BytesPerSector - movzx ebx,WORD [BYTE bp+ReservedSectors] - add eax,ebx ; FAT Sector Number += ReservedSectors - mov ebx,DWORD [BYTE bp+HiddenSectors] - add eax,ebx ; FAT Sector Number += HiddenSectors - pop ebx - dec ebx - and ecx,ebx ; FAT Offset Within Sector = ECX % BytesPerSector - ; EAX holds logical FAT sector number - ; ECX holds FAT entry offset + shl eax,2 ; EAX = EAX * 4 (since FAT32 entries are 4 bytes) + mov ecx,eax ; Save this for later in ECX + xor edx,edx + movzx ebx,WORD [BYTE bp+BytesPerSector] + push ebx + div ebx ; FAT Sector Number = EAX / BytesPerSector + movzx ebx,WORD [BYTE bp+ReservedSectors] + add eax,ebx ; FAT Sector Number += ReservedSectors + mov ebx,DWORD [BYTE bp+HiddenSectors] + add eax,ebx ; FAT Sector Number += HiddenSectors + pop ebx + dec ebx + and ecx,ebx ; FAT Offset Within Sector = ECX % BytesPerSector + ; EAX holds logical FAT sector number + ; ECX holds FAT entry offset - ; Now we have to check the extended flags - ; to see which FAT is the active one - ; and use it, or if they are mirrored then - ; no worries - movzx ebx,WORD [BYTE bp+ExtendedFlags] ; Get extended flags and put into ebx - and bx,0x0f ; Mask off upper 8 bits, now we have active fat in bl - jz LoadFatSector ; If fat is mirrored then skip fat calcs - cmp bl,[BYTE bp+NumberOfFats] ; Compare bl to number of fats - jb GetActiveFatOffset - jmp PrintFileSystemError ; If bl is bigger than numfats exit with error + ; Now we have to check the extended flags + ; to see which FAT is the active one + ; and use it, or if they are mirrored then + ; no worries + movzx ebx,WORD [BYTE bp+ExtendedFlags] ; Get extended flags and put into ebx + and bx,0x0f ; Mask off upper 8 bits, now we have active fat in bl + jz LoadFatSector ; If fat is mirrored then skip fat calcs + cmp bl,[BYTE bp+NumberOfFats] ; Compare bl to number of fats + jb GetActiveFatOffset + jmp PrintFileSystemError ; If bl is bigger than numfats exit with error GetActiveFatOffset: - push eax ; Save logical FAT sector number - mov eax,[BYTE bp+SectorsPerFatBig] ; Get the number of sectors occupied by one fat in eax - mul ebx ; Multiplied by the active FAT index we have in ebx - pop edx ; Get logical FAT sector number - add eax,edx ; Add the current FAT sector offset + push eax ; Save logical FAT sector number + mov eax,[BYTE bp+SectorsPerFatBig] ; Get the number of sectors occupied by one fat in eax + mul ebx ; Multiplied by the active FAT index we have in ebx + pop edx ; Get logical FAT sector number + add eax,edx ; Add the current FAT sector offset LoadFatSector: - push ecx - ; EAX holds logical FAT sector number - ; Check if we have already loaded it - cmp eax,DWORD [FatSectorInCache] - je LoadFatSectorAlreadyLoaded + push ecx + ; EAX holds logical FAT sector number + ; Check if we have already loaded it + cmp eax,DWORD [FatSectorInCache] + je LoadFatSectorAlreadyLoaded - mov DWORD [FatSectorInCache],eax + mov DWORD [FatSectorInCache],eax mov bx,9000h mov es,bx - xor bx,bx ; We will load it to [9000:0000h] - mov cx,1 - call ReadSectors + xor bx,bx ; We will load it to [9000:0000h] + mov cx,1 + call ReadSectors LoadFatSectorAlreadyLoaded: mov bx,9000h mov es,bx - pop ecx - mov eax,DWORD [es:ecx] ; Get FAT entry - and eax,0fffffffh ; Mask off reserved bits + pop ecx + mov eax,DWORD [es:ecx] ; Get FAT entry + and eax,0fffffffh ; Mask off reserved bits - ret + ret -FatSectorInCache: ; This variable tells us which sector we currently have in memory - dd 0ffffffffh ; There is no need to re-read the same sector if we don't have to +FatSectorInCache: ; This variable tells us which sector we currently have in memory + dd 0ffffffffh ; There is no need to re-read the same sector if we don't have to ; Reads cluster number in EAX into [ES:0000] ReadCluster: - ; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors; + ; StartSector = ((Cluster - 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors; - dec eax - dec eax - xor edx,edx - movzx ebx,BYTE [BYTE bp+SectsPerCluster] - mul ebx - push eax - xor edx,edx - movzx eax,BYTE [BYTE bp+NumberOfFats] - mul DWORD [BYTE bp+SectorsPerFatBig] - movzx ebx,WORD [BYTE bp+ReservedSectors] - add eax,ebx - add eax,DWORD [BYTE bp+HiddenSectors] - pop ebx - add eax,ebx ; EAX now contains the logical sector number of the cluster - xor bx,bx ; We will load it to [ES:0000], ES loaded before function call - movzx cx,BYTE [BYTE bp+SectsPerCluster] - call ReadSectors - ret + dec eax + dec eax + xor edx,edx + movzx ebx,BYTE [BYTE bp+SectsPerCluster] + mul ebx + push eax + xor edx,edx + movzx eax,BYTE [BYTE bp+NumberOfFats] + mul DWORD [BYTE bp+SectorsPerFatBig] + movzx ebx,WORD [BYTE bp+ReservedSectors] + add eax,ebx + add eax,DWORD [BYTE bp+HiddenSectors] + pop ebx + add eax,ebx ; EAX now contains the logical sector number of the cluster + xor bx,bx ; We will load it to [ES:0000], ES loaded before function call + movzx cx,BYTE [BYTE bp+SectsPerCluster] + call ReadSectors + ret ; Displays a file not found error message @@ -494,7 +494,7 @@ PrintFileNotFound: mov si,msgAnyKey ; Press any key message call PutChars ; Display it - jmp Reboot + jmp Reboot msgFreeLdr db 'freeldr.sys not found',0dh,0ah,0 filename db 'FREELDR SYS' diff --git a/reactos/boot/freeldr/bootsect/faty.S b/reactos/boot/freeldr/bootsect/faty.S index 018160b1898..0d57999bc42 100644 --- a/reactos/boot/freeldr/bootsect/faty.S +++ b/reactos/boot/freeldr/bootsect/faty.S @@ -1,8 +1,8 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Bootsector - * FILE: boot/freeldr/bootsect/fatx.S - * PURPOSE: Combined FAT16 and FAT32 boot sector + * FILE: boot/freeldr/bootsect/faty.S + * PURPOSE: Combined FAT12, FAT16 and FAT32 boot sector * PROGRAMMERS: Brian Palmer * Timo Kreuzer */