mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 21:36:11 +00:00
[BOOTSECTOR]
Convert fat bootsector to new syntax svn path=/trunk/; revision=52197
This commit is contained in:
parent
4a4060ce3c
commit
7cc02537dd
2 changed files with 434 additions and 2 deletions
|
@ -4,13 +4,12 @@ if(ARCH MATCHES i386 OR ARCH MATCHES amd64)
|
|||
CreateBootSectorTarget2(dosmbr ${CMAKE_CURRENT_SOURCE_DIR}/dosmbr.S ${CMAKE_CURRENT_BINARY_DIR}/dosmbr.bin 7c00)
|
||||
#CreateBootSectorTarget2(ext2 ${CMAKE_CURRENT_SOURCE_DIR}/ext2.S ${CMAKE_CURRENT_BINARY_DIR}/ext2.bin 0)
|
||||
CreateBootSectorTarget2(fat32 ${CMAKE_CURRENT_SOURCE_DIR}/fat32.S ${CMAKE_CURRENT_BINARY_DIR}/fat32.bin 7c00)
|
||||
#CreateBootSectorTarget2(fat ${CMAKE_CURRENT_SOURCE_DIR}/fat.S ${CMAKE_CURRENT_BINARY_DIR}/fat.bin 0)
|
||||
CreateBootSectorTarget2(fat ${CMAKE_CURRENT_SOURCE_DIR}/fat.S ${CMAKE_CURRENT_BINARY_DIR}/fat.bin 7c00)
|
||||
CreateBootSectorTarget2(isoboot ${CMAKE_CURRENT_SOURCE_DIR}/isoboot.S ${CMAKE_CURRENT_BINARY_DIR}/isoboot.bin 7000)
|
||||
CreateBootSectorTarget2(isobtrt ${CMAKE_CURRENT_SOURCE_DIR}/isobtrt.S ${CMAKE_CURRENT_BINARY_DIR}/isobtrt.bin 7000)
|
||||
|
||||
if(NOT MSVC)
|
||||
CreateBootSectorTarget(ext2 ${CMAKE_CURRENT_SOURCE_DIR}/ext2.asm ${CMAKE_CURRENT_BINARY_DIR}/ext2.bin 0)
|
||||
CreateBootSectorTarget(fat ${CMAKE_CURRENT_SOURCE_DIR}/fat.asm ${CMAKE_CURRENT_BINARY_DIR}/fat.bin 0)
|
||||
endif()
|
||||
|
||||
add_cd_file(TARGET dosmbr DESTINATION loader NO_CAB FILE ${CMAKE_CURRENT_BINARY_DIR}/dosmbr.bin FOR all)
|
||||
|
|
433
reactos/boot/freeldr/bootsect/fat.S
Normal file
433
reactos/boot/freeldr/bootsect/fat.S
Normal file
|
@ -0,0 +1,433 @@
|
|||
// FAT.ASM
|
||||
// FAT12/16 Boot Sector
|
||||
// Copyright (c) 1998, 2001, 2002 Brian Palmer
|
||||
|
||||
|
||||
|
||||
// This is a FAT12/16 file system boot sector
|
||||
// that searches the entire root directory
|
||||
// for the file freeldr.sys and loads it into
|
||||
// memory.
|
||||
//
|
||||
// The stack is set to 0000:7BF2 so that the first
|
||||
// WORD pushed will be placed at 0000:7BF0
|
||||
//
|
||||
// The DWORD at 0000:7BFC or BP-04h is the logical
|
||||
// sector number of the start of the data area.
|
||||
//
|
||||
// The DWORD at 0000:7BF8 or BP-08h is the total
|
||||
// sector count of the boot drive as reported by
|
||||
// the computers bios.
|
||||
//
|
||||
// The WORD at 0000:7BF6 or BP-0ah is the offset
|
||||
// of the ReadSectors function in the boot sector.
|
||||
//
|
||||
// The WORD at 0000:7BF4 or BP-0ch is the offset
|
||||
// of the ReadCluster function in the boot sector.
|
||||
//
|
||||
// The WORD at 0000:7BF2 or BP-0eh is the offset
|
||||
// of the PutChars function in the boot sector.
|
||||
//
|
||||
// When it locates freeldr.sys on the disk it will
|
||||
// load the first sector of the file to 0000:8000
|
||||
// With the help of this sector we should be able
|
||||
// to load the entire file off the disk, no matter
|
||||
// how fragmented it is.
|
||||
//
|
||||
// We load the entire FAT table into memory at
|
||||
// 7000:0000. This improves the speed of floppy disk
|
||||
// boots dramatically.
|
||||
|
||||
#include <asm.inc>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
// org 7c00h
|
||||
|
||||
.code16
|
||||
|
||||
start:
|
||||
jmp main
|
||||
nop
|
||||
|
||||
OEMName:
|
||||
.ascii "FrLdr1.0"
|
||||
BytesPerSector:
|
||||
.word 512
|
||||
SectsPerCluster:
|
||||
.byte 1
|
||||
ReservedSectors:
|
||||
.word 1
|
||||
NumberOfFats:
|
||||
.byte 2
|
||||
MaxRootEntries:
|
||||
.word 224
|
||||
TotalSectors:
|
||||
.word 2880
|
||||
MediaDescriptor:
|
||||
.byte HEX(0f0)
|
||||
SectorsPerFat:
|
||||
.word 9
|
||||
SectorsPerTrack:
|
||||
.word 18
|
||||
NumberOfHeads:
|
||||
.word 2
|
||||
HiddenSectors:
|
||||
.long 0
|
||||
TotalSectorsBig:
|
||||
.long 0
|
||||
BootDrive:
|
||||
.byte HEX(0ff)
|
||||
Reserved:
|
||||
.byte 0
|
||||
ExtendSig:
|
||||
.byte HEX(29)
|
||||
SerialNumber:
|
||||
.long 00000000
|
||||
VolumeLabel:
|
||||
.ascii "NO NAME "
|
||||
FileSystem:
|
||||
.ascii "FAT12 "
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
// If we get here then the call to the BIOS failed
|
||||
// so just set CHS equal to the maximum addressable
|
||||
// size
|
||||
mov cx, HEX(0ffff)
|
||||
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, 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]
|
||||
|
||||
// We now have the total number of sectors as reported
|
||||
// by the bios in eax, so store it in our variable
|
||||
mov dword ptr [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 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
|
||||
// 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 bx, word ptr BP_REL(BytesPerSector)
|
||||
add ax, bx
|
||||
dec ax
|
||||
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
|
||||
adc word ptr [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, 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
|
||||
|
||||
FoundFreeLoader:
|
||||
// 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 ptr es:[di + HEX(1a)] // Get start cluster
|
||||
push ax // Save start cluster
|
||||
push HEX(800) // 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 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
|
||||
// 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, [HEX(8000) + HEX(0A8)] // load the RVA of the EntryPoint into eax
|
||||
add bx, HEX(8003) // RVA -> VA and skip 3 bytes (jump to fathelper code)
|
||||
push bx // push offset
|
||||
retf // Transfer control to FreeLoader
|
||||
|
||||
|
||||
|
||||
|
||||
// Displays an error message
|
||||
// And reboots
|
||||
ErrBoot:
|
||||
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
|
||||
xor ax, ax
|
||||
int HEX(16) // Wait for a keypress
|
||||
int HEX(19) // Reboot
|
||||
|
||||
PutChars:
|
||||
lodsb
|
||||
or al,al
|
||||
jz short Done
|
||||
mov ah, HEX(0e)
|
||||
mov bx, 7
|
||||
int HEX(10)
|
||||
jmp short PutChars
|
||||
Done:
|
||||
ret
|
||||
|
||||
// Displays a bad boot message
|
||||
// And reboots
|
||||
BadBoot:
|
||||
mov si, offset msgDiskError // Bad boot disk message
|
||||
call PutChars // Display it
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
|
||||
// Reads logical sectors into [ES:BX]
|
||||
// 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, 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
|
||||
|
||||
ReadSectorsLBA:
|
||||
popa
|
||||
ReadSectorsLBALoop:
|
||||
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
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
popa // Restore sector count & logical sector number
|
||||
|
||||
inc ax // Increment Sector to Read
|
||||
adc dx, 0
|
||||
|
||||
push bx
|
||||
mov bx, es
|
||||
add bx, HEX(20) // Increment read buffer for next sector
|
||||
mov es, bx
|
||||
pop bx
|
||||
|
||||
loop ReadSectorsLBALoop // Read next sector
|
||||
|
||||
ret
|
||||
|
||||
|
||||
// Reads logical sectors into [ES:BX]
|
||||
// DX:AX has logical sector number to read
|
||||
// CX has number of sectors to read
|
||||
// CarryFlag set on error
|
||||
ReadSectorsCHS:
|
||||
popa
|
||||
ReadSectorsCHSLoop:
|
||||
pusha
|
||||
xchg ax, cx
|
||||
xchg ax, dx
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
jc BadBoot
|
||||
|
||||
popa
|
||||
inc ax //Increment Sector to Read
|
||||
jnz NoCarryCHS
|
||||
inc dx
|
||||
|
||||
|
||||
NoCarryCHS:
|
||||
push bx
|
||||
mov bx, es
|
||||
add bx, HEX(20)
|
||||
mov es, bx
|
||||
pop bx
|
||||
// Increment read buffer for next sector
|
||||
loop ReadSectorsCHSLoop // Read next sector
|
||||
|
||||
ret
|
||||
|
||||
|
||||
msgDiskError:
|
||||
.asciz "Disk error\r\n"
|
||||
msgFreeLdr:
|
||||
.asciz "ldr not found\r\n"
|
||||
// Sorry, need the space...
|
||||
//msgAnyKey:
|
||||
// .asciz "Press any key to restart\r\n"
|
||||
filename:
|
||||
.ascii "FREELDR SYS"
|
||||
|
||||
.org 509 // Pad to 509 bytes
|
||||
|
||||
BootPartition:
|
||||
.byte 0
|
||||
|
||||
BootSignature:
|
||||
.word HEX(0aa55) // BootSector signature
|
||||
|
||||
.endcode16
|
||||
|
||||
END
|
Loading…
Add table
Add a link
Reference in a new issue