X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FStorage%2FLVM%2Fmbr.c;h=78d3d24d2258bda65e5554509ae5852197fe3dc0;hb=08bc0c87326899a62ccb0f08b3d334c82b199f07;hp=8cbb5b1907c910ee4932f887b424821a14961b70;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Storage/LVM/mbr.c b/KernelLand/Modules/Storage/LVM/mbr.c index 8cbb5b19..78d3d24d 100644 --- a/KernelLand/Modules/Storage/LVM/mbr.c +++ b/KernelLand/Modules/Storage/LVM/mbr.c @@ -1,66 +1,120 @@ /* - * Acess2 IDE Harddisk Driver - * - MBR Parsing Code + * Acess2 Logical Volume Manager + * - By John Hodge (thePowersGang) + * * mbr.c + * - MBR Parsing Code */ #define DEBUG 0 #include -#include "lvm_int.h" +#include "lvm.h" +#include "mbr.h" // === PROTOTYPES === -void LVM_MBR_Initialise(int Disk, tMBR *MBR); -Uint64 LVM_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length); + int LVM_MBR_Detect(tLVM_Vol *Volume); + int LVM_MBR_CountSubvolumes(tLVM_Vol *Volume, void *FirstSector); +void LVM_MBR_PopulateSubvolumes(tLVM_Vol *Volume, void *FirstSector); +Uint64 LVM_MBR_int_ReadExt(tLVM_Vol *Volume, Uint64 Addr, Uint64 *Base, Uint64 *Length); // === GLOBALS === +tLVM_Format gLVM_MBRType = { + .Name = "MBR", + .CountSubvolumes = LVM_MBR_CountSubvolumes, + .PopulateSubvolumes = LVM_MBR_PopulateSubvolumes +}; // === CODE === +int LVM_MBR_Detect(tLVM_Vol *Volume) +{ + tMBR mbr; + // TODO: handle non-512 byte sectors + if( LVM_int_ReadVolume( Volume, 0, 1, &mbr ) != 0 ) + return -1; // Stop on Errors + + if( mbr.BootFlag != LittleEndian16(0xAA55) ) + return 0; + + return 1; +} + /** - * \fn void ATA_ParseMBR(int Disk, tMBR *MBR) + * \brief Initialise a volume as */ -void ATA_ParseMBR(int Disk, tMBR *MBR) +int LVM_MBR_CountSubvolumes(tLVM_Vol *Volume, void *FirstSector) { - int i, j = 0, k = 4; + tMBR *MBR = FirstSector; Uint64 extendedLBA; Uint64 base, len; + int numPartitions = 0; - ENTER("iDisk", Disk); + ENTER("pVolume pFirstSector", Volume, FirstSector); // Count Partitions - gATA_Disks[Disk].NumPartitions = 0; + numPartitions = 0; extendedLBA = 0; - for( i = 0; i < 4; i ++ ) + for( int i = 0; i < 4; i ++ ) { if( MBR->Parts[i].SystemID == 0 ) continue; - if( MBR->Parts[i].Boot == 0x0 || MBR->Parts[i].Boot == 0x80 // LBA 28 - || MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 // LBA 48 - ) + + if( MBR->Parts[i].Boot == 0x0 || MBR->Parts[i].Boot == 0x80 ) // LBA 28 { - if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 ) { - LOG("Extended Partition at 0x%llx", MBR->Parts[i].LBAStart); - if(extendedLBA != 0) { - Warning("Disk %i has multiple extended partitions, ignoring rest", Disk); - continue; - } - extendedLBA = MBR->Parts[i].LBAStart; + base = MBR->Parts[i].LBAStart; + } + else if( MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 ) // LBA 48 + { + base = (MBR->Parts[i].StartHi << 16) | MBR->Parts[i].LBAStart; + } + else + continue ; // Invalid, so don't count + + if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 ) + { + LOG("Extended Partition at 0x%llx", base); + if(extendedLBA != 0) { + Log_Warning( + "LBA MBR", + "Volume %p has multiple extended partitions, ignoring all but first", + Volume + ); continue; } - LOG("Primary Partition at 0x%llx", MBR->Parts[i].LBAStart); - - gATA_Disks[Disk].NumPartitions ++; - continue; + extendedLBA = base; + } + else + { + LOG("Primary Partition at 0x%llx", base); + numPartitions ++; } - // Invalid Partition, so don't count it } - while(extendedLBA != 0) + // Detect the GPT protector + if( extendedLBA == 0 && numPartitions == 1 && MBR->Parts[0].SystemID == 0xEE ) { - extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len); - if( extendedLBA == -1 ) break; - gATA_Disks[Disk].NumPartitions ++; + // TODO: Hand off to GPT parsing code + Log_Warning("LBA MBR", "TODO: Hand off to GPT"); } - LOG("gATA_Disks[Disk].NumPartitions = %i", gATA_Disks[Disk].NumPartitions); - // Create patition array - gATA_Disks[Disk].Partitions = malloc( gATA_Disks[Disk].NumPartitions * sizeof(tATA_Partition) ); + // Handle extended partions + while(extendedLBA != 0) + { + extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len); + if( extendedLBA == (Uint64)-1 ) + break; + numPartitions ++; + } + LOG("numPartitions = %i", numPartitions); + + LEAVE('i', numPartitions); + return numPartitions; +} + +void LVM_MBR_PopulateSubvolumes(tLVM_Vol *Volume, void *FirstSector) +{ + Uint64 extendedLBA; + Uint64 base, len; + int i, j; + tMBR *MBR = FirstSector; + + ENTER("pVolume pFirstSector", Volume, FirstSector); // --- Fill Partition Info --- extendedLBA = 0; @@ -73,7 +127,7 @@ void ATA_ParseMBR(int Disk, tMBR *MBR) base = MBR->Parts[i].LBAStart; len = MBR->Parts[i].LBALength; } - else if( MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 ) // LBA 58 + else if( MBR->Parts[i].Boot == 0x1 || MBR->Parts[i].Boot == 0x81 ) // LBA 48 { base = (MBR->Parts[i].StartHi << 16) | MBR->Parts[i].LBAStart; len = (MBR->Parts[i].LengthHi << 16) | MBR->Parts[i].LBALength; @@ -82,29 +136,23 @@ void ATA_ParseMBR(int Disk, tMBR *MBR) continue; if( MBR->Parts[i].SystemID == 0xF || MBR->Parts[i].SystemID == 5 ) { - if(extendedLBA != 0) { - Log_Warning("ATA", "Disk %i has multiple extended partitions, ignoring rest", Disk); - continue; - } - extendedLBA = base; + if(extendedLBA == 0) + extendedLBA = base; continue; } // Create Partition - ATA_int_MakePartition( - &gATA_Disks[Disk].Partitions[j], Disk, j, - base, len - ); + LVM_int_SetSubvolume_Anon( Volume, j, base, len ); j ++; } // Scan extended partitions while(extendedLBA != 0) { - extendedLBA = ATA_MBR_int_ReadExt(Disk, extendedLBA, &base, &len); - if(extendedLBA == -1) break; - ATA_int_MakePartition( - &gATA_Disks[Disk].Partitions[j], Disk, k, base, len - ); + extendedLBA = LVM_MBR_int_ReadExt(Volume, extendedLBA, &base, &len); + if(extendedLBA == (Uint64)-1) + break; + LVM_int_SetSubvolume_Anon( Volume, j, base, len ); + j ++ ; } LEAVE('-'); @@ -114,7 +162,7 @@ void ATA_ParseMBR(int Disk, tMBR *MBR) * \brief Reads an extended partition * \return LBA of next Extended, -1 on error, 0 for last */ -Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) +Uint64 LVM_MBR_int_ReadExt(tLVM_Vol *Volume, Uint64 Addr, Uint64 *Base, Uint64 *Length) { Uint64 link = 0; int bFoundPart = 0;; @@ -122,7 +170,8 @@ Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) tMBR mbr; Uint64 base, len; - if( ATA_ReadDMA( Disk, Addr, 1, &mbr ) != 0 ) + // TODO: Handle non-512 byte sectors + if( LVM_int_ReadVolume( Volume, Addr, 1, &mbr ) != 0 ) return -1; // Stop on Errors for( i = 0; i < 4; i ++ ) @@ -140,9 +189,9 @@ Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) len = (mbr.Parts[i].LengthHi << 16) | mbr.Parts[i].LBALength; } else { - Log_Warning("ATA MBR", - "Unknown partition type 0x%x, Disk %i Ext 0x%llx Part %i", - mbr.Parts[i].Boot, Disk, Addr, i + Log_Warning("LVM MBR", + "Unknown partition type 0x%x, Volume %p Ext 0x%llx Part %i", + mbr.Parts[i].Boot, Volume, Addr, i ); return -1; } @@ -152,9 +201,9 @@ Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) case 0xF: case 0x5: if(link != 0) { - Log_Warning("ATA MBR", - "Disk %i has two forward links in the extended partition", - Disk + Log_Warning("LVM MBR", + "Volume %p has two forward links in the extended partition", + Volume ); return -1; } @@ -162,23 +211,24 @@ Uint64 ATA_MBR_int_ReadExt(int Disk, Uint64 Addr, Uint64 *Base, Uint64 *Length) break; default: if(bFoundPart) { - Warning("ATA MBR", - "Disk %i has more than one partition in the extended partition at 0x%llx", - Disk, Addr + Warning("LVM MBR", + "Volume %p has more than one partition in the extended partition at 0x%llx", + Volume, Addr ); return -1; } bFoundPart = 1; - *Base = base; + *Base = Addr + base; // Extended partitions are based off the sub-mbr *Length = len; break; } } if(!bFoundPart) { - Log_Warning("ATA MBR", - "No partition in extended partiton, Disk %i 0x%llx", - Disk, Addr); + Log_Warning("LVM MBR", + "No partition in extended partiton, Volume %p 0x%llx", + Volume, Addr + ); return -1; }