- disk geometry detection and check code rewritten:
* if the image provides a geometry, always use it. * if the cylinder value is set to 0 and the image supports autodetection, calculate the cylinder value from disk size, sectors and heads. * in all other cases the specified geometry is used. * a panic only occurs if the image size is too small for the geometry. * extra data past the end of the disk now causes an info message. - TODO #1: 'flat' mode hdimage: read disk size of raw devices on Linux - TODO #2: 'flat' mode hdimage: use geometry from MBR on image if present
This commit is contained in:
parent
44c3b65961
commit
67db6ee123
@ -311,46 +311,36 @@ void bx_hard_drive_c::init(void)
|
||||
BX_PANIC(("ata%d-%d: could not open hard drive image file '%s'", channel, device, SIM->get_param_string("path", base)->getptr()));
|
||||
return;
|
||||
}
|
||||
bx_bool geometry_detect = 0;
|
||||
Bit32u image_caps = BX_HD_THIS channels[channel].drives[device].hdimage->get_capabilities();
|
||||
|
||||
if ((image_caps & (HDIMAGE_AUTO_GEOMETRY | HDIMAGE_HAS_GEOMETRY)) != 0) {
|
||||
geometry_detect = ((cyl == 0) || (image_caps & HDIMAGE_HAS_GEOMETRY));
|
||||
if ((heads == 0) || (spt == 0)) {
|
||||
BX_PANIC(("ata%d-%d cannot have zero heads, or sectors/track", channel, device));
|
||||
}
|
||||
if ((image_caps & HDIMAGE_HAS_GEOMETRY) != 0) {
|
||||
// If the image provides a geometry, always use it.
|
||||
cyl = BX_HD_THIS channels[channel].drives[device].hdimage->cylinders;
|
||||
heads = BX_HD_THIS channels[channel].drives[device].hdimage->heads;
|
||||
spt = BX_HD_THIS channels[channel].drives[device].hdimage->sectors;
|
||||
BX_INFO(("ata%d-%d: image geometry: CHS=%d/%d/%d", channel, device, cyl, heads, spt));
|
||||
} else {
|
||||
if (cyl == 0 || heads == 0 || spt == 0) {
|
||||
BX_PANIC(("ata%d-%d cannot have zero cylinders, heads, or sectors/track", channel, device));
|
||||
}
|
||||
}
|
||||
|
||||
if (BX_HD_THIS channels[channel].drives[device].hdimage->hd_size != 0) {
|
||||
if (geometry_detect) {
|
||||
if ((cyl == 0) && (image_caps & HDIMAGE_AUTO_GEOMETRY)) {
|
||||
// Autodetect number of cylinders
|
||||
disk_size = BX_HD_THIS channels[channel].drives[device].hdimage->hd_size;
|
||||
if ((image_caps & HDIMAGE_HAS_GEOMETRY) == 0) {
|
||||
cyl = (int)(disk_size / (heads * spt * 512));
|
||||
if (disk_size != ((Bit64u)cyl * heads * spt * 512)) {
|
||||
BX_PANIC(("ata%d-%d: geometry autodetection failed", channel, device));
|
||||
}
|
||||
BX_HD_THIS channels[channel].drives[device].hdimage->cylinders = cyl;
|
||||
BX_INFO(("ata%d-%d: autodetect geometry: CHS=%d/%d/%d", channel, device, cyl, heads, spt));
|
||||
} else {
|
||||
cyl = BX_HD_THIS channels[channel].drives[device].hdimage->cylinders;
|
||||
heads = BX_HD_THIS channels[channel].drives[device].hdimage->heads;
|
||||
spt = BX_HD_THIS channels[channel].drives[device].hdimage->sectors;
|
||||
BX_INFO(("ata%d-%d: image geometry: CHS=%d/%d/%d", channel, device, cyl, heads, spt));
|
||||
if ((heads == 0) || (spt == 0)) {
|
||||
BX_PANIC(("ata%d-%d cannot have zero heads, or sectors/track", channel, device));
|
||||
}
|
||||
cyl = (int)(BX_HD_THIS channels[channel].drives[device].hdimage->hd_size / (heads * spt * 512));
|
||||
disk_size = ((Bit64u)cyl * heads * spt * 512);
|
||||
BX_HD_THIS channels[channel].drives[device].hdimage->cylinders = cyl;
|
||||
BX_INFO(("ata%d-%d: autodetect geometry: CHS=%d/%d/%d", channel, device, cyl, heads, spt));
|
||||
} else {
|
||||
if (disk_size != BX_HD_THIS channels[channel].drives[device].hdimage->hd_size) {
|
||||
BX_PANIC(("ata%d-%d disk size doesn't match specified geometry", channel, device));
|
||||
// workaround large files problem with diskimages
|
||||
BX_HD_THIS channels[channel].drives[device].hdimage->hd_size = disk_size;
|
||||
// Default method: use CHS from configuration.
|
||||
if (cyl == 0 || heads == 0 || spt == 0) {
|
||||
BX_PANIC(("ata%d-%d cannot have zero cylinders, heads, or sectors/track", channel, device));
|
||||
}
|
||||
BX_INFO(("ata%d-%d: using specified geometry: CHS=%d/%d/%d", channel, device, cyl, heads, spt));
|
||||
}
|
||||
if (disk_size > BX_HD_THIS channels[channel].drives[device].hdimage->hd_size) {
|
||||
BX_PANIC(("ata%d-%d: specified geometry doesn't fit on disk image", channel, device));
|
||||
} else if (disk_size < BX_HD_THIS channels[channel].drives[device].hdimage->hd_size) {
|
||||
BX_INFO(("ata%d-%d: ignoring extra data past the end of the disk image", channel, device));
|
||||
}
|
||||
} else if (geometry_detect) {
|
||||
BX_PANIC(("ata%d-%d image doesn't support geometry detection", channel, device));
|
||||
}
|
||||
} else if (SIM->get_param_enum("type", base)->get() == BX_ATA_DEVICE_CDROM) {
|
||||
bx_list_c *cdrom_rt = (bx_list_c*)SIM->get_param(BXPN_MENU_RUNTIME_CDROM);
|
||||
|
Loading…
Reference in New Issue
Block a user