diff options
Diffstat (limited to 'com32/chain/options.c')
-rw-r--r-- | com32/chain/options.c | 230 |
1 files changed, 135 insertions, 95 deletions
diff --git a/com32/chain/options.c b/com32/chain/options.c index 658a45ca..4e722a01 100644 --- a/com32/chain/options.c +++ b/com32/chain/options.c @@ -1,21 +1,55 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin + * Copyright 2010 Shao Miller + * Copyright 2010-2012 Michal Soltys + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <syslinux/movebits.h> #include <stdint.h> #include <stdlib.h> #include <string.h> -#include "common.h" #include "chain.h" +#include "partiter.h" #include "utility.h" #include "options.h" struct options opt; -static int soi_s2n(char *ptr, unsigned int *seg, - unsigned int *off, - unsigned int *ip, - unsigned int def) +static int soi_s2n(char *ptr, + addr_t *seg, + addr_t *off, + addr_t *ip, + addr_t def) { - unsigned int segval = 0, offval, ipval, val; + addr_t segval, offval, ipval, val; char *p; + /* defaults */ + segval = 0; offval = def; ipval = def; @@ -25,17 +59,22 @@ static int soi_s2n(char *ptr, unsigned int *seg, if (p[0] == ':' && p[1] && p[1] != ':') ipval = strtoul(p+1, NULL, 0); + /* verify if load address is within [dosmin, dosmax) */ val = (segval << 4) + offval; - if (val < ADDRMIN || val > ADDRMAX) { - error("Invalid seg:off:* address specified..\n"); + if (val < dosmin || val >= dosmax) { + error("Invalid seg:off:* address specified."); goto bail; } + /* + * verify if jump address is within [dosmin, dosmax) and offset is 16bit + * sane + */ val = (segval << 4) + ipval; - if (ipval > 0xFFFE || val < ADDRMIN || val > ADDRMAX) { - error("Invalid seg:*:ip address specified.\n"); + if (ipval > 0xFFFE || val < dosmin || val >= dosmax) { + error("Invalid seg:*:ip address specified."); goto bail; } @@ -53,75 +92,82 @@ bail: static void usage(void) { - unsigned int i; - static const char key[] = "Press any key...\n"; + size_t i; static const char *const usage[] = { -"\ -Usage:\n\ - chain.c32 [options]\n\ - chain.c32 {fd|hd}<disk#>{,| }[<part#>] [options]\n\ - chain.c32 mbr{:|=}<id>{,| }[<part#>] [options]\n\ - chain.c32 guid{:|=}<guid>{,| }[<part#>] [options]\n\ - chain.c32 label{:|=}<label> [<part#>] [options]\n\ - chain.c32 boot{,| }[<part#>] [options]\n\ - chain.c32 fs [options]\n\ -", "\ -\nOptions ('no' prefix specifies default value):\n\ - sect[=<s[:o[:i]]>] Load sector at <s:o>, jump to <s:i>\n\ - - defaults to 0:0x7C00:0x7C00\n\ - - ommited o/i values default to 0\n\ - maps Map loaded sector into real memory\n\ - nosetbpb Fix BPB fields in loaded sector\n\ - nofilebpb Apply 'setbpb' to loaded file\n\ - nosave Write adjusted sector back to disk\n\ - hand Prepare handover area\n\ - nohptr Force ds:si and ds:bp to point to handover area\n\ - noswap Swap drive numbers, if bootdisk is not fd0/hd0\n\ - nohide Disable all hide variations (also the default)\n\ - hide Hide primary partitions, unhide selected partition\n\ - hideall Hide *all* partitions, unhide selected partition\n\ - unhide Unhide primary partitions\n\ - unhideall Unhide *all* partitions\n\ - nofixchs Walk *all* partitions and fix E/MBRs' chs values\n\ - nokeeppxe Keep the PXE and UNDI stacks in memory (PXELINUX)\n\ - nowarn Wait for a keypress to continue chainloading\n\ - - useful to see emited warnings\n\ - nobreak Actually perform the chainloading\n\ -", "\ -\nOptions continued ...\n\ - file=<file> Load and execute <file>\n\ - seg=<s[:o[:i]]> Load file at <s:o>, jump to <s:i>\n\ - - defaults to 0:0x7C00:0x7C00\n\ - - ommited o/i values default to 0\n\ - isolinux=<loader> Load another version of ISOLINUX\n\ - ntldr=<loader> Load Windows NTLDR, SETUPLDR.BIN or BOOTMGR\n\ - reactos=<loader> Load ReactOS's loader\n\ - cmldr=<loader> Load Recovery Console of Windows NT/2K/XP/2003\n\ - freedos=<loader> Load FreeDOS KERNEL.SYS\n\ - msdos=<loader> Load MS-DOS 2.xx - 6.xx IO.SYS\n\ - msdos7=<loader> Load MS-DOS 7+ IO.SYS\n\ - pcdos=<loader> Load PC-DOS IBMBIO.COM\n\ - drmk=<loader> Load DRMK DELLBIO.BIN\n\ - grub=<loader> Load GRUB Legacy stage2\n\ - grubcfg=<filename> Set alternative config filename for GRUB Legacy\n\ - grldr=<loader> Load GRUB4DOS grldr\n\ - bss=<filename> Emulate syslinux's BSS\n\ - bs=<filename> Emulate syslinux's BS\n\ -\nPlease see doc/chain.txt for the detailed documentation.\n\ -" - }; +"Usage:", +"", +" disk + partition selection:", +" chain.c32 [options]", +" chain.c32 hd#[,#] [options]", +" chain.c32 fd#[,#] [options]", +" chain.c32 mbr=<id>[,#] [options]", +" chain.c32 guid=<guid>[,#] [options]", +" chain.c32 boot[,#] [options]", +"", +" direct partition selection:", +" chain.c32 guid=<guid> [options]", +" chain.c32 label=<label> [options]", +" chain.c32 fs [options]", +"", +"You can use ':' instead of '=' and ' ' instead of ','.", +"The default is 'boot,0'.", +"", +"Options:", +" sect[=<s[:o[:i]]>] Load sector at <s:o>, jump to <s:i>", +" - defaults to 0:0x7C00:0x7C00", +" - omitted o/i values default to 0", +" maps Map loaded sector into real memory", +" setbpb Fix BPB fields in loaded sector", +" filebpb Apply 'setbpb' to loaded file", +" save Write adjusted sector back to disk", +" hand Prepare handover area", +" hptr Force ds:si and ds:bp to point to handover area", +" swap Swap drive numbers, if bootdisk is not fd0/hd0", +" nohide Disable all hide variations (default)", +" hide Hide primary partitions, unhide selected partition", +" hideall Hide *all* partitions, unhide selected partition", +" unhide Unhide primary partitions", +" unhideall Unhide *all* partitions", +" fixchs Walk *all* partitions and fix E/MBRs' CHS values", +" keeppxe Keep the PXE and UNDI stacks in memory (PXELINUX)", +" warn Wait for a keypress to continue chainloading", +" break Don't chainload", +" relax Relax sanity checks", +" prefmbr On hybrid MBR/GPT disks, prefer legacy layout", +"", +" file=<file> Load and execute <file>", +" seg=<s[:o[:i]]> Load file at <s:o>, jump to <s:i>", +" - defaults to 0:0x7C00:0x7C00", +" - omitted o/i values default to 0", +" isolinux=<loader> Load another version of ISOLINUX", +" ntldr=<loader> Load Windows NTLDR, SETUPLDR.BIN or BOOTMGR", +" reactos=<loader> Load ReactOS's loader", +" cmldr=<loader> Load Recovery Console of Windows NT/2K/XP/2003", +" freedos=<loader> Load FreeDOS KERNEL.SYS", +" msdos=<loader> Load MS-DOS 2.xx - 6.xx IO.SYS", +" msdos7=<loader> Load MS-DOS 7+ IO.SYS", +" pcdos=<loader> Load PC-DOS IBMBIO.COM", +" drmk=<loader> Load DRMK DELLBIO.BIN", +" grub=<loader> Load GRUB Legacy stage2", +" grubcfg=<config> Set alternative config filename for GRUB Legacy", +" grldr=<loader> Load GRUB4DOS grldr", +" bss=<sectimage> Emulate syslinux's BSS", +" bs=<sectimage> Emulate syslinux's BS", +"", +"Please see doc/chain.txt for the detailed documentation." +}; for (i = 0; i < sizeof(usage)/sizeof(usage[0]); i++) { - if (i) { - error(key); + if (i % 20 == 19) { + puts("Press any key..."); wait_key(); } - error(usage[i]); + puts(usage[i]); } } void opt_set_defs(void) { - memset(&opt, 0, sizeof(opt)); + memset(&opt, 0, sizeof opt); opt.sect = true; /* by def. load sector */ opt.maps = true; /* by def. map sector */ opt.hand = true; /* by def. prepare handover */ @@ -136,7 +182,7 @@ void opt_set_defs(void) int opt_parse_args(int argc, char *argv[]) { int i; - unsigned int v; + size_t v; char *p; for (i = 1; i < argc; i++) { @@ -152,7 +198,6 @@ int opt_parse_args(int argc, char *argv[]) opt.bss = true; opt.maps = false; opt.setbpb = true; - /* opt.save = true; */ } else if (!strncmp(argv[i], "bs=", 3)) { opt.file = argv[i] + 3; opt.sect = false; @@ -168,7 +213,6 @@ int opt_parse_args(int argc, char *argv[]) opt.fip = 0; opt.file = argv[i] + 6; opt.setbpb = true; - /* opt.save = true; */ opt.hand = false; } else if (!strncmp(argv[i], "reactos=", 8)) { /* @@ -182,7 +226,6 @@ int opt_parse_args(int argc, char *argv[]) opt.fip = 0x8100; opt.file = argv[i] + 8; opt.setbpb = true; - /* opt.save = true; */ opt.hand = false; } else if (!strncmp(argv[i], "cmldr=", 6)) { opt.fseg = 0x2000; /* CMLDR wants this address */ @@ -191,7 +234,6 @@ int opt_parse_args(int argc, char *argv[]) opt.file = argv[i] + 6; opt.cmldr = true; opt.setbpb = true; - /* opt.save = true; */ opt.hand = false; } else if (!strncmp(argv[i], "freedos=", 8)) { opt.fseg = 0x60; /* FREEDOS wants this address */ @@ -200,7 +242,6 @@ int opt_parse_args(int argc, char *argv[]) opt.sseg = 0x1FE0; opt.file = argv[i] + 8; opt.setbpb = true; - /* opt.save = true; */ opt.hand = false; } else if ( (v = 6, !strncmp(argv[i], "msdos=", v) || !strncmp(argv[i], "pcdos=", v)) || @@ -211,7 +252,6 @@ int opt_parse_args(int argc, char *argv[]) opt.sseg = 0x8000; opt.file = argv[i] + v; opt.setbpb = true; - /* opt.save = true; */ opt.hand = false; } else if (!strncmp(argv[i], "drmk=", 5)) { opt.fseg = 0x70; /* DRMK wants this address */ @@ -223,7 +263,6 @@ int opt_parse_args(int argc, char *argv[]) opt.file = argv[i] + 5; /* opt.drmk = true; */ opt.setbpb = true; - /* opt.save = true; */ opt.hand = false; } else if (!strncmp(argv[i], "grub=", 5)) { opt.fseg = 0x800; /* stage2 wants this address */ @@ -261,15 +300,15 @@ int opt_parse_args(int argc, char *argv[]) } else if (!strcmp(argv[i], "noswap")) { opt.swap = false; } else if (!strcmp(argv[i], "nohide")) { - opt.hide = 0; + opt.hide = HIDE_OFF; } else if (!strcmp(argv[i], "hide")) { - opt.hide = 1; /* 001b */ + opt.hide = HIDE_ON; } else if (!strcmp(argv[i], "hideall")) { - opt.hide = 2; /* 010b */ + opt.hide = HIDE_ON | HIDE_EXT; } else if (!strcmp(argv[i], "unhide")) { - opt.hide = 5; /* 101b */ + opt.hide = HIDE_ON | HIDE_REV; } else if (!strcmp(argv[i], "unhideall")) { - opt.hide = 6; /* 110b */ + opt.hide = HIDE_ON | HIDE_EXT | HIDE_REV; } else if (!strcmp(argv[i], "setbpb")) { opt.setbpb = true; } else if (!strcmp(argv[i], "nosetbpb")) { @@ -296,10 +335,18 @@ int opt_parse_args(int argc, char *argv[]) opt.fixchs = true; } else if (!strcmp(argv[i], "nofixchs")) { opt.fixchs = false; + } else if (!strcmp(argv[i], "relax")) { + opt.piflags |= PIF_RELAX; + } else if (!strcmp(argv[i], "norelax")) { + opt.piflags &= ~PIF_RELAX; } else if (!strcmp(argv[i], "warn")) { opt.warn = true; } else if (!strcmp(argv[i], "nowarn")) { opt.warn = false; + } else if (!strcmp(argv[i], "prefmbr")) { + opt.piflags |= PIF_PREFMBR; + } else if (!strcmp(argv[i], "noprefmbr")) { + opt.piflags &= ~PIF_PREFMBR; } else if (!strcmp(argv[i], "nobreak")) { opt.brkchain = false; } else if (!strcmp(argv[i], "break")) { @@ -337,34 +384,27 @@ int opt_parse_args(int argc, char *argv[]) } if (opt.grubcfg && !opt.grub) { - error("grubcfg=<filename> must be used together with grub=<loader>.\n"); + error("grubcfg=<filename> must be used together with grub=<loader>."); goto bail; } -#if 0 - if ((!opt.maps || !opt.sect) && !opt.file) { - error("You have to load something.\n"); - goto bail; - } -#endif - if (opt.filebpb && !opt.file) { - error("Option 'filebpb' requires a file.\n"); + error("Option 'filebpb' requires a file."); goto bail; } if (opt.save && !opt.sect) { - error("Option 'save' requires a sector.\n"); + error("Option 'save' requires a sector."); goto bail; } if (opt.setbpb && !opt.sect) { - error("Option 'setbpb' requires a sector.\n"); + error("Option 'setbpb' requires a sector."); goto bail; } if (opt.maps && !opt.sect) { - error("Option 'maps' requires a sector.\n"); + error("Option 'maps' requires a sector."); goto bail; } |