From 657cd05c0a53716879e6fa372af34c43dd9f26e4 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sun, 18 Mar 2018 09:07:31 +0000 Subject: [PATCH] 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. --- bochs/iodev/harddrv.cc | 18 ++++++++++++------ bochs/iodev/hdimage/hdimage.cc | 24 +++++++++++++++++------- bochs/iodev/hdimage/hdimage.h | 3 ++- bochs/iodev/hdimage/vbox.cc | 6 ++++-- bochs/iodev/hdimage/vmware3.cc | 7 ++++--- bochs/iodev/hdimage/vmware4.cc | 6 ++++-- bochs/iodev/hdimage/vpc-img.cc | 5 +++-- bochs/iodev/hdimage/vvfat.cc | 3 ++- 8 files changed, 48 insertions(+), 24 deletions(-) diff --git a/bochs/iodev/harddrv.cc b/bochs/iodev/harddrv.cc index 45cdaa91a..0dd10ff68 100644 --- a/bochs/iodev/harddrv.cc +++ b/bochs/iodev/harddrv.cc @@ -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)); diff --git a/bochs/iodev/hdimage/hdimage.cc b/bochs/iodev/hdimage/hdimage.cc index 0c159f502..8e759b11e 100644 --- a/bochs/iodev/hdimage/hdimage.cc +++ b/bochs/iodev/hdimage/hdimage.cc @@ -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) { diff --git a/bochs/iodev/hdimage/hdimage.h b/bochs/iodev/hdimage/hdimage.h index 3753ac586..5b7d5fe30 100644 --- a/bochs/iodev/hdimage/hdimage.h +++ b/bochs/iodev/hdimage/hdimage.h @@ -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 diff --git a/bochs/iodev/hdimage/vbox.cc b/bochs/iodev/hdimage/vbox.cc index 4a26e3ee5..84d5a431b 100644 --- a/bochs/iodev/hdimage/vbox.cc +++ b/bochs/iodev/hdimage/vbox.cc @@ -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; } diff --git a/bochs/iodev/hdimage/vmware3.cc b/bochs/iodev/hdimage/vmware3.cc index df7e3ee5e..ea2657127 100644 --- a/bochs/iodev/hdimage/vmware3.cc +++ b/bochs/iodev/hdimage/vmware3.cc @@ -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; } diff --git a/bochs/iodev/hdimage/vmware4.cc b/bochs/iodev/hdimage/vmware4.cc index 832ebc810..48e2590c3 100644 --- a/bochs/iodev/hdimage/vmware4.cc +++ b/bochs/iodev/hdimage/vmware4.cc @@ -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; } diff --git a/bochs/iodev/hdimage/vpc-img.cc b/bochs/iodev/hdimage/vpc-img.cc index 49254fabe..96f9b9273 100644 --- a/bochs/iodev/hdimage/vpc-img.cc +++ b/bochs/iodev/hdimage/vpc-img.cc @@ -6,7 +6,7 @@ // // Copyright (c) 2005 Alex Beregszaszi // Copyright (c) 2009 Kevin Wolf -// 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); diff --git a/bochs/iodev/hdimage/vvfat.cc b/bochs/iodev/hdimage/vvfat.cc index 56479d84c..d89bf834f 100644 --- a/bochs/iodev/hdimage/vvfat.cc +++ b/bochs/iodev/hdimage/vvfat.cc @@ -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 {