⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 initdisk.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 3 页
字号:
        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, &regs);  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, &regs);  /* 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, &regs);  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 + -