TARGET = i386
+OBJS = $(TARGET)/arch.S $(TARGET)/boot.S $(TARGET)/mb.S $(TARGET)/mem.S $(TARGET)/disk.S
+
.PHONY : clean
all: arch.a
-arch.a:
+arch.a: $(OBJS)
$(MAKE) -C $(TARGET)
clean:
int $0x13
jc _get_heads_error
- incb %dh
movzbl %dh,%edx
+ incl %edx
movl %edx,_biosdisk_retval
jmp _get_heads_done
ret
+/*
+ * BOOL BiosInt13GetDriveParameters(ULONG Drive, PGEOMETRY Geometry);
+ */
+_bios_int13_cylinders:
+ .long 0
+_bios_int13_heads:
+ .long 0
+_bios_int13_sectors:
+ .long 0
+_bios_int13_bytes_per_sector:
+ .long 0
+_bios_int13_drive_parameters_struct_address:
+ .long 0
+EXTERN(_BiosInt13GetDriveParameters)
+ .code32
+
+ push %ebx
+ push %ecx
+ push %edx
+ push %edi
+ push %esi
+ push %es
+
+ /* Get drive */
+ movl 0x1c(%esp),%eax
+ movl %eax,_biosdisk_drive
+ movl 0x20(%esp),%eax
+ movl %eax,_bios_int13_drive_parameters_struct_address
+
+ call switch_to_real
+
+ .code16
+
+ movb $0x08,%ah
+ movb _biosdisk_drive,%dl
+ int $0x13
+ jc _BiosInt13GetDriveParameters_Error
+
+ // Get the heads
+ movzbl %dh,%eax
+ incl %eax
+ movl %eax,_bios_int13_heads
+
+ // Get the sectors
+ movw %cx,%dx
+ andb $0x3f,%dl
+ movzbl %dl,%edx
+ movl %edx,_bios_int13_sectors
+
+ // Get the cylinders
+ xorl %edx,%edx
+ andb $0xc0,%cl
+ shrb $0x06,%cl
+ movb %cl,%dh
+ movb %ch,%dl
+ incl %edx
+ movl %edx,_bios_int13_cylinders
+
+ // Get the bytes per sector
+ movl $512,_bios_int13_bytes_per_sector // Just assume 512 bytes per sector
+ movl $0x01,_biosdisk_retval
+ jmp _BiosInt13GetDriveParameters_Done
+
+_BiosInt13GetDriveParameters_Error:
+ movl $0x00,_biosdisk_retval
+
+_BiosInt13GetDriveParameters_Done:
+
+ call switch_to_prot
+
+ .code32
+
+ // Copy drive parameters to structure
+ movl $_bios_int13_cylinders,%esi
+ movl _bios_int13_drive_parameters_struct_address,%edi
+ movl $0x04,%ecx
+ cld
+ rep movsl
+
+ movl _biosdisk_retval,%eax // Get return value
+
+ pop %es
+ pop %esi
+ pop %edi
+ pop %edx
+ pop %ecx
+ pop %ebx
+
+ ret
+
}
// Now try to read in the block
- if (!DiskReadMultipleLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
+ if (!DiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
{
FreeMemory(CacheBlock->BlockData);
FreeMemory(CacheBlock);
#define BOCHS_OUTPUT_PORT 0xe9
-//ULONG DebugPort = RS232;
+ULONG DebugPort = RS232;
//ULONG DebugPort = SCREEN;
-ULONG DebugPort = BOCHS;
+//ULONG DebugPort = BOCHS;
ULONG ComPort = COM1;
-ULONG BaudRate = 19200;
+//ULONG BaudRate = 19200;
+ULONG BaudRate = 115200;
BOOL DebugStartOfLine = TRUE;
} GEOMETRY, *PGEOMETRY;
+//
+// Define the structure of a partition table entry
+//
+typedef struct _PARTITION_TABLE_ENTRY
+{
+ BYTE BootIndicator; // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only)
+ BYTE StartHead; // Beginning head number
+ BYTE StartSector; // Beginning sector (2 high bits of cylinder #)
+ BYTE StartCylinder; // Beginning cylinder# (low order bits of cylinder #)
+ BYTE SystemIndicator; // System indicator
+ BYTE EndHead; // Ending head number
+ BYTE EndSector; // Ending sector (2 high bits of cylinder #)
+ BYTE EndCylinder; // Ending cylinder# (low order bits of cylinder #)
+ DWORD SectorCountBeforePartition; // Number of sectors preceding the partition
+ DWORD PartitionSectorCount; // Number of sectors in the partition
+
+} PACKED PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
+
+//
+// Define the structure of the master boot record
+//
+typedef struct _MASTER_BOOT_RECORD
+{
+ BYTE MasterBootRecordCodeAndData[0x1be];
+ PARTITION_TABLE_ENTRY PartitionTable[4];
+ WORD MasterBootRecordMagic;
+
+} PACKED MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
+
+//
+// Partition type defines
+//
+#define PARTITION_ENTRY_UNUSED 0x00 // Entry unused
+#define PARTITION_FAT_12 0x01 // 12-bit FAT entries
+#define PARTITION_XENIX_1 0x02 // Xenix
+#define PARTITION_XENIX_2 0x03 // Xenix
+#define PARTITION_FAT_16 0x04 // 16-bit FAT entries
+#define PARTITION_EXTENDED 0x05 // Extended partition entry
+#define PARTITION_HUGE 0x06 // Huge partition MS-DOS V4
+#define PARTITION_IFS 0x07 // IFS Partition
+#define PARTITION_OS2BOOTMGR 0x0A // OS/2 Boot Manager/OPUS/Coherent swap
+#define PARTITION_FAT32 0x0B // FAT32
+#define PARTITION_FAT32_XINT13 0x0C // FAT32 using extended int13 services
+#define PARTITION_XINT13 0x0E // Win95 partition using extended int13 services
+#define PARTITION_XINT13_EXTENDED 0x0F // Same as type 5 but uses extended int13 services
+#define PARTITION_PREP 0x41 // PowerPC Reference Platform (PReP) Boot Partition
+#define PARTITION_LDM 0x42 // Logical Disk Manager partition
+#define PARTITION_UNIX 0x63 // Unix
+
///////////////////////////////////////////////////////////////////////////////////////
//
// BIOS Disk Functions
int get_heads(int drive); // Implemented in asmcode.S
int get_cylinders(int drive); // Implemented in asmcode.S
int get_sectors(int drive); // Implemented in asmcode.S
+BOOL BiosInt13GetDriveParameters(ULONG Drive, PGEOMETRY Geometry); // Implemented in disk.S
///////////////////////////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////////////////////////
VOID DiskError(PUCHAR ErrorString);
BOOL DiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry);
-BOOL DiskSetDriveGeometry(ULONG DriveNumber, ULONG Cylinders, ULONG Heads, ULONG Sectors, ULONG BytesPerSector);
-BOOL DiskReadMultipleLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer);
-BOOL DiskReadLogicalSector(ULONG DriveNumber, ULONG SectorNumber, PVOID Buffer);
+BOOL DiskReadLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer);
+
+///////////////////////////////////////////////////////////////////////////////////////
+//
+// Fixed Disk Partition Management Functions
+//
+///////////////////////////////////////////////////////////////////////////////////////
+BOOL DiskIsDriveRemovable(ULONG DriveNumber);
+BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOL DiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOL DiskReadBootRecord(ULONG DriveNumber, ULONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
#endif // defined __DISK_H
include ../rules.mk
-OBJS = disk.o geometry.o
+OBJS = disk.o geometry.o partition.o
.PHONY : clean
geometry.o: geometry.c ../disk.h
$(CC) $(FLAGS) -o geometry.o -c geometry.c
+partition.o: partition.c ../disk.h
+ $(CC) $(FLAGS) -o partition.o -c partition.c
+
clean:
- $(RM) *.o
- $(RM) *.a
}
}
-BOOL DiskReadMultipleLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
+BOOL DiskReadLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
ULONG PhysicalSector;
ULONG PhysicalHead;
return TRUE;
}
-
-BOOL DiskReadLogicalSector(ULONG DriveNumber, ULONG SectorNumber, PVOID Buffer)
-{
- ULONG PhysicalSector;
- ULONG PhysicalHead;
- ULONG PhysicalTrack;
- GEOMETRY DriveGeometry;
-
- DbgPrint((DPRINT_DISK, "ReadLogicalSector() DriveNumber: 0x%x SectorNumber: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, Buffer));
-
- //
- // Check to see if it is a fixed disk drive
- // If so then check to see if Int13 extensions work
- // If they do then use them, otherwise default back to BIOS calls
- //
- if ((DriveNumber >= 0x80) && (BiosInt13ExtensionsSupported(DriveNumber)))
- {
- DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. BiosInt13ExtensionsSupported(%d) = %s\n", DriveNumber, BiosInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
-
- //
- // LBA is easy, nothing to calculate
- // Just do the read
- //
- if (!BiosInt13ReadExtended(DriveNumber, SectorNumber, 1, Buffer))
- {
- DiskError("Disk read error.");
- return FALSE;
- }
- }
- else
- {
- //
- // Get the drive geometry
- //
- if (!DiskGetDriveGeometry(DriveNumber, &DriveGeometry))
- {
- return FALSE;
- }
-
- //
- // Calculate the physical disk offsets
- //
- PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
- PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
- PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
-
- DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalHead: %d\n", PhysicalHead));
- DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalTrack: %d\n", PhysicalTrack));
- DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalSector: %d\n", PhysicalSector));
-
- //
- // Make sure the read is within the geometry boundaries
- //
- if ((PhysicalHead >= DriveGeometry.Heads) ||
- (PhysicalTrack >= DriveGeometry.Cylinders) ||
- (PhysicalSector > DriveGeometry.Sectors))
- {
- DiskError("Disk read exceeds drive geometry limits.");
- return FALSE;
- }
-
- //
- // Perform the read
- //
- if (!BiosInt13Read(DriveNumber, PhysicalHead, PhysicalTrack, PhysicalSector, 1, Buffer))
- {
- DiskError("Disk read error.");
- return FALSE;
- }
- }
-
- return TRUE;
-}
#include <mm.h>
-typedef struct
-{
- LIST_ITEM ListEntry;
-
- ULONG DriveNumber;
- GEOMETRY DriveGeometry;
-
-} DRIVE_GEOMETRY, *PDRIVE_GEOMETRY;
-
-
-PDRIVE_GEOMETRY DriveGeometryListHead = NULL;
-
-
BOOL DiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry)
{
- PDRIVE_GEOMETRY DriveGeometryListEntry;
-
- //
- // Search the drive geometry list for the requested drive
- //
- DriveGeometryListEntry = DriveGeometryListHead;
- while (DriveGeometryListEntry != NULL)
- {
- //
- // Check to see if this is the drive we want
- //
- if (DriveGeometryListEntry->DriveNumber == DriveNumber)
- {
- //
- // Yep - return the information
- //
- RtlCopyMemory(DriveGeometry, &DriveGeometryListEntry->DriveGeometry, sizeof(GEOMETRY));
- return TRUE;
- }
-
- //
- // Nope, get next item
- //
- DriveGeometryListEntry = (PDRIVE_GEOMETRY)RtlListGetNext((PLIST_ITEM)DriveGeometryListEntry);
- }
-
- DiskError("Drive geometry unknown.");
- return FALSE;
-}
-
-BOOL DiskSetDriveGeometry(ULONG DriveNumber, ULONG Cylinders, ULONG Heads, ULONG Sectors, ULONG BytesPerSector)
-{
- PDRIVE_GEOMETRY DriveGeometryListEntry;
-
- //
- // Search the drive geometry list for the requested drive
- //
- DriveGeometryListEntry = DriveGeometryListHead;
- while (DriveGeometryListEntry != NULL)
- {
- //
- // Check to see if this is the drive
- //
- if (DriveGeometryListEntry->DriveNumber == DriveNumber)
- {
- //
- // Yes, we already have this drive's geometry information
- // so just return
- //
- return TRUE;
- }
-
- //
- // Nope, get next item
- //
- DriveGeometryListEntry = (PDRIVE_GEOMETRY)RtlListGetNext((PLIST_ITEM)DriveGeometryListEntry);
- }
-
- //
- // If we get here then this is a new drive and we have
- // to add it's information to our list
- //
- DriveGeometryListEntry = (PDRIVE_GEOMETRY)AllocateMemory(sizeof(DRIVE_GEOMETRY));
- if (DriveGeometryListEntry == NULL)
+ // For now just return the geometry as the BIOS reports it
+ // BytesPerSector is always set to 512 by BiosInt13GetDriveParameters()
+ if (!BiosInt13GetDriveParameters(DriveNumber, DriveGeometry))
{
+ DiskError("Drive geometry unknown.");
return FALSE;
}
- RtlZeroMemory(DriveGeometryListEntry, sizeof(DRIVE_GEOMETRY));
- DriveGeometryListEntry->DriveNumber = DriveNumber;
- DriveGeometryListEntry->DriveGeometry.Cylinders = Cylinders;
- DriveGeometryListEntry->DriveGeometry.Heads = Heads;
- DriveGeometryListEntry->DriveGeometry.Sectors = Sectors;
- DriveGeometryListEntry->DriveGeometry.BytesPerSector = BytesPerSector;
-
- if (DriveGeometryListHead == NULL)
- {
- DriveGeometryListHead = DriveGeometryListEntry;
- }
- else
- {
- RtlListInsertTail((PLIST_ITEM)DriveGeometryListHead, (PLIST_ITEM)DriveGeometryListEntry);
- }
-
return TRUE;
}
--- /dev/null
+/*
+ * FreeLoader
+ * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <freeldr.h>
+#include <disk.h>
+#include <rtl.h>
+#include <mm.h>
+#include <debug.h>
+
+
+
+BOOL DiskIsDriveRemovable(ULONG DriveNumber)
+{
+ // Hard disks use drive numbers >= 0x80
+ // So if the drive number indicates a hard disk
+ // then return FALSE
+ if (DriveNumber >= 0x80)
+ {
+ return FALSE;
+ }
+
+ // Drive is a floppy diskette so return TRUE
+ return TRUE;
+}
+
+BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
+{
+ ULONG BootablePartitionCount = 0;
+ MASTER_BOOT_RECORD MasterBootRecord;
+
+ // Read master boot record
+ if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
+ {
+ return FALSE;
+ }
+
+ // Count the bootable partitions
+ if (MasterBootRecord.PartitionTable[0].BootIndicator == 0x80)
+ {
+ BootablePartitionCount++;
+ BootPartition = 0;
+ }
+ if (MasterBootRecord.PartitionTable[1].BootIndicator == 0x80)
+ {
+ BootablePartitionCount++;
+ BootPartition = 1;
+ }
+ if (MasterBootRecord.PartitionTable[2].BootIndicator == 0x80)
+ {
+ BootablePartitionCount++;
+ BootPartition = 2;
+ }
+ if (MasterBootRecord.PartitionTable[3].BootIndicator == 0x80)
+ {
+ BootablePartitionCount++;
+ BootPartition = 3;
+ }
+
+ // Make sure there was only one bootable partition
+ if (BootablePartitionCount != 1)
+ {
+ DiskError("Too many bootable partitions or none found.");
+ return FALSE;
+ }
+
+ // Copy the partition table entry
+ RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[BootPartition], sizeof(PARTITION_TABLE_ENTRY));
+
+ return TRUE;
+}
+
+BOOL DiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
+{
+ MASTER_BOOT_RECORD MasterBootRecord;
+ PARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
+ ULONG ExtendedPartitionNumber;
+ ULONG Index;
+
+ // Read master boot record
+ if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
+ {
+ return FALSE;
+ }
+
+ // If they are asking for a primary
+ // partition then things are easy
+ if (PartitionNumber < 5)
+ {
+ // PartitionNumber is one-based and we need it zero-based
+ PartitionNumber--;
+
+ // Copy the partition table entry
+ RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[PartitionNumber], sizeof(PARTITION_TABLE_ENTRY));
+
+ return TRUE;
+ }
+ else
+ {
+ // They want an extended partition entry so we will need
+ // to loop through all the extended partitions on the disk
+ // and return the one they want.
+
+ ExtendedPartitionNumber = PartitionNumber - 5;
+
+ for (Index=0; Index<=ExtendedPartitionNumber; Index++)
+ {
+ // Get the extended partition table entry
+ if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
+ {
+ return FALSE;
+ }
+
+ // Read the partition boot record
+ if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionTableEntry.SectorCountBeforePartition, &MasterBootRecord))
+ {
+ return FALSE;
+ }
+
+ // Get the first real partition table entry
+ if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
+ {
+ return FALSE;
+ }
+ }
+
+ // When we get here we should have the correct entry
+ // already stored in PartitionTableEntry
+ // so just return TRUE
+ return TRUE;
+ }
+
+}
+
+BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
+{
+ ULONG Index;
+
+ for (Index=0; Index<4; Index++)
+ {
+ // Check the system indicator
+ // If it's not an extended or unused partition
+ // then we're done
+ if ((MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_ENTRY_UNUSED) &&
+ (MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_EXTENDED) &&
+ (MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_XINT13_EXTENDED))
+ {
+ RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
+{
+ ULONG Index;
+
+ for (Index=0; Index<4; Index++)
+ {
+ // Check the system indicator
+ // If it an extended partition then we're done
+ if ((MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_EXTENDED) ||
+ (MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_XINT13_EXTENDED))
+ {
+ RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL DiskReadBootRecord(ULONG DriveNumber, ULONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
+{
+ ULONG Index;
+
+ // Read master boot record
+ if (!DiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, BootRecord))
+ {
+ return FALSE;
+ }
+
+
+#ifdef DEBUG
+
+ DbgPrint((DPRINT_DISK, "Dumping partition table for drive 0x%x:\n", DriveNumber));
+ DbgPrint((DPRINT_DISK, "Boot record logical start sector = %d\n", LogicalSectorNumber));
+ DbgPrint((DPRINT_DISK, "sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD)));
+
+ for (Index=0; Index<4; Index++)
+ {
+ DbgPrint((DPRINT_DISK, "-------------------------------------------\n"));
+ DbgPrint((DPRINT_DISK, "Partition %d\n", (Index + 1)));
+ DbgPrint((DPRINT_DISK, "BootIndicator: 0x%x\n", BootRecord->PartitionTable[Index].BootIndicator));
+ DbgPrint((DPRINT_DISK, "StartHead: 0x%x\n", BootRecord->PartitionTable[Index].StartHead));
+ DbgPrint((DPRINT_DISK, "StartSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].StartSector));
+ DbgPrint((DPRINT_DISK, "StartCylinder: 0x%x\n", BootRecord->PartitionTable[Index].StartCylinder));
+ DbgPrint((DPRINT_DISK, "SystemIndicator: 0x%x\n", BootRecord->PartitionTable[Index].SystemIndicator));
+ DbgPrint((DPRINT_DISK, "EndHead: 0x%x\n", BootRecord->PartitionTable[Index].EndHead));
+ DbgPrint((DPRINT_DISK, "EndSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].EndSector));
+ DbgPrint((DPRINT_DISK, "EndCylinder: 0x%x\n", BootRecord->PartitionTable[Index].EndCylinder));
+ DbgPrint((DPRINT_DISK, "SectorCountBeforePartition: 0x%x\n", BootRecord->PartitionTable[Index].SectorCountBeforePartition));
+ DbgPrint((DPRINT_DISK, "PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount));
+ }
+
+#endif // defined DEBUG
+
+ // Check the partition table magic value
+ if (BootRecord->MasterBootRecordMagic != 0xaa55)
+ {
+ DiskError("Invalid partition table magic (0xaa55)");
+ return FALSE;
+ }
+
+ return TRUE;
+}
#ifndef __FS_H
#define __FS_H
-//
-// Define the structure of a partition table entry
-//
-typedef struct _PARTITION_TABLE_ENTRY
-{
- BYTE BootIndicator; // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only)
- BYTE StartHead; // Beginning head number
- BYTE StartSector; // Beginning sector (2 high bits of cylinder #)
- BYTE StartCylinder; // Beginning cylinder# (low order bits of cylinder #)
- BYTE SystemIndicator; // System indicator
- BYTE EndHead; // Ending head number
- BYTE EndSector; // Ending sector (2 high bits of cylinder #)
- BYTE EndCylinder; // Ending cylinder# (low order bits of cylinder #)
- DWORD SectorCountBeforePartition; // Number of sectors preceding the partition
- DWORD PartitionSectorCount; // Number of sectors in the partition
-} PACKED PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
+#define EOF -1
-//
-// This macro will return the cylinder when you pass it a cylinder/sector
-// pair where the high 2 bits of the cylinder are stored in the sector byte
-//
-#define MAKE_CYLINDER(cylinder, sector) ( cylinder + ((((WORD)sector) & 0xC0) << 2) )
-
-//
-// Define the structure of the master boot record
-//
-typedef struct _MASTER_BOOT_RECORD
-{
- BYTE MasterBootRecordCodeAndData[0x1be];
- PARTITION_TABLE_ENTRY PartitionTable[4];
- WORD MasterBootRecordMagic;
-
-} PACKED MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
-
-//
-// Partition type defines
-//
-#define PARTITION_ENTRY_UNUSED 0x00 // Entry unused
-#define PARTITION_FAT_12 0x01 // 12-bit FAT entries
-#define PARTITION_XENIX_1 0x02 // Xenix
-#define PARTITION_XENIX_2 0x03 // Xenix
-#define PARTITION_FAT_16 0x04 // 16-bit FAT entries
-#define PARTITION_EXTENDED 0x05 // Extended partition entry
-#define PARTITION_HUGE 0x06 // Huge partition MS-DOS V4
-#define PARTITION_IFS 0x07 // IFS Partition
-#define PARTITION_OS2BOOTMGR 0x0A // OS/2 Boot Manager/OPUS/Coherent swap
-#define PARTITION_FAT32 0x0B // FAT32
-#define PARTITION_FAT32_XINT13 0x0C // FAT32 using extended int13 services
-#define PARTITION_XINT13 0x0E // Win95 partition using extended int13 services
-#define PARTITION_XINT13_EXTENDED 0x0F // Same as type 5 but uses extended int13 services
-#define PARTITION_PREP 0x41 // PowerPC Reference Platform (PReP) Boot Partition
-#define PARTITION_LDM 0x42 // Logical Disk Manager partition
-#define PARTITION_UNIX 0x63 // Unix
+#define FS_FAT 1
+#define FS_NTFS 2
+#define FS_EXT2 3
+#define FS_REISER 4
-#define FILE VOID
-#define PFILE FILE *
+#define FILE VOID
+#define PFILE FILE *
VOID FileSystemError(PUCHAR ErrorString);
BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber);
ULONG GetFilePointer(PFILE FileHandle);
BOOL IsEndOfFile(PFILE FileHandle);
-
-#define EOF -1
-
-#define FS_FAT 1
-#define FS_NTFS 2
-#define FS_EXT2 3
-
#endif // #defined __FS_H
BOOL FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector)
{
- ULONG PhysicalTrack;
- ULONG PhysicalHead;
- ULONG PhysicalSector;
DbgPrint((DPRINT_FILESYSTEM, "FatOpenVolume() DriveNumber = 0x%x VolumeStartSector = %d\n", DriveNumber, VolumeStartSector));
// Now try to read the boot sector
// If this fails then abort
- if (BiosInt13ExtensionsSupported(DriveNumber))
+ if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, FatVolumeBootSector))
{
- if (!BiosInt13ReadExtended(DriveNumber, VolumeStartSector, 1, FatVolumeBootSector))
- {
- FileSystemError("Disk read error.");
- return FALSE;
- }
- }
- else
- {
- // Calculate the physical disk offsets
- PhysicalSector = 1 + (VolumeStartSector % get_sectors(DriveNumber));
- PhysicalHead = (VolumeStartSector / get_sectors(DriveNumber)) % get_heads(DriveNumber);
- PhysicalTrack = (VolumeStartSector / get_sectors(DriveNumber)) / get_heads(DriveNumber);
-
- if (!BiosInt13Read(DriveNumber, PhysicalHead, PhysicalTrack, PhysicalSector, 1, FatVolumeBootSector))
- {
- FileSystemError("Disk read error.");
- return FALSE;
- }
+ return FALSE;
}
// Get the FAT type
return FALSE;
}
- //
- // Set the drive geometry
- //
- if (!DiskSetDriveGeometry(DriveNumber, get_cylinders(DriveNumber), get_heads(DriveNumber), get_sectors(DriveNumber), FatVolumeBootSector->BytesPerSector))
- {
- return FALSE;
- }
-
//
// Check the FAT cluster size
// We do not support clusters bigger than 64k
+++ /dev/null
-/*
- * FreeLoader
- * Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <fs.h>
-
-#ifndef __FILESYS_H
-#define __FILESYS_H
-
-BOOL FsInternalIsDiskPartitioned(ULONG DriveNumber); // Returns TRUE if the disk contains partitions, FALSE if floppy disk
-BOOL FsInternalGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); // Returns the active partition table entry
-BOOL FsInternalGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); // Returns the active partition table entry
-ULONG FsInternalGetPartitionCount(ULONG DriveNumber); // Returns the number of partitions on the disk
-
-#endif // #defined __FILESYS_H
#include <freeldr.h>
#include <fs.h>
-#include "filesys.h"
#include "fat.h"
#include <disk.h>
#include <rtl.h>
*/
BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
{
- MASTER_BOOT_RECORD DriveMasterBootRecord;
PARTITION_TABLE_ENTRY PartitionTableEntry;
DbgPrint((DPRINT_FILESYSTEM, "OpenDiskDrive() DriveNumber: 0x%x PartitionNumber: 0x%x\n", DriveNumber, PartitionNumber));
// Check and see if it is a floppy drive
// If so then just assume FAT12 file system type
- if (FsInternalIsDiskPartitioned(DriveNumber) == FALSE)
+ if (DiskIsDriveRemovable(DriveNumber))
{
DbgPrint((DPRINT_FILESYSTEM, "Drive is a floppy diskette drive. Assuming FAT12 file system.\n"));
return FatOpenVolume(DriveNumber, 0);
}
- //
- // Read master boot record
- //
- if (!BiosInt13Read(DriveNumber, 0, 0, 1, 1, &DriveMasterBootRecord))
- {
- FileSystemError("Disk read error.");
- return FALSE;
- }
-
-
-#ifdef DEBUG
-
- DbgPrint((DPRINT_FILESYSTEM, "Drive is a hard disk, dumping partition table:\n"));
- DbgPrint((DPRINT_FILESYSTEM, "sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD)));
-
- for (BootPartition=0; BootPartition<4; BootPartition++)
- {
- DbgPrint((DPRINT_FILESYSTEM, "-------------------------------------------\n"));
- DbgPrint((DPRINT_FILESYSTEM, "Partition %d\n", (BootPartition + 1)));
- DbgPrint((DPRINT_FILESYSTEM, "BootIndicator: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].BootIndicator));
- DbgPrint((DPRINT_FILESYSTEM, "StartHead: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].StartHead));
- DbgPrint((DPRINT_FILESYSTEM, "StartSector (Plus 2 cylinder bits): 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].StartSector));
- DbgPrint((DPRINT_FILESYSTEM, "StartCylinder: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].StartCylinder));
- DbgPrint((DPRINT_FILESYSTEM, "SystemIndicator: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].SystemIndicator));
- DbgPrint((DPRINT_FILESYSTEM, "EndHead: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].EndHead));
- DbgPrint((DPRINT_FILESYSTEM, "EndSector (Plus 2 cylinder bits): 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].EndSector));
- DbgPrint((DPRINT_FILESYSTEM, "EndCylinder: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].EndCylinder));
- DbgPrint((DPRINT_FILESYSTEM, "SectorCountBeforePartition: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].SectorCountBeforePartition));
- DbgPrint((DPRINT_FILESYSTEM, "PartitionSectorCount: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].PartitionSectorCount));
- }
-
-#endif // defined DEBUG
-
-
- // Check the partition table magic value
- if (DriveMasterBootRecord.MasterBootRecordMagic != 0xaa55)
- {
- FileSystemError("Invalid partition table magic (0xaa55)");
- return FALSE;
- }
+ // Set the boot partition
+ BootPartition = PartitionNumber;
// Get the requested partition entry
if (PartitionNumber == 0)
{
// Partition requested was zero which means the boot partition
- if (FsInternalGetActivePartitionEntry(DriveNumber, &PartitionTableEntry) == FALSE)
+ if (DiskGetActivePartitionEntry(DriveNumber, &PartitionTableEntry) == FALSE)
{
return FALSE;
}
else
{
// Get requested partition
- if (FsInternalGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry) == FALSE)
+ if (DiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry) == FALSE)
{
return FALSE;
}
return TRUE;
}
-BOOL FsInternalIsDiskPartitioned(ULONG DriveNumber)
-{
- // Hard disks use drive numbers >= 0x80
- // So if the drive number indicates a hard disk
- // then return TRUE
- if (DriveNumber >= 0x80)
- {
- return TRUE;
- }
-
- // Drive is a floppy diskette so return FALSE
- return FALSE;
-}
-
-BOOL FsInternalGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
-{
- ULONG BootablePartitionCount = 0;
- MASTER_BOOT_RECORD MasterBootRecord;
-
- // Read master boot record
- if (!BiosInt13Read(DriveNumber, 0, 0, 1, 1, &MasterBootRecord))
- {
- FileSystemError("Disk read error.");
- return FALSE;
- }
-
- // Count the bootable partitions
- if (MasterBootRecord.PartitionTable[0].BootIndicator == 0x80)
- {
- BootablePartitionCount++;
- BootPartition = 0;
- }
- if (MasterBootRecord.PartitionTable[1].BootIndicator == 0x80)
- {
- BootablePartitionCount++;
- BootPartition = 1;
- }
- if (MasterBootRecord.PartitionTable[2].BootIndicator == 0x80)
- {
- BootablePartitionCount++;
- BootPartition = 2;
- }
- if (MasterBootRecord.PartitionTable[3].BootIndicator == 0x80)
- {
- BootablePartitionCount++;
- BootPartition = 3;
- }
-
- // Make sure there was only one bootable partition
- if (BootablePartitionCount != 1)
- {
- FileSystemError("Too many bootable partitions or none found.");
- return FALSE;
- }
-
- // Copy the partition table entry
- RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[BootPartition], sizeof(PARTITION_TABLE_ENTRY));
-
- return TRUE;
-}
-
-BOOL FsInternalGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
-{
- MASTER_BOOT_RECORD MasterBootRecord;
-
- // Read master boot record
- if (!BiosInt13Read(DriveNumber, 0, 0, 1, 1, &MasterBootRecord))
- {
- FileSystemError("Disk read error.");
- return FALSE;
- }
-
- // PartitionNumber is one-based and we need it zero-based
- PartitionNumber--;
-
- // Copy the partition table entry
- RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[PartitionNumber], sizeof(PARTITION_TABLE_ENTRY));
-
- return TRUE;
-}
-
PFILE OpenFile(PUCHAR FileName)
{
PFILE FileHandle = NULL;
}
return(FALSE);
-}
\ No newline at end of file
+}
MAKE = make
# For a release build uncomment this line
-FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -O3
+#FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -O3
# For a debug build uncomment this line
-#FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -DDEBUG -O3
+FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -DDEBUG -O3