diff options
author | hpa <hpa> | 2002-10-29 06:12:58 +0000 |
---|---|---|
committer | hpa <hpa> | 2002-10-29 06:12:58 +0000 |
commit | ff6ca4781bf1d9694537a070c85bde5b9e9b82a0 (patch) | |
tree | 13b30dcffc4e90346026460bc83997a9e746318d | |
parent | e4f84982db57372d435f2d9239f839df3a5e77db (diff) | |
download | syslinux-2.01-pre1.tar.gz |
Support DOSEMU-style hard disk imagessyslinux-2.01-pre1
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | memdisk/setup.c | 62 | ||||
-rwxr-xr-x | mkdiskimage.in | 16 |
3 files changed, 62 insertions, 20 deletions
@@ -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"; |