summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2002-10-29 06:12:58 +0000
committerhpa <hpa>2002-10-29 06:12:58 +0000
commitff6ca4781bf1d9694537a070c85bde5b9e9b82a0 (patch)
tree13b30dcffc4e90346026460bc83997a9e746318d
parente4f84982db57372d435f2d9239f839df3a5e77db (diff)
downloadsyslinux-2.01-pre1.tar.gz
Support DOSEMU-style hard disk imagessyslinux-2.01-pre1
-rw-r--r--NEWS4
-rw-r--r--memdisk/setup.c62
-rwxr-xr-xmkdiskimage.in16
3 files changed, 62 insertions, 20 deletions
diff --git a/NEWS b/NEWS
index 6dc6c9e1..acaa087e 100644
--- a/NEWS
+++ b/NEWS
@@ -3,8 +3,10 @@ apply to that specific program only; other changes apply to all of
them.
Changes in 2.01:
+ * MEMDISK: Support disk images with DOSEMU headers.
* Update the mkdiskimage script to handle newer mtools
- versions.
+ versions, and be able to generate disk images with DOSEMU
+ headers (controlled by the -d option).
Changes in 2.00:
* ALL: Add support for "COM32" (32-bit COMBOOT) images.
diff --git a/memdisk/setup.c b/memdisk/setup.c
index 98a3c96c..b96b4318 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -296,17 +296,18 @@ const char *getcmditem(const char *what)
struct geometry {
uint32_t sectors; /* 512-byte sector count */
uint32_t c, h, s; /* C/H/S geometry */
+ uint32_t offset; /* Byte offset for disk */
uint8_t type; /* Type byte for INT 13h AH=08h */
uint8_t driveno; /* Drive no */
};
static const struct geometry geometries[] =
{
- { 720, 40, 2, 9, 0x01, 0 }, /* 360 K */
- { 1440, 80, 2, 9, 0x03, 0 }, /* 720 K*/
- { 2400, 80, 2, 15, 0x02, 0 }, /* 1200 K */
- { 2880, 80, 2, 18, 0x04, 0 }, /* 1440 K */
- { 5760, 80, 2, 36, 0x06, 0 }, /* 2880 K */
+ { 720, 40, 2, 9, 0, 0x01, 0 }, /* 360 K */
+ { 1440, 80, 2, 9, 0, 0x03, 0 }, /* 720 K*/
+ { 2400, 80, 2, 15, 0, 0x02, 0 }, /* 1200 K */
+ { 2880, 80, 2, 18, 0, 0x04, 0 }, /* 1440 K */
+ { 5760, 80, 2, 36, 0, 0x06, 0 }, /* 2880 K */
};
#define known_geometries (sizeof(geometries)/sizeof(struct geometry))
@@ -320,24 +321,35 @@ struct ptab_entry {
uint32_t size;
};
+/* Format of a DOSEMU header */
+struct dosemu_header {
+ uint8_t magic[7]; /* DOSEMU\0 */
+ uint32_t h;
+ uint32_t s;
+ uint32_t c;
+ uint32_t offset;
+ uint8_t pad[105];
+} __attribute__((packed));
+
const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
{
- static struct geometry hd_geometry = { 0, 0, 0, 0, 0, 0x80 };
+ static struct geometry hd_geometry = { 0, 0, 0, 0, 0, 0, 0x80 };
struct ptab_entry ptab[4]; /* Partition table buffer */
+ struct dosemu_header dosemu;
unsigned int sectors, v;
unsigned int max_c, max_h, max_s;
- unsigned int c, h, s;
+ unsigned int c, h, s, offset;
int i;
+ int drive_specified;
const char *p;
printf("command line: %s\n", shdr->cmdline);
- if ( size & 0x1ff ) {
- puts("MEMDISK: Image has fractional end sector\n");
- size &= ~0x1ff;
- }
+ offset = 0;
+ if ( CMD_HASDATA(p = getcmditem("offset")) && (v = atou(p)) )
+ offset = v;
- sectors = size >> 9;
+ sectors = (size-offset) >> 9;
for ( i = 0 ; i < known_geometries ; i++ ) {
if ( sectors == geometries[i].sectors ) {
hd_geometry = geometries[i];
@@ -346,6 +358,20 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
}
hd_geometry.sectors = sectors;
+ hd_geometry.offset = offset;
+
+ /* Do we have a DOSEMU header? */
+ copy_from_high(&dosemu, where+hd_geometry.offset, sizeof dosemu);
+ if ( !memcmp("DOSEMU", dosemu.magic, 7) ) {
+ /* Always a hard disk unless overruled by command-line options */
+ hd_geometry.driveno = 0x80;
+ hd_geometry.type = 0;
+ hd_geometry.c = dosemu.c;
+ hd_geometry.h = dosemu.h;
+ hd_geometry.s = dosemu.s;
+ hd_geometry.offset += dosemu.offset;
+ sectors = (size-hd_geometry.offset) >> 9;
+ }
if ( CMD_HASDATA(p = getcmditem("c")) && (v = atou(p)) )
hd_geometry.c = v;
@@ -358,16 +384,17 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
hd_geometry.driveno = 0;
if ( hd_geometry.type == 0 )
hd_geometry.type = 0x10; /* ATAPI floppy, e.g. LS-120 */
- }
- if ( getcmditem("harddisk") != CMD_NOTFOUND ) {
+ drive_specified = 1;
+ } else if ( getcmditem("harddisk") != CMD_NOTFOUND ) {
hd_geometry.driveno = 0x80;
hd_geometry.type = 0;
+ drive_specified = 1;
}
if ( (hd_geometry.c == 0) || (hd_geometry.h == 0) ||
(hd_geometry.s == 0) ) {
/* Hard disk image, need to examine the partition table for geometry */
- copy_from_high(&ptab, where+(512-2-4*16), sizeof ptab);
+ copy_from_high(&ptab, where+hd_geometry.offset+(512-2-4*16), sizeof ptab);
max_c = max_h = 0; max_s = 1;
for ( i = 0 ; i < 4 ; i++ ) {
@@ -400,6 +427,9 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
hd_geometry.c = sectors/(hd_geometry.h*hd_geometry.s);
}
+ if ( (size-hd_geometry.offset) & 0x1ff ) {
+ puts("MEMDISK: Image has fractional end sector\n");
+ }
if ( sectors % (hd_geometry.h*hd_geometry.s) ) {
puts("MEMDISK: Image seems to have fractional end cylinder\n");
}
@@ -491,7 +521,7 @@ uint32_t setup(void)
pptr->heads = geometry->h;
pptr->sectors = geometry->s;
pptr->disksize = geometry->sectors;
- pptr->diskbuf = shdr->ramdisk_image;
+ pptr->diskbuf = shdr->ramdisk_image + geometry->offset;
pptr->statusptr = (geometry->driveno & 0x80) ? 0x474 : 0x441;
/* Set up a drive parameter table */
diff --git a/mkdiskimage.in b/mkdiskimage.in
index a250af29..f75d0ac9 100755
--- a/mkdiskimage.in
+++ b/mkdiskimage.in
@@ -22,7 +22,9 @@ sub absolute_path($) {
for $a ( @ARGV ) {
if ( $a =~ /^\-/ ) {
- $opt{$'} = 1;
+ foreach $o ( split(//, substr($a,1)) ) {
+ $opt{$o} = 1;
+ }
} else {
push(@args, $a);
}
@@ -33,7 +35,8 @@ $c += 0; $h += 0; $s += 0;
if ( !$file || $c < 1 || $c > 1024 ||
$h < 1 || $h > 256 || $s < 1 || $s > 63 ) {
- print STDERR "Usage: $0 [-o] file c h s (max: 1024 256 63)\n";
+ print STDERR "Usage: $0 [-do] file c h s (max: 1024 256 63)\n";
+ print STDERR " -d add DOSEMU header\n";
print STDERR " -o print filesystem offset to stdout\n";
exit 1;
}
@@ -43,6 +46,13 @@ $cylsize = $h*$s*512;
sysopen(OUTPUT, $file, O_CREAT|O_RDWR|O_TRUNC, 0666)
or die "$0: Cannot open: $file\n";
+# Print out DOSEMU header, if requested
+if ( $opt{'d'} ) {
+ $emuhdr = "DOSEMU\0" . pack("VVVV", $h, $s, $c, 128);
+ $emuhdr .= "\0" x (128 - length($emuhdr));
+ print OUTPUT $emuhdr;
+}
+
# Print the MBR and partition table
$mbr = '';
while ( $line = <DATA> ) {
@@ -106,7 +116,7 @@ $imglink = $tmpdir.'/disk.img';
die "$0: Failed to create symlink $imglink\n"
if ( !symlink(absolute_path($file), $imglink) );
-$offset = $s*512;
+$offset = $s*512 + ($opt{'d'} ? 128 : 0);
open(MCONFIG, "> ${cfgfile}") or die "$0: Cannot make mtools config\n";
print MCONFIG "drive z:\n";
print MCONFIG "file=\"${imglink}\"\n";