Continued preparing hard disk sector size option in the hdimage code.

- 'flat' mode: disk image size must be multiple of sector size.
- 'concat' mode: each disk image size and lseek() offset must be multiple of
   sector size.
- 'sparse' mode: page size and lseek() offset must be multiple of sector size.
- TODO: 'growing', 'undoable' and 'volatile' mode: redolog_t class is still
  based on 512-byte blocks.
- TODO: 'vbox', 'vmware3', 'vmware4', 'vpc' and 'vvfat' mode have a builtin
  geometry. If other sector sizes are supported, it should be handled correctly.
- harddrv code now reports current sector size, but still panics for now.
- TODO: harrdrv and USB disk code, bximage, BIOS.
This commit is contained in:
Volker Ruppert 2018-03-18 09:07:31 +00:00
parent db95a54238
commit 657cd05c0a
8 changed files with 48 additions and 24 deletions

View File

@ -295,10 +295,11 @@ void bx_hard_drive_c::init(void)
int cyl = SIM->get_param_num("cylinders", base)->get();
int heads = SIM->get_param_num("heads", base)->get();
int spt = SIM->get_param_num("spt", base)->get();
if (SIM->get_param_num("sect_size", base)->get() != BX_SECT_SIZE_512) {
int sect_size = atoi(SIM->get_param_enum("sect_size", base)->get_selected());
if (sect_size != 512) {
BX_PANIC(("Disk sector size other than 512 not yet supported"));
}
Bit64u disk_size = (Bit64u)cyl * heads * spt * 512;
Bit64u disk_size = (Bit64u)cyl * heads * spt * sect_size;
image_mode = SIM->get_param_enum("mode", base)->get();
channels[channel].drives[device].hdimage = DEV_hdimage_init_image(image_mode,
@ -315,6 +316,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->spt = spt;
BX_HD_THIS channels[channel].drives[device].hdimage->sect_size = sect_size;
/* open hard drive image file */
if ((BX_HD_THIS channels[channel].drives[device].hdimage->open(SIM->get_param_string("path", base)->getptr())) < 0) {
@ -328,7 +330,9 @@ void bx_hard_drive_c::init(void)
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->spt;
BX_INFO(("ata%d-%d: image geometry: CHS=%d/%d/%d", channel, device, cyl, heads, spt));
sect_size = BX_HD_THIS channels[channel].drives[device].hdimage->sect_size;
BX_INFO(("ata%d-%d: image geometry: CHS=%d/%d/%d (sector size=%d)",
channel, device, cyl, heads, spt, sect_size));
} else {
if ((cyl == 0) && (image_caps & HDIMAGE_AUTO_GEOMETRY)) {
// Autodetect number of cylinders
@ -336,15 +340,17 @@ void bx_hard_drive_c::init(void)
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);
disk_size = ((Bit64u)cyl * heads * spt * sect_size);
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));
BX_INFO(("ata%d-%d: autodetect geometry: CHS=%d/%d/%d (sector size=%d)",
channel, device, cyl, heads, spt, sect_size));
} else {
// 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));
BX_INFO(("ata%d-%d: using specified geometry: CHS=%d/%d/%d (sector size=%d)",
channel, device, cyl, heads, spt, sect_size));
}
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));

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2017 The Bochs Project
// Copyright (C) 2002-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -492,6 +492,7 @@ bx_bool hdimage_copy_file(const char *src, const char *dst)
device_image_t::device_image_t()
{
hd_size = 0;
sect_size = 512;
}
int device_image_t::open(const char* _pathname)
@ -527,7 +528,9 @@ int flat_image_t::open(const char* _pathname, int flags)
}
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"));
if ((hd_size % sect_size) != 0) {
BX_PANIC(("size of disk image must be multiple of %d bytes", sect_size));
}
return fd;
}
@ -641,7 +644,7 @@ int concat_image_t::open(const char* _pathname0, int flags)
BX_PANIC(("block devices should REALLY NOT be used as concat images"));
}
#endif
if ((stat_buf.st_size % 512) != 0) {
if ((stat_buf.st_size % sect_size) != 0) {
BX_PANIC(("size of disk image must be multiple of 512 bytes"));
}
start_offset_table[i] = start_offset;
@ -676,8 +679,8 @@ void concat_image_t::close()
Bit64s concat_image_t::lseek(Bit64s offset, int whence)
{
if ((offset % 512) != 0)
BX_PANIC(("lseek HD with offset not multiple of 512"));
if ((offset % sect_size) != 0)
BX_PANIC(("lseek HD with offset not multiple of %d", sect_size));
BX_DEBUG(("concat_image_t.lseek(%d)", whence));
switch (whence) {
case SEEK_SET:
@ -928,6 +931,9 @@ int sparse_image_t::open(const char* pathname0, int flags)
if ((underlying_filesize % pagesize) != 0)
panic("size of sparse disk image is not multiple of page size");
if ((pagesize % sect_size) != 0)
panic("page size of sparse disk image is not multiple of sector size");
underlying_current_filepos = 0;
if (-1 == ::lseek(fd, 0, SEEK_SET))
panic("error while seeking to start of file");
@ -990,8 +996,8 @@ void sparse_image_t::close()
Bit64s sparse_image_t::lseek(Bit64s offset, int whence)
{
if ((offset % 512) != 0)
BX_PANIC(("lseek HD with offset not multiple of 512"));
if ((offset % sect_size) != 0)
BX_PANIC(("lseek HD with offset not multiple of %d", sect_size));
if (whence != SEEK_SET)
BX_PANIC(("lseek HD with whence not SEEK_SET"));
@ -1395,6 +1401,7 @@ int dll_image_t::open(const char* pathname, int flags)
vunit = vdisk_open(pathname, flags);
if (vunit >= 0) {
hd_size = (Bit64u)vdisk_get_size(vunit) << 9;
sect_size = 512;
vblk = 0;
}
} else {
@ -1989,6 +1996,7 @@ int growing_image_t::open(const char* _pathname, int flags)
pathname = _pathname;
int filedes = redolog->open(pathname, REDOLOG_SUBTYPE_GROWING, flags);
hd_size = redolog->get_size();
sect_size = 512;
BX_INFO(("'growing' disk opened, growing file is '%s'", pathname));
return filedes;
}
@ -2146,6 +2154,7 @@ int undoable_image_t::open(const char* pathname, int flags)
return -1;
hd_size = ro_disk->hd_size;
sect_size = 512;
// If not set, we make up the redolog filename from the pathname
if (redolog_name == NULL) {
@ -2292,6 +2301,7 @@ int volatile_image_t::open(const char* pathname, int flags)
return -1;
hd_size = ro_disk->hd_size;
sect_size = 512;
// If not set, use pathname as template
if (redolog_name == NULL) {

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2005-2017 The Bochs Project
// Copyright (C) 2005-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -207,6 +207,7 @@ class device_image_t
unsigned cylinders;
unsigned heads;
unsigned spt;
unsigned sect_size;
Bit64u hd_size;
protected:
#ifndef WIN32

View File

@ -10,7 +10,7 @@
* Contact: fys [at] fysnet [dot] net
*
* Copyright (C) 2015 Benjamin D Lunt.
* Copyright (C) 2006-2017 The Bochs Project
* Copyright (C) 2006-2018 The Bochs Project
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -123,12 +123,13 @@ int vbox_image_t::open(const char* _pathname, int flags)
current_offset = 0;
hd_size = header.disk_size;
sect_size = (unsigned) header.sector_size;
if ((unsigned) header.cylinders > 0) {
cylinders = (unsigned) header.cylinders;
heads = (unsigned) header.heads;
spt = (unsigned) header.sectors;
} else {
cylinders = (unsigned) ((header.disk_size / 512) / 16) / 63;
cylinders = (unsigned) ((header.disk_size / sect_size) / 16) / 63;
heads = 16;
spt = 63;
}
@ -138,6 +139,7 @@ int vbox_image_t::open(const char* _pathname, int flags)
BX_DEBUG((" .cylinders = %d", cylinders));
BX_DEBUG((" .heads = %d", heads));
BX_DEBUG((" .sectors = %d", spt));
BX_DEBUG((" .sect_size = %d", sect_size));
return 1;
}

View File

@ -10,7 +10,7 @@
* Contact: snrrrub@yahoo.com
*
* Copyright (C) 2003 Net Integration Technologies, Inc.
* Copyright (C) 2003-2017 The Bochs Project
* Copyright (C) 2003-2018 The Bochs Project
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -290,16 +290,17 @@ int vmware3_image_t::open(const char* _pathname, int flags)
}
current = &images[0];
requested_offset = 0;
sect_size = 512;
if (header.total_sectors_in_disk != 0) {
cylinders = header.cylinders_in_disk;
heads = header.heads_in_disk;
spt = header.sectors_in_disk;
hd_size = header.total_sectors_in_disk * 512;
hd_size = header.total_sectors_in_disk * sect_size;
} else {
cylinders = header.cylinders;
heads = header.heads;
spt = header.sectors;
hd_size = header.total_sectors * 512;
hd_size = header.total_sectors * sect_size;
}
return 1;
}

View File

@ -10,7 +10,7 @@
* Contact: snrrrub@gmail.com
*
* Copyright (C) 2006 Sharvil Nanavati.
* Copyright (C) 2006-2017 The Bochs Project
* Copyright (C) 2006-2018 The Bochs Project
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -90,7 +90,8 @@ int vmware4_image_t::open(const char* _pathname, int flags)
current_offset = 0;
is_dirty = 0;
hd_size = header.total_sectors * SECTOR_SIZE;
sect_size = SECTOR_SIZE;
hd_size = header.total_sectors * sect_size;
cylinders = (unsigned)(header.total_sectors / (16 * 63));
heads = 16;
spt = 63;
@ -100,6 +101,7 @@ int vmware4_image_t::open(const char* _pathname, int flags)
BX_DEBUG((" .cylinders = %d", cylinders));
BX_DEBUG((" .heads = %d", heads));
BX_DEBUG((" .sectors = %d", spt));
BX_DEBUG((" .sect size = %d", sect_size));
return 1;
}

View File

@ -6,7 +6,7 @@
//
// Copyright (c) 2005 Alex Beregszaszi
// Copyright (c) 2009 Kevin Wolf <kwolf@suse.de>
// Copyright (C) 2012-2017 The Bochs Project
// Copyright (C) 2012-2018 The Bochs Project
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@ -135,7 +135,8 @@ int vpc_image_t::open(const char* _pathname, int flags)
heads = footer->heads;
spt = footer->secs_per_cyl;
sector_count = (Bit64u)(cylinders * heads * spt);
hd_size = sector_count * 512;
sect_size = 512;
hd_size = sector_count * sect_size;
if (sector_count >= 65535 * 16 * 255) {
bx_close_image(fd, pathname);

View File

@ -6,7 +6,7 @@
// ported from QEMU block driver with some additions (see below)
//
// Copyright (c) 2004,2005 Johannes E. Schindelin
// Copyright (C) 2010-2016 The Bochs Project
// Copyright (C) 2010-2018 The Bochs Project
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@ -1200,6 +1200,7 @@ int vvfat_image_t::open(const char* dirname, int flags)
if (fat_type != 0) {
sector_count = partition->start_sector_long + partition->length_sector_long;
spt = partition->start_sector_long;
sect_size = 512;
if (partition->end_CHS.head > 15) {
heads = 16;
} else {