📄 initdisk.c
字号:
if (maxclust > FAT16MAX) maxclust = FAT16MAX; DebugPrintf(("FAT16: #clu=%lu, fatlen=%u, maxclu=%lu, limit=%u\n", clust, fatlength, maxclust, FAT_MAGIC16)); if (clust > maxclust - 2) { DebugPrintf(("FAT16: too many clusters\n")); clust = 0; } else if (clust <= FAT_MAGIC) { /* The <= 4086 avoids that the filesystem will be misdetected as having a * 12 bit FAT. */ DebugPrintf(("FAT16: would be misdetected as FAT12\n")); clust = 0; } if (clust) break; defbpb->bpb_nsector <<= 1; } while (defbpb->bpb_nsector && defbpb->bpb_nsector <= maxclustsize); defbpb->bpb_nfsect = fatlength; memcpy(pddt->ddt_fstype, MSDOS_FAT16_SIGN, 8); break; }#ifdef WITHFAT32 case FAT32: case FAT32_LBA: { unsigned long fatlength, clust, maxclust; /* For FAT32, use the cluster size table described in the FAT spec: * http://www.microsoft.com/hwdev/download/hardware/fatgen103.pdf */ unsigned sz_gb = (unsigned)(NumSectors / 2097152UL); unsigned char nsector = 64; /* disks greater than 32 GB, 32K cluster */ if (sz_gb <= 32) /* disks up to 32 GB, 16K cluster */ nsector = 32; if (sz_gb <= 16) /* disks up to 16 GB, 8K cluster */ nsector = 16; if (sz_gb <= 8) /* disks up to 8 GB, 4K cluster */ nsector = 8; if (NumSectors <= 532480UL) /* disks up to 260 MB, 0.5K cluster */ nsector = 1; defbpb->bpb_nsector = nsector; do { fatlength = cdiv(fatdata + 2 * defbpb->bpb_nsector, (ULONG)defbpb->bpb_nbyte * defbpb->bpb_nsector / 4 + defbpb->bpb_nfat); /* Need to calculate number of clusters, since the unused parts of the * FATS and data area together could make up space for an additional, * not really present cluster. */ clust = (fatdata - defbpb->bpb_nfat * fatlength) / defbpb->bpb_nsector; maxclust = (fatlength * defbpb->bpb_nbyte) / 4; if (maxclust > FAT32MAX) maxclust = FAT32MAX; DebugPrintf(("FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", clust, fatlength, maxclust, FAT32MAX)); if (clust > maxclust - 2) { clust = 0; DebugPrintf(("FAT32: too many clusters\n")); } if (clust) break; defbpb->bpb_nsector <<= 1; } while (defbpb->bpb_nsector && defbpb->bpb_nsector <= maxclustsize); defbpb->bpb_nfsect = 0; defbpb->bpb_xnfsect = fatlength; /* set up additional FAT32 fields */ defbpb->bpb_xflags = 0; defbpb->bpb_xfsversion = 0; defbpb->bpb_xrootclst = 2; defbpb->bpb_xfsinfosec = 1; defbpb->bpb_xbackupsec = 6; memcpy(pddt->ddt_fstype, MSDOS_FAT32_SIGN, 8); break; }#endif } pddt->ddt_fstype[8] = '\0';}STATIC void push_ddt(ddt *pddt){ ddt FAR *fddt = DynAlloc("ddt", 1, sizeof(ddt)); fmemcpy(fddt, pddt, sizeof(ddt)); if (pddt->ddt_logdriveno != 0) { (fddt - 1)->ddt_next = fddt; if (pddt->ddt_driveno == 0 && pddt->ddt_logdriveno == 1) (fddt - 1)->ddt_descflags |= DF_CURLOG | DF_MULTLOG; }}void DosDefinePartition(struct DriveParamS *driveParam, ULONG StartSector, struct PartTableEntry *pEntry, int extendedPartNo, int PrimaryNum){ ddt nddt; ddt *pddt = &nddt; struct CHS chs; if (nUnits >= NDEV) { printf("more Partitions detected then possible, max = %d\n", NDEV); return; /* we are done */ } pddt->ddt_next = MK_FP(0, 0xffff); pddt->ddt_driveno = driveParam->driveno; pddt->ddt_logdriveno = nUnits; pddt->ddt_descflags = driveParam->descflags; /* Turn of LBA if not forced and the partition is within 1023 cyls and of the right type */ /* the FileSystem type was internally converted to LBA_xxxx if a non-LBA partition above cylinder 1023 was found */ if (!InitKernelConfig.ForceLBA && !ExtLBAForce && !IsLBAPartition(pEntry->FileSystem)) pddt->ddt_descflags &= ~DF_LBA; pddt->ddt_ncyl = driveParam->chs.Cylinder;#ifdef DEBUG if (pddt->ddt_descflags & DF_LBA) DebugPrintf(("LBA enabled for drive %c:\n", 'A' + nUnits));#endif pddt->ddt_offset = StartSector; pddt->ddt_defbpb.bpb_nbyte = SEC_SIZE; pddt->ddt_defbpb.bpb_mdesc = 0xf8; pddt->ddt_defbpb.bpb_nheads = driveParam->chs.Head; pddt->ddt_defbpb.bpb_nsecs = driveParam->chs.Sector; pddt->ddt_defbpb.bpb_hidden = pEntry->RelSect; pddt->ddt_defbpb.bpb_nsize = 0; pddt->ddt_defbpb.bpb_huge = pEntry->NumSect; if (pEntry->NumSect <= 0xffff) { pddt->ddt_defbpb.bpb_nsize = (UWORD) (pEntry->NumSect); pddt->ddt_defbpb.bpb_huge = 0; /* may still be set on Win95 */ } /* sectors per cluster, sectors per FAT etc. */ CalculateFATData(pddt, pEntry->NumSect, pEntry->FileSystem); pddt->ddt_serialno = 0x12345678l; /* drive inaccessible until bldbpb successful */ pddt->ddt_descflags |= init_readdasd(pddt->ddt_driveno) | DF_NOACCESS; pddt->ddt_type = 5; memcpy(&pddt->ddt_bpb, &pddt->ddt_defbpb, sizeof(bpb)); push_ddt(pddt); /* Alain whishes to keep this in later versions, too Tom likes this too, so he made it configurable by SYS CONFIG ... */ if (InitKernelConfig.InitDiskShowDriveAssignment) { char *ExtPri; int num; LBA_to_CHS(&chs, StartSector, driveParam); ExtPri = "Pri"; num = PrimaryNum + 1; if (extendedPartNo) { ExtPri = "Ext"; num = extendedPartNo; } printf("\r%c: HD%d, %s[%2d]", 'A' + nUnits, (driveParam->driveno & 0x7f) + 1, ExtPri, num); printCHS(", CHS= ", &chs); printf(", start=%6lu MB, size=%6lu MB\n", StartSector / 2048, pEntry->NumSect / 2048); } nUnits++;}/* Get the parameters of the hard disk */STATIC int LBA_Get_Drive_Parameters(int drive, struct DriveParamS *driveParam){ iregs regs; struct _bios_LBA_disk_parameterS lba_bios_parameters; ExtLBAForce = FALSE; memset(driveParam, 0, sizeof *driveParam); drive |= 0x80; /* for tests - disable LBA support, even if exists */ if (!InitKernelConfig.GlobalEnableLBAsupport) { goto StandardBios; } /* check for LBA support */ regs.b.x = 0x55aa; regs.a.b.h = 0x41; regs.d.b.l = drive; init_call_intr(0x13, ®s); if (regs.b.x != 0xaa55 || (regs.flags & 0x01)) { goto StandardBios; } /* by ralph : if DAP cannot be used, don't use LBA */ if ((regs.c.x & 1) == 0) { goto StandardBios; } /* drive supports LBA addressing */ /* version 1.0, 2.0 have different verify */ if (regs.a.x < 0x2100) LBA_WRITE_VERIFY = 0x4301; memset(&lba_bios_parameters, 0, sizeof(lba_bios_parameters)); lba_bios_parameters.size = sizeof(lba_bios_parameters); regs.si = FP_OFF(&lba_bios_parameters); regs.ds = FP_SEG(&lba_bios_parameters); regs.a.b.h = 0x48; regs.d.b.l = drive; init_call_intr(0x13, ®s); /* error or DMA boundary errors not handled transparently */ if (regs.flags & 0x01) { goto StandardBios; } /* verify maximum settings, we can't handle more */ if (lba_bios_parameters.heads > 0xffff || lba_bios_parameters.sectors > 0xffff || lba_bios_parameters.totalSectHigh != 0) { printf("Drive is too large to handle, using only 1st 8 GB\n" " drive %02x heads %lu sectors %lu , total=0x%lx-%08lx\n", drive, (ULONG) lba_bios_parameters.heads, (ULONG) lba_bios_parameters.sectors, (ULONG) lba_bios_parameters.totalSect, (ULONG) lba_bios_parameters.totalSectHigh); goto StandardBios; } driveParam->total_sectors = lba_bios_parameters.totalSect; /* if we arrive here, success */ driveParam->descflags = DF_LBA; if (lba_bios_parameters.information & 8) driveParam->descflags |= DF_WRTVERIFY; StandardBios: /* old way to get parameters */ regs.a.b.h = 0x08; regs.d.b.l = drive; init_call_intr(0x13, ®s); if (regs.flags & 0x01) goto ErrorReturn; driveParam->chs.Head = (regs.d.x >> 8) + 1; driveParam->chs.Sector = (regs.c.x & 0x3f); driveParam->chs.Cylinder = (regs.c.x >> 8) | ((regs.c.x & 0xc0) << 2); if (driveParam->chs.Sector == 0) { /* happens e.g. with Bochs 1.x if no harddisk defined */ driveParam->chs.Sector = 63; /* avoid division by zero...! */ printf("BIOS reported 0 sectors/track, assuming 63!\n"); } if (!(driveParam->descflags & DF_LBA)) { driveParam->total_sectors = min(driveParam->chs.Cylinder, 1023) * driveParam->chs.Head * driveParam->chs.Sector; } driveParam->driveno = drive; DebugPrintf(("drive parameters %02x - %04lu-%u-%u", drive, driveParam->chs.Cylinder, driveParam->chs.Head, driveParam->chs.Sector)); DebugPrintf((" total size %luMB\n\n", driveParam->total_sectors / 2048));ErrorReturn: return driveParam->driveno;}/* converts physical into logical representation of partition entry*/STATIC void ConvCHSToIntern(struct CHS *chs, UBYTE * pDisk){ chs->Head = pDisk[0]; chs->Sector = pDisk[1] & 0x3f; chs->Cylinder = pDisk[2] + ((pDisk[1] & 0xc0) << 2);}BOOL ConvPartTableEntryToIntern(struct PartTableEntry * pEntry, UBYTE * pDisk){ int i; if (pDisk[0x1fe] != 0x55 || pDisk[0x1ff] != 0xaa) { memset(pEntry, 0, 4 * sizeof(struct PartTableEntry)); return FALSE; } pDisk += 0x1be; for (i = 0; i < 4; i++, pDisk += 16, pEntry++) { pEntry->Bootable = pDisk[0]; pEntry->FileSystem = pDisk[4]; ConvCHSToIntern(&pEntry->Begin, pDisk+1); ConvCHSToIntern(&pEntry->End, pDisk+5); pEntry->RelSect = *(ULONG *) (pDisk + 8); pEntry->NumSect = *(ULONG *) (pDisk + 12); } return TRUE;}BOOL is_suspect(struct CHS *chs, struct CHS *pEntry_chs){ /* Valid entry: entry == chs || // partition entry equal to computed values (chs->Cylinder > 1023 && // or LBA partition (entry->Cylinder == 1023 || entry->Cylinder == (0x3FF & chs->Cylinder))) */ return !((pEntry_chs->Cylinder == chs->Cylinder && pEntry_chs->Head == chs->Head && pEntry_chs->Sector == chs->Sector) || chs->Cylinder > 1023u && (pEntry_chs->Cylinder == 1023 || pEntry_chs->Cylinder == (0x3ff & chs->Cylinder)));}void print_warning_suspect(char *partitionName, UBYTE fs, struct CHS *chs, struct CHS *pEntry_chs){ printf("WARNING: using suspect partition %s FS %02x:", partitionName, fs); printCHS(" with calculated values ", chs); printCHS(" instead of ", pEntry_chs); printf("\n"); memcpy(pEntry_chs, chs, sizeof(struct CHS));}BOOL ScanForPrimaryPartitions(struct DriveParamS * driveParam, int scan_type, struct PartTableEntry * pEntry, ULONG startSector, int partitionsToIgnore, int extendedPartNo){ int i; struct CHS chs, end; ULONG partitionStart; char partitionName[12]; for (i = 0; i < 4; i++, pEntry++) { if (pEntry->FileSystem == 0) continue; if (partitionsToIgnore & (1 << i)) continue; if (IsExtPartition(pEntry->FileSystem)) continue; if (scan_type == SCAN_PRIMARYBOOT && !pEntry->Bootable) continue; partitionStart = startSector + pEntry->RelSect; if (!IsFATPartition(pEntry->FileSystem)) { continue; } if (extendedPartNo) sprintf(partitionName, "Ext:%d", extendedPartNo); else sprintf(partitionName, "Pri:%d", i + 1); /* some sanity checks, that partition structure is OK */ LBA_to_CHS(&chs, partitionStart, driveParam); LBA_to_CHS(&end, partitionStart + pEntry->NumSect - 1, driveParam); /* some FDISK's enter for partitions > 8 GB cyl = 1023, other (cyl&1023) */ if (is_suspect(&chs, &pEntry->Begin)) { print_warning_suspect(partitionName, pEntry->FileSystem, &chs, &pEntry->Begin); } if (is_suspect(&end, &pEntry->End)) { if (pEntry->NumSect == 0) { printf("Not using partition %s with 0 sectors\n", partitionName); continue; } print_warning_suspect(partitionName, pEntry->FileSystem, &end, &pEntry->End); } if (chs.Cylinder > 1023 || end.Cylinder > 1023) { if (!(driveParam->descflags & DF_LBA)) { printf ("can't use LBA partition without LBA support - part %s FS %02x", partitionName, pEntry->FileSystem); printCHS(" start ", &chs); printCHS(", end ", &end); printf("\n"); continue; } if (!InitKernelConfig.ForceLBA && !ExtLBAForce && !IsLBAPartition(pEntry->FileSystem)) { printf ("WARNING: Partition ID does not suggest LBA - part %s FS %02x.\n" "Please run FDISK to correct this - using LBA to access partition.\n", partitionName, pEntry->FileSystem); printCHS(" start ", &chs); printCHS(", end ", &end); printf("\n"); pEntry->FileSystem = (pEntry->FileSystem == FAT12 ? FAT12_LBA : pEntry->FileSystem == FAT32 ? FAT32_LBA : /* pEntry->FileSystem == FAT16 ? */ FAT16_LBA); } /* else its a diagnostic message only */#ifdef DEBUG printf("found and using LBA partition %s FS %02x",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -