📄 initdisk.c
字号:
{
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",
partitionName, pEntry->FileSystem);
printCHS(" start ", &chs);
printCHS(", end ", &end);
printf("\n");
#endif
}
/*
here we have a partition table in our hand !!
*/
partitionsToIgnore |= 1 << i;
DosDefinePartition(driveParam, partitionStart, pEntry,
extendedPartNo, i);
if (scan_type == SCAN_PRIMARYBOOT || scan_type == SCAN_PRIMARY)
{
return partitionsToIgnore;
}
}
return partitionsToIgnore;
}
void BIOS_drive_reset(unsigned drive);
int Read1LBASector(struct DriveParamS *driveParam, unsigned drive,
ULONG LBA_address, void * buffer)
{
static struct _bios_LBA_address_packet dap = {
16, 0, 0, 0, 0, 0, 0
};
struct CHS chs;
iregs regs;
int num_retries;
/* disabled because this should not happen and if it happens the BIOS
should complain; also there are weird disks around with
CMOS geometry < real geometry */
#if 0
if (LBA_address >= driveParam->total_sectors)
{
printf("LBA-Transfer error : address overflow = %lu > %lu max\n",
LBA_address + 1, driveParam->total_sectors);
return 1;
}
#endif
for (num_retries = 0; num_retries < N_RETRY; num_retries++)
{
regs.d.b.l = drive | 0x80;
if (driveParam->descflags & DF_LBA)
{
dap.number_of_blocks = 1;
dap.buffer_address = buffer;
dap.block_address_high = 0; /* clear high part */
dap.block_address = LBA_address; /* clear high part */
/* Load the registers and call the interrupt. */
regs.a.x = LBA_READ;
regs.si = FP_OFF(&dap);
regs.ds = FP_SEG(&dap);
}
else
{ /* transfer data, using old bios functions */
LBA_to_CHS(&chs, LBA_address, driveParam);
/* avoid overflow at end of track */
if (chs.Cylinder > 1023)
{
printf("LBA-Transfer error : cylinder %u > 1023\n", chs.Cylinder);
return 1;
}
regs.a.x = 0x0201;
regs.b.x = FP_OFF(buffer);
regs.c.x =
((chs.Cylinder & 0xff) << 8) + ((chs.Cylinder & 0x300) >> 2) +
chs.Sector;
regs.d.b.h = chs.Head;
regs.es = FP_SEG(buffer);
} /* end of retries */
init_call_intr(0x13, ®s);
if ((regs.flags & FLG_CARRY) == 0)
break;
BIOS_drive_reset(driveParam->driveno);
}
return regs.flags & FLG_CARRY ? 1 : 0;
}
/* Load the Partition Tables and get information on all drives */
int ProcessDisk(int scanType, unsigned drive, int PartitionsToIgnore)
{
struct PartTableEntry PTable[4];
ULONG RelSectorOffset;
ULONG ExtendedPartitionOffset;
int iPart;
int strangeHardwareLoop;
int num_extended_found = 0;
struct DriveParamS driveParam;
/* Get the hard drive parameters and ensure that the drive exists. */
/* If there was an error accessing the drive, skip that drive. */
if (!LBA_Get_Drive_Parameters(drive, &driveParam))
{
printf("can't get drive parameters for drive %02x\n", drive);
return PartitionsToIgnore;
}
RelSectorOffset = 0; /* boot sector */
ExtendedPartitionOffset = 0; /* not found yet */
/* Read the Primary Partition Table. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -