From: hpa Date: Wed, 5 Jan 2005 01:01:29 +0000 (+0000) Subject: Allow the user to override the extlinux detected geometry; add online help X-Git-Tag: syslinux-3.11~144 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=80717f76b561e490cf862c87be2e3ef1e5596b37;p=profile%2Fivi%2Fsyslinux.git Allow the user to override the extlinux detected geometry; add online help --- diff --git a/Makefile b/Makefile index 5f5c35e..f6927c0 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,8 @@ BINFILES = bootsect_bin.c ldlinux_bin.c mbr_bin.c \ # syslinux.exe is BTARGET so as to not require everyone to have the # mingw suite installed -BTARGET = kwdhash.gen version.gen ldlinux.bss ldlinux.sys ldlinux.bin \ +BTARGET = kwdhash.gen version.gen version.h \ + ldlinux.bss ldlinux.sys ldlinux.bin \ pxelinux.0 mbr.bin isolinux.bin isolinux-debug.bin \ extlinux.bin extlinux.bss extlinux.sys BOBJECTS = $(BTARGET) dos/syslinux.com win32/syslinux.exe memdisk/memdisk @@ -113,7 +114,10 @@ installer: installer-local installer-local: $(ITARGET) $(BINFILES) version.gen: version version.pl - $(PERL) version.pl version + $(PERL) version.pl $< $@ '%define' + +version.h: version version.pl + $(PERL) version.pl $< $@ '#define' kwdhash.gen: keywords genhash.pl $(PERL) genhash.pl < keywords > kwdhash.gen diff --git a/NEWS b/NEWS index bb8180b..9692d43 100644 --- a/NEWS +++ b/NEWS @@ -14,7 +14,12 @@ Changes in 3.02: work better over a serial console (speed, and readability on monochrome terminal emulators.) * New CONSOLE directive to control output on the video console - (useful for dealing with some broken serial-forwarding BIOSes.) + (useful for dealing with some broken serial-forwarding + BIOSes.) + * New com32 module "ethersel" for searching for an Ethernet + card and selecting the proper version of Etherboot. + * EXTLINUX: Allow the user to override the detected geometry. + Add help. Changes in 3.01: * EXTLINUX, SYSLINUX: Fix compile errors on some systems. diff --git a/extlinux/extlinux.c b/extlinux/extlinux.c index b186ec9..5d1733e 100644 --- a/extlinux/extlinux.c +++ b/extlinux/extlinux.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -37,12 +39,58 @@ #include /* Hard disk geometry */ #include /* FIGETBSZ, FIBMAP */ +#include "../version.h" + #ifdef DEBUG # define dprintf printf #else # define dprintf(...) ((void)0) #endif +/* Global option handling */ + +/* These are the options we can set and their values */ +struct my_options { + unsigned int sectors; + unsigned int heads; +} opt = { + .sectors = 0, + .heads = 0, +}; + +static void __attribute__((noreturn)) usage(int rv) +{ + fprintf(stderr, + "Usage: %s [options] directory\n" + " --zip -z Force zipdrive geometry (-H 64 -S 32)\n" + " --sectors=# -S Force the number of sectors per track\n" + " --heads=# -H Force number of heads\n" + "\n" + " Note: geometry is determined at boot time for devices which\n" + " are considered hard disks by the BIOS. Unfortunately, this is\n" + " not possible for devices which are considered floppy disks,\n" + " which includes zipdisks and LS-120 superfloppies.\n" + "\n" + " The -z option is useful for USB devices which are considered\n" + " hard disks by some BIOSes and zipdrives by other BIOSes.\n", + program); + + exit(rv); +} + +static const struct option long_options[] = { + { "zipdrive", 0, NULL, 'z' }, + { "sectors", 1, NULL, 'S' }, + { "heads", 1, NULL, 'H' }, + { "version", 0, NULL, 'v' }, + { "help", 0, NULL, 'h' }, + { 0, 0, 0, 0 } +}; + +static const char short_options[] = "zS:H:vh"; + + + #if defined(__linux__) && !defined(BLKGETSIZE64) /* This takes a u64, but the size field says size_t. Someone screwed big. */ # define BLKGETSIZE64 _IOR(0x12,114,size_t) @@ -358,12 +406,14 @@ get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo) what zipdisks use, so this would help if someone has a USB key that they're booting in USB-ZIP mode. */ - geo->heads = 64; - geo->sectors = 32; - geo->cylinders = totalbytes/(64*32*512); + geo->heads = opt.heads ?: 64; + geo->sectors = opt.sectors ?: 32; + geo->cylinders = totalbytes/(geo->heads*geo->sectors << SECTOR_SHIFT); geo->start = 0; - fprintf(stderr, "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n", - geo->heads, geo->sectors); + + if ( !opt.sectors && !opt.heads ) + fprintf(stderr, "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n", + geo->heads, geo->sectors); return 1; } @@ -384,6 +434,7 @@ patch_file_and_bootblock(int fd, int dirfd, int devfd) unsigned char *p, *patcharea; int i, dw; uint32_t csum; + unsigned int sectors, heads; if ( fstat(dirfd, &dirst) ) { perror("fstat dirfd"); @@ -393,10 +444,15 @@ patch_file_and_bootblock(int fd, int dirfd, int devfd) totalbytes = get_size(devfd); get_geometry(devfd, totalbytes, &geo); + if ( opt.heads ) + geo.heads = opt.heads; + if ( opt.sectors ) + geo.sectors = opt.sectors; + /* Patch this into a fake FAT superblock. This isn't because FAT is a good format in any way, it's because it lets the early bootstrap share code with the FAT version. */ - dprintf("cyl = %u, heads = %u, sect = %u\n", geo.cylinders, geo.heads, geo.sectors); + dprintf("heads = %u, sect = %u\n", geo.heads, geo.sectors); totalsectors = totalbytes >> SECTOR_SHIFT; if ( totalsectors >= 65536 ) { @@ -570,7 +626,7 @@ install_file(char *path, int devfd, struct stat *rst) } int -install_loader(char *path) +install_loader(const char *path, unsigned int sectors, unsigned int heads) { struct stat st, dst, fst; struct mntent *mnt = NULL; @@ -648,11 +704,49 @@ int main(int argc, char *argv[]) { program = argv[0]; - - if ( argc != 2 ) { - fprintf(stderr, "Usage: %s directory\n", program); - exit(1); + int opt; + unsigned long a; + const char *directory; + + while ( (opt = getopt_long(argc, argv, short_options, + long_options, NULL)) != EOF ) { + switch ( opt ) { + case 'z': + opt.heads = 64; + opt.sectors = 32; + break; + case 'S': + opt.sectors = strtoul(optarg, NULL, 0); + if ( opt.sectors < 1 || opt.sectors > 63 ) { + fprintf(stderr, "%s: invalid number of sectors: %u (must be 1-63)\n", + program, opt.sectors); + exit(EX_USAGE); + } + break; + case 'H': + opt.heads = strtoul(optarg, NULL, 0); + if ( opt.heads < 1 || opt.heads > 256 ) { + fprintf(stderr, "%s: invalid number of heads: %u (must be 1-256)\n", + program, opt.heads); + exit(EX_USAGE); + } + break; + case 'h': + usage(0); + break; + case 'v': + fputs("extlinux " VERSION "\n", stderr); + exit(0); + default: + fprintf(stderr, "%s: Unknown option: %c\n", optopt); + exit(EX_USAGE); + } } - return install_loader(argv[1]); + directory = argv[optind]; + + if ( !directory ) + usage(EX_USAGE); + + return install_loader(directory); } diff --git a/version.pl b/version.pl index fa09e40..39d42a0 100755 --- a/version.pl +++ b/version.pl @@ -5,7 +5,7 @@ use Fcntl; -$vfile = $ARGV[0]; +($vfile, $vout, $def) = $ARGV[0]; sysopen(VERSION, $vfile, O_RDONLY) or die "$0: Cannot open $vfile\n"; $version = ; chomp $version; @@ -16,10 +16,11 @@ unless ( $version =~ /^([0-9]+)\.([0-9]+)$/ ) { } $vma = $1+0; $vmi = $2+0; -open(VI, "> version.gen") or die "$0: Cannot create version.gen\n"; -print VI "%define VERSION \"$version\"\n"; -print VI "%define VER_MAJOR $vma\n"; -print VI "%define VER_MINOR $vmi\n"; +sysopen(VI, $vout, O_WRONLY|O_CREAT|O_TRUNC) + or die "$0: Cannot create $vout: $!\n"; +print VI "$def VERSION \"$version\"\n"; +print VI "$def VER_MAJOR $vma\n"; +print VI "$def VER_MINOR $vmi\n"; close(VI);