From d966918e7304ff405fae20916cf137d737c92dea Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 22 Jun 2010 10:55:03 -0700 Subject: [PATCH] memdisk: add a sector_shift field to the MDI; fix memdiskfind Add a sector_shift field to the MDI rather than assuming 512-byte sectors. Fix memdiskfind to report size in bytes, not in sectors. Signed-off-by: H. Peter Anvin --- doc/memdisk.txt | 5 +++-- memdisk/mstructs.h | 2 +- memdisk/setup.c | 21 +++++++++++---------- utils/memdiskfind.c | 8 +++++++- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/doc/memdisk.txt b/doc/memdisk.txt index c7244ab..b8ed9ae 100644 --- a/doc/memdisk.txt +++ b/doc/memdisk.txt @@ -190,13 +190,14 @@ The MEMDISK info structure currently contains: [ES:DI+2] byte MEMDISK minor version [ES:DI+3] byte MEMDISK major version [ES:DI+4] dword Pointer to MEMDISK data in high memory - [ES:DI+8] dword Size of MEMDISK data in 512-byte sectors + [ES:DI+8] dword Size of MEMDISK data in sectors [ES:DI+12] 16:16 Far pointer to command line [ES:DI+16] 16:16 Old INT 13h pointer [ES:DI+20] 16:16 Old INT 15h pointer [ES:DI+24] word Amount of DOS memory before MEMDISK loaded [ES:DI+26] byte Boot loader ID - [ES:DI+27] byte Currently unused + [ES:DI+27] byte Sector size as a power of 2 + (If zero, assume 512-byte sectors) [ES:DI+28] word If nonzero, offset (vs ES) to installed DPT This pointer+16 contains the original INT 1Eh diff --git a/memdisk/mstructs.h b/memdisk/mstructs.h index c2e6352..fecbff4 100644 --- a/memdisk/mstructs.h +++ b/memdisk/mstructs.h @@ -93,7 +93,7 @@ struct mdi { uint16_t olddosmem; uint8_t bootloaderid; - uint8_t _pad1; + uint8_t sector_shift; uint16_t dpt_ptr; } MEMDISK_PACKED_POSTFIX; diff --git a/memdisk/setup.c b/memdisk/setup.c index 20b48c4..3f69cd3 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -242,7 +242,7 @@ struct geometry { uint32_t boot_lba; /* LBA of bootstrap code */ uint8_t type; /* Type byte for INT 13h AH=08h */ uint8_t driveno; /* Drive no */ - uint16_t sector_size; /* Sector size in bytes (512 vs. 2048) */ + uint8_t sector_shift; /* Sector size as a power of 2 */ const char *hsrc, *ssrc; /* Origins of H and S geometries */ }; @@ -322,13 +322,13 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, printf("command line: %s\n", shdr->cmdline); - hd_geometry.sector_size = 512; /* Assume floppy/HDD at first */ + hd_geometry.sector_shift = 9; /* Assume floppy/HDD at first */ offset = 0; if (CMD_HASDATA(p = getcmditem("offset")) && (v = atou(p))) offset = v; - sectors = xsectors = (size - offset) >> 9; + sectors = xsectors = (size - offset) >> hd_geometry.sector_shift; hd_geometry.hsrc = "guess"; hd_geometry.ssrc = "guess"; @@ -372,8 +372,7 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, hd_geometry.h = 255; hd_geometry.s = 15; /* 2048-byte sectors, so adjust the size and count */ - hd_geometry.sector_size = 2048; - sectors = (size - hd_geometry.offset) >> 11; + hd_geometry.sector_shift = 11; break; case 1: /* 1.2 MB floppy */ hd_geometry.s = 15; @@ -393,9 +392,10 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, case 4: hd_geometry.driveno = 0x80; hd_geometry.type = 0; - sectors = (size - hd_geometry.offset) >> 9; break; } + sectors = (size - hd_geometry.offset) >> hd_geometry.sector_shift; + /* For HDD emulation, we figure out the geometry later. Otherwise: */ if (hd_geometry.s) { hd_geometry.hsrc = hd_geometry.ssrc = "El Torito"; @@ -413,7 +413,7 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, hd_geometry.h = dosemu.h; hd_geometry.s = dosemu.s; hd_geometry.offset += dosemu.offset; - sectors = (size - hd_geometry.offset) >> 9; + sectors = (size - hd_geometry.offset) >> hd_geometry.sector_shift; hd_geometry.hsrc = hd_geometry.ssrc = "DOSEMU"; } @@ -466,7 +466,7 @@ static const struct geometry *get_disk_image_geometry(uint32_t where, if (!(max_h | max_s)) { /* No FAT filesystem found to steal geometry from... */ - if ((sectors < 4096 * 2) && (hd_geometry.sector_size == 512)) { + if ((sectors < 4096 * 2) && (hd_geometry.sector_shift == 9)) { int ok = 0; unsigned int xsectors = sectors; @@ -778,7 +778,7 @@ void setup(const struct real_mode_args *rm_args_ptr) /* Choose the appropriate installable memdisk hook */ if (do_eltorito) { - if (geometry->sector_size == 2048) { + if (geometry->sector_shift == 11) { bin_size = (int)&_binary_memdisk_iso_2048_bin_size; memdisk_hook = (char *)&_binary_memdisk_iso_2048_bin_start; } else { @@ -817,6 +817,7 @@ void setup(const struct real_mode_args *rm_args_ptr) pptr->sectors = geometry->s; pptr->mdi.disksize = geometry->sectors; pptr->mdi.diskbuf = ramdisk_image + geometry->offset; + pptr->mdi.sector_shift = geometry->sector_shift; pptr->statusptr = (geometry->driveno & 0x80) ? 0x474 : 0x441; pptr->mdi.bootloaderid = shdr->type_of_loader; @@ -912,7 +913,7 @@ void setup(const struct real_mode_args *rm_args_ptr) * for INT 0x13, AH=0x48 "EDD Get Disk Parameters" call on an * El Torito ODD. Check for 2048-byte sector size */ - if (geometry->sector_size != 2048) + if (geometry->sector_shift != 11) pptr->edd_dpt.flags |= 0x0002; /* Geometry valid */ } if (!(geometry->driveno & 0x80)) { diff --git a/utils/memdiskfind.c b/utils/memdiskfind.c index 45d54bc..f2086b2 100644 --- a/utils/memdiskfind.c +++ b/utils/memdiskfind.c @@ -60,7 +60,13 @@ static bool valid_mbft(const struct mBFT *mbft, size_t space) static void output_params(const struct mBFT *mbft) { - printf("%u,%u\n", mbft->mdi.diskbuf, mbft->mdi.disksize); + int sector_shift = mbft->mdi.sector_shift; + + if (!sector_shift) + sector_shift = 9; + + printf("%#x,%#x\n", + mbft->mdi.diskbuf, mbft->mdi.disksize << sector_shift); } int main(int argc, char *argv[]) -- 2.7.4