From eadb9947a49e7ddc2ce29e567ae70c2c02e7571a Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Tue, 5 Oct 2010 23:27:03 +0200 Subject: [PATCH] com32/chain: allow service-only runs This patch introduces small feature, allowing so called "service-only" runs - where the chain modules does everything as instructed, but otherwise doesn't perform actual chainloading. This is useful for 'mbrchs', '[un]hide[all]' and 'setbpb'+'save' options, making possible adjustments to partition/boot sector values on any disk/partition. See 'chain' option in doc/chain.txt for more details. Signed-off-by: Michal Soltys --- com32/chain/chain.c | 14 +++++++++----- com32/chain/options.c | 29 +++++++++++++++++++++-------- com32/chain/options.h | 1 + doc/chain.txt | 36 ++++++++++++++++++++++++++++++++---- 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/com32/chain/chain.c b/com32/chain/chain.c index 25d8fa7..73d107d 100644 --- a/com32/chain/chain.c +++ b/com32/chain/chain.c @@ -662,9 +662,10 @@ int main(int argc, char *argv[]) memset(&hdat, 0, sizeof(hdat)); memset(&sdat, 0, sizeof(sdat)); 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 */ + opt.sect = true; /* by def. load sector */ + opt.maps = true; /* by def. map sector */ + opt.hand = true; /* by def. prepare handover */ + opt.chain = true; /* by def. do chainload */ opt.foff = opt.soff = opt.fip = opt.sip = 0x7C00; opt.drivename = "boot"; #ifdef DEBUG @@ -777,7 +778,7 @@ int main(int argc, char *argv[]) goto bail; /* - * Prepare boot-time mmap data We should to it here, as manglers could + * Prepare boot-time mmap data. We should to it here, as manglers could * potentially alter some of the data. */ @@ -806,7 +807,10 @@ int main(int argc, char *argv[]) wait_key(); } - do_boot(data, ndata); + if (ndata && opt.chain) /* boot only if we actually chainload */ + do_boot(data, ndata); + else + error("Service-only run completed, exiting.\n"); bail: pi_del(&iter); /* Free allocated areas */ diff --git a/com32/chain/options.c b/com32/chain/options.c index 2c3d0ff..53810da 100644 --- a/com32/chain/options.c +++ b/com32/chain/options.c @@ -65,10 +65,6 @@ Usage:\n\ chain.c32 fs [options]\n\ ", "\ \nOptions ('no' prefix specifies default value):\n\ - file= Load and execute \n\ - seg= Load file at , jump to \n\ - - defaults to 0:0x7C00:0x7C00\n\ - - ommited o/i values default to 0\n\ sect[=] Load sector at , jump to \n\ - defaults to 0:0x7C00:0x7C00\n\ - ommited o/i values default to 0x7C00\n\ @@ -78,17 +74,23 @@ Usage:\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\ - bss= Emulate syslinux's BSS\n\ - bs= Emulate syslinux's BS\n\ noswap Swap drive numbers, if bootdisk is not fd0/hd0\n\ - nohide Hide primary partitions, unhide selected partition\n\ - nohideall Hide *all* partitions, unhide selected partition\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\ nombrchs 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\ + chain Actually perform the chainloading\n\ ", "\ \nOptions continued ...\n\ + file= Load and execute \n\ + seg= Load file at , jump to \n\ + - defaults to 0:0x7C00:0x7C00\n\ + - ommited o/i values default to 0\n\ isolinux= Load another version of ISOLINUX\n\ ntldr= Load Windows NTLDR, SETUPLDR.BIN or BOOTMGR\n\ cmldr= Load Recovery Console of Windows NT/2K/XP/2003\n\ @@ -100,6 +102,8 @@ Usage:\n\ grub= Load GRUB Legacy stage2\n\ grubcfg= Set alternative config filename for GRUB Legacy\n\ grldr= Load GRUB4DOS grldr\n\ + bss= Emulate syslinux's BSS\n\ + bs= Emulate syslinux's BS\n\ \nPlease see doc/chain.txt for the detailed documentation.\n\ " }; @@ -268,6 +272,13 @@ int parse_args(int argc, char *argv[]) opt.warn = true; } else if (!strcmp(argv[i], "nowarn")) { opt.warn = false; + } else if (!strcmp(argv[i], "chain")) { + opt.chain = true; + } else if (!strcmp(argv[i], "nochain")) { + opt.chain = false; + opt.file = NULL; + opt.maps = false; + opt.hand = false; } else if (((argv[i][0] == 'h' || argv[i][0] == 'f') && argv[i][1] == 'd') || !strncmp(argv[i], "mbr:", 4) @@ -302,10 +313,12 @@ int parse_args(int argc, char *argv[]) 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"); diff --git a/com32/chain/options.h b/com32/chain/options.h index ee15768..bc244f6 100644 --- a/com32/chain/options.h +++ b/com32/chain/options.h @@ -29,6 +29,7 @@ struct options { bool filebpb; bool mbrchs; bool warn; + bool chain; uint16_t keeppxe; struct syslinux_rm_regs regs; }; diff --git a/doc/chain.txt b/doc/chain.txt index 76234f1..c508651 100644 --- a/doc/chain.txt +++ b/doc/chain.txt @@ -10,6 +10,7 @@ Chain module can perform few basic tasks: - load and jump to a file (also loading a sector for other purposes) - prepare handover data to use by a file / boot sector - fix different options in a file / sector / partition entries +- perform a "service-only" run It can chainload data from both GPT and DOS partitions, as well as boot the first sector from a raw disk. @@ -33,6 +34,22 @@ In most basic form, syslinux loads specified boot sector (or mbr, if not specified) at 0:0x7c00, prepares handover area as a standard mbr would do, and jumps to 0:0x7c00. +A "service-only" run is possible when either: + +- 'nochain' is in effect + +or + +- 'nofile' and 'nomaps' are in effect + +This is useful for invocations such as: + +chain.c32 hdN M setbpb save nochain +chain.c32 hdN mbrchs nochain +chain.c32 hdN unhideall nochain + +Please see respective options for more details. + Module invocation: @@ -187,7 +204,7 @@ drive we use during chainloading is not fd0 or hd0. In certain situations it's useful to hide partitions - for example to make sure DOS gets C:. 'hide' will hide hidable primary partitions, except the one we're booting from. Similary, 'hideall' will hide all hidable partitions, except the -one we're booting from. Hiding is performed only on the booting drive. Options +one we're booting from. Hiding is performed only on the selected drive. Options starting with 'un' will simply unhide every partition (primary ones or all). Writing is only performed, if the os type values actually changed. @@ -196,7 +213,7 @@ Writing is only performed, if the os type values actually changed. If you want to make a drive you're booting from totally compatible with current BIOS, you can use this to fix all partitions' CHS numbers. Good to silence e.g. -FreeDOS complainig about 'logical CHS differs from physcial' of sfdisk about +FreeDOS complainig about 'logical CHS differs from physical' of sfdisk about 'found (...) expected (...). Functionally seems to be mostly cosmetic, as Microsoft world - in cases it cares about geometry - generally sticks to values written in bootsectors. And the rest of the world generally doesn't care about @@ -214,6 +231,17 @@ stacks in memory (pxelinux only). This option will wait for a keypress right before continuing the chainloading. Useful to see warnings emited by the chain module. + *chain + nochain + nochain sets: nofile nomaps nohand + +It is possible to trigger a "service-only" run - The chain module will do +everything requested as usual, but it will not perform the actual chainloading. +'nochain' option disables handover, file loading and sector mapping, as these +are pointless in such scenario (although file might be reenabled in some future +version, if writing to actual files becomes possible). Mainly useful for +options 'mbrchs', '[un]hide[all]' and setbpb. + isolinux= sets: file= nohand nosect isolinux @@ -279,7 +307,7 @@ Chainloads GRUB4DOS grldr, performing additional corrections on the file in memory. bss= - sets: bss= nomaps setbpb bss + sets: file= nomaps setbpb bss This emulates syslinux's native BSS option. This loads both the file and the sector, adjusts BPB values in the loaded sector, then copies all possible BPB @@ -287,7 +315,7 @@ fields to the loaded file. Everything is made with reference to the selected disk/partition. bs= - sets: bs= nosect filebpb + sets: file= nosect filebpb This emulates syslinux's native BS option. This loads the file and if possible - adjusts its BPB values. Everything is made with reference to the selected -- 2.7.4