- hdimage 'flat' mode: added support for Linux block devices (part of SF patch #3412431)

- hdimage: renamed 'sectors' to 'spt' (same as the config parameter)
- harddrv: fixed info message
This commit is contained in:
Volker Ruppert 2011-11-26 15:09:00 +00:00
parent f66a04e7d1
commit 3029d55f4a
7 changed files with 50 additions and 40 deletions

View File

@ -1524,7 +1524,7 @@ bx_bool bx_floppy_ctrl_c::evaluate_media(Bit8u devtype, Bit8u type, char *path,
media->type = BX_FLOPPY_1_44;
media->tracks = media->vvfat->cylinders;
media->heads = media->vvfat->heads;
media->sectors_per_track = media->vvfat->sectors;
media->sectors_per_track = media->vvfat->spt;
media->sectors = 2880;
media->vvfat_floppy = 1;
media->fd = 0;

View File

@ -304,7 +304,7 @@ void bx_hard_drive_c::init(void)
}
BX_HD_THIS channels[channel].drives[device].hdimage->cylinders = cyl;
BX_HD_THIS channels[channel].drives[device].hdimage->heads = heads;
BX_HD_THIS channels[channel].drives[device].hdimage->sectors = spt;
BX_HD_THIS channels[channel].drives[device].hdimage->spt = spt;
/* open hard drive image file */
if ((BX_HD_THIS channels[channel].drives[device].hdimage->open(SIM->get_param_string("path", base)->getptr())) < 0) {
@ -317,7 +317,7 @@ void bx_hard_drive_c::init(void)
// 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;
spt = BX_HD_THIS channels[channel].drives[device].hdimage->spt;
BX_INFO(("ata%d-%d: image geometry: CHS=%d/%d/%d", channel, device, cyl, heads, spt));
} else {
if ((cyl == 0) && (image_caps & HDIMAGE_AUTO_GEOMETRY)) {
@ -339,7 +339,7 @@ void bx_hard_drive_c::init(void)
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));
BX_INFO(("ata%d-%d: extra data outside of CHS address range", channel, device));
}
}
} else if (SIM->get_param_enum("type", base)->get() == BX_ATA_DEVICE_CDROM) {
@ -438,7 +438,7 @@ void bx_hard_drive_c::init(void)
// AMI BIOS: 1st hard disk landing zone, high byte
DEV_cmos_set_reg(0x22, DEV_cmos_get_reg(0x1c));
// AMI BIOS: 1st hard disk sectors/track
DEV_cmos_set_reg(0x23, BX_DRIVE(0,0).hdimage->sectors);
DEV_cmos_set_reg(0x23, BX_DRIVE(0,0).hdimage->spt);
}
//set up cmos for second hard drive
@ -463,7 +463,7 @@ void bx_hard_drive_c::init(void)
// AMI BIOS: 2nd hard disk landing zone, high byte
DEV_cmos_set_reg(0x2b, DEV_cmos_get_reg(0x25));
// AMI BIOS: 2nd hard disk sectors/track
DEV_cmos_set_reg(0x2c, BX_DRIVE(0,1).hdimage->sectors);
DEV_cmos_set_reg(0x2c, BX_DRIVE(0,1).hdimage->spt);
}
DEV_cmos_set_reg(0x39, 0);
@ -476,7 +476,7 @@ void bx_hard_drive_c::init(void)
if (BX_DRIVE_IS_HD(channel,device)) {
Bit16u cylinders = BX_DRIVE(channel,device).hdimage->cylinders;
Bit16u heads = BX_DRIVE(channel,device).hdimage->heads;
Bit16u spt = BX_DRIVE(channel,device).hdimage->sectors;
Bit16u spt = BX_DRIVE(channel,device).hdimage->spt;
Bit8u translation = SIM->get_param_enum("translation", base)->get();
Bit8u reg = 0x39 + channel/2;
@ -2057,7 +2057,7 @@ void bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
raise_interrupt(channel);
break;
}
if (BX_SELECTED_CONTROLLER(channel).sector_count != BX_SELECTED_DRIVE(channel).hdimage->sectors) {
if (BX_SELECTED_CONTROLLER(channel).sector_count != BX_SELECTED_DRIVE(channel).hdimage->spt) {
BX_ERROR(("ata%d-%d: init drive params: logical sector count %d not supported", channel, BX_SLAVE_SELECTED(channel),
BX_SELECTED_CONTROLLER(channel).sector_count));
command_aborted(channel, value);
@ -2547,8 +2547,8 @@ bx_hard_drive_c::calculate_logical_address(Bit8u channel, Bit64s *sector)
}
} else {
logical_sector = ((Bit32u)BX_SELECTED_CONTROLLER(channel).cylinder_no * BX_SELECTED_DRIVE(channel).hdimage->heads *
BX_SELECTED_DRIVE(channel).hdimage->sectors) +
(Bit32u)(BX_SELECTED_CONTROLLER(channel).head_no * BX_SELECTED_DRIVE(channel).hdimage->sectors) +
BX_SELECTED_DRIVE(channel).hdimage->spt) +
(Bit32u)(BX_SELECTED_CONTROLLER(channel).head_no * BX_SELECTED_DRIVE(channel).hdimage->spt) +
(BX_SELECTED_CONTROLLER(channel).sector_no - 1);
}
@ -2583,7 +2583,7 @@ bx_hard_drive_c::increment_address(Bit8u channel, Bit64s *sector)
}
} else {
BX_SELECTED_CONTROLLER(channel).sector_no++;
if (BX_SELECTED_CONTROLLER(channel).sector_no > BX_SELECTED_DRIVE(channel).hdimage->sectors) {
if (BX_SELECTED_CONTROLLER(channel).sector_no > BX_SELECTED_DRIVE(channel).hdimage->spt) {
BX_SELECTED_CONTROLLER(channel).sector_no = 1;
BX_SELECTED_CONTROLLER(channel).head_no++;
if (BX_SELECTED_CONTROLLER(channel).head_no >= BX_SELECTED_DRIVE(channel).hdimage->heads) {
@ -2738,9 +2738,9 @@ void bx_hard_drive_c::identify_drive(Bit8u channel)
// Word 5: # unformatted bytes per sector in default xlated mode
// Word 6: # user-addressable sectors per track in default xlate mode
// Note: words 4,5 are now "Vendor specific (obsolete)"
BX_SELECTED_DRIVE(channel).id_drive[4] = (512 * BX_SELECTED_DRIVE(channel).hdimage->sectors);
BX_SELECTED_DRIVE(channel).id_drive[4] = (512 * BX_SELECTED_DRIVE(channel).hdimage->spt);
BX_SELECTED_DRIVE(channel).id_drive[5] = 512;
BX_SELECTED_DRIVE(channel).id_drive[6] = BX_SELECTED_DRIVE(channel).hdimage->sectors;
BX_SELECTED_DRIVE(channel).id_drive[6] = BX_SELECTED_DRIVE(channel).hdimage->spt;
// Word 7-9: Vendor specific
@ -2832,14 +2832,14 @@ void bx_hard_drive_c::identify_drive(Bit8u channel)
BX_SELECTED_DRIVE(channel).id_drive[54] = BX_SELECTED_DRIVE(channel).hdimage->cylinders;
}
BX_SELECTED_DRIVE(channel).id_drive[55] = BX_SELECTED_DRIVE(channel).hdimage->heads;
BX_SELECTED_DRIVE(channel).id_drive[56] = BX_SELECTED_DRIVE(channel).hdimage->sectors;
BX_SELECTED_DRIVE(channel).id_drive[56] = BX_SELECTED_DRIVE(channel).hdimage->spt;
// Word 57-58: Current capacity in sectors
// Excludes all sectors used for device specific purposes.
temp32 =
BX_SELECTED_DRIVE(channel).hdimage->cylinders *
BX_SELECTED_DRIVE(channel).hdimage->heads *
BX_SELECTED_DRIVE(channel).hdimage->sectors;
BX_SELECTED_DRIVE(channel).hdimage->spt;
BX_SELECTED_DRIVE(channel).id_drive[57] = (temp32 & 0xffff); // LSW
BX_SELECTED_DRIVE(channel).id_drive[58] = (temp32 >> 16); // MSW
@ -2860,7 +2860,7 @@ void bx_hard_drive_c::identify_drive(Bit8u channel)
if (BX_SELECTED_DRIVE(channel).hdimage->hd_size > 0)
num_sects = (BX_SELECTED_DRIVE(channel).hdimage->hd_size >> 9);
else
num_sects = BX_SELECTED_DRIVE(channel).hdimage->cylinders * BX_SELECTED_DRIVE(channel).hdimage->heads * BX_SELECTED_DRIVE(channel).hdimage->sectors;
num_sects = BX_SELECTED_DRIVE(channel).hdimage->cylinders * BX_SELECTED_DRIVE(channel).hdimage->heads * BX_SELECTED_DRIVE(channel).hdimage->spt;
BX_SELECTED_DRIVE(channel).id_drive[60] = (Bit16u)(num_sects & 0xffff); // LSW
BX_SELECTED_DRIVE(channel).id_drive[61] = (Bit16u)(num_sects >> 16); // MSW

View File

@ -34,6 +34,10 @@
#if BX_HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef linux
#include <linux/fs.h>
#include <sys/ioctl.h>
#endif
#define LOG_THIS theHDImageCtl->
@ -175,16 +179,22 @@ int default_image_t::open(const char* pathname, int flags)
#ifndef WIN32
/* look at size of image file to calculate disk geometry */
struct stat stat_buf;
int ret = fstat(fd, &stat_buf);
if (ret) {
if (fstat(fd, &stat_buf)) {
BX_PANIC(("fstat() returns error!"));
}
hd_size = (Bit64u)stat_buf.st_size;
#endif
if ((hd_size % 512) != 0) {
BX_PANIC(("size of disk image must be multiple of 512 bytes"));
#ifdef linux
if (stat_buf.st_rdev) { // Is this a special device file (e.g. /dev/sde) ?
ioctl(fd, BLKGETSIZE64, &hd_size); // yes it's!
}
else
#endif
{
hd_size = (Bit64u)stat_buf.st_size; // standard unix procedure to get size of regular files
}
#endif
BX_INFO(("hd_size: "FMT_LL"u", hd_size));
if (hd_size <= 0) BX_PANIC(("size of disk image not detected / invalid"));
if ((hd_size % 512) != 0) BX_PANIC(("size of disk image must be multiple of 512 bytes"));
return fd;
}

View File

@ -153,7 +153,7 @@ class device_image_t
unsigned cylinders;
unsigned heads;
unsigned sectors;
unsigned spt;
Bit64u hd_size;
};

View File

@ -284,12 +284,12 @@ int vmware3_image_t::open(const char * pathname)
if (header.total_sectors_in_disk!=0) {
cylinders = header.cylinders_in_disk;
heads = header.heads_in_disk;
sectors = header.sectors_in_disk;
spt = header.sectors_in_disk;
hd_size = header.total_sectors_in_disk * 512;
} else {
cylinders = header.cylinders;
heads = header.heads;
sectors = header.sectors;
spt = header.sectors;
hd_size = header.total_sectors * 512;
}

View File

@ -82,13 +82,13 @@ int vmware4_image_t::open(const char * pathname)
hd_size = header.total_sectors * SECTOR_SIZE;
cylinders = (unsigned)hd_size / (16 * 63);
heads = 16;
sectors = 63;
spt = 63;
BX_DEBUG(("VMware 4 disk geometry:"));
BX_DEBUG((" .size = " FMT_LL "d", hd_size));
BX_DEBUG((" .cylinders = %d", cylinders));
BX_DEBUG((" .heads = %d", heads));
BX_DEBUG((" .sectors = %d", sectors));
BX_DEBUG((" .sectors = %d", spt));
return 1;
}

View File

@ -367,8 +367,8 @@ bx_bool vvfat_image_t::sector2CHS(Bit32u spos, mbr_chs_t *chs)
{
Bit32u head, sector;
sector = spos % sectors;
spos /= sectors;
sector = spos % spt;
spos /= spt;
head = spos % heads;
spos /= heads;
if (spos > 1023) {
@ -1054,7 +1054,7 @@ int vvfat_image_t::init_directories(const char* dirname)
if (fat_type != 32) {
bootsector->sectors_per_fat = htod16(sectors_per_fat);
}
bootsector->sectors_per_track = htod16(sectors);
bootsector->sectors_per_track = htod16(spt);
bootsector->number_of_heads = htod16(heads);
bootsector->hidden_sectors = htod32(offset_to_bootsector);
bootsector->total_sectors = htod32((volume_sector_count > 0xffff) ? volume_sector_count:0);
@ -1204,14 +1204,14 @@ int vvfat_image_t::open(const char* dirname)
}
if (fat_type != 0) {
sector_count = partition->start_sector_long + partition->length_sector_long;
sectors = partition->start_sector_long;
spt = partition->start_sector_long;
if (partition->end_CHS.head > 15) {
heads = 16;
} else {
heads = partition->end_CHS.head + 1;
}
cylinders = sector_count / (heads * sectors);
offset_to_bootsector = sectors;
cylinders = sector_count / (heads * spt);
offset_to_bootsector = spt;
memcpy(&first_sectors[0], sector_buffer, 0x200);
use_mbr_file = 1;
BX_INFO(("VVFAT: using MBR from file"));
@ -1248,13 +1248,13 @@ int vvfat_image_t::open(const char* dirname)
}
if ((fat_type != 0) && (bs->number_of_fats == 2)) {
sector_count = bs->total_sectors16 + bs->total_sectors + bs->hidden_sectors;
sectors = bs->sectors_per_track;
spt = bs->sectors_per_track;
if (bs->number_of_heads > 15) {
heads = 16;
} else {
heads = bs->number_of_heads;
}
cylinders = sector_count / (heads * sectors);
cylinders = sector_count / (heads * spt);
offset_to_bootsector = bs->hidden_sectors;
use_boot_file = 1;
}
@ -1274,7 +1274,7 @@ int vvfat_image_t::open(const char* dirname)
// floppy support
cylinders = 80;
heads = 2;
sectors = 18;
spt = 18;
offset_to_bootsector = 0;
fat_type = 12;
sectors_per_cluster = 1;
@ -1285,11 +1285,11 @@ int vvfat_image_t::open(const char* dirname)
if (cylinders == 0) {
cylinders = 1024;
heads = 16;
sectors = 63;
spt = 63;
}
offset_to_bootsector = sectors;
offset_to_bootsector = spt;
}
sector_count = cylinders * heads * sectors;
sector_count = cylinders * heads * spt;
}
hd_size = sector_count * 512;