diff options
author | Michal Soltys <soltys@ziu.info> | 2010-08-26 09:21:55 +0200 |
---|---|---|
committer | Michal Soltys <soltys@ziu.info> | 2010-09-28 09:32:52 +0200 |
commit | 2cb7f5d10e6c94a0cac7a425f23d244b25b0727b (patch) | |
tree | a8f47119eb18a12db6cb327cb8098a082303de4c | |
parent | 1c1f14dc77b5b361333a7e790eed3206526fb26d (diff) | |
download | syslinux-2cb7f5d10e6c94a0cac7a425f23d244b25b0727b.tar.gz syslinux-2cb7f5d10e6c94a0cac7a425f23d244b25b0727b.tar.xz syslinux-2cb7f5d10e6c94a0cac7a425f23d244b25b0727b.zip |
chain, options: bugfixes, adjustments; big doc update
- seg='s offset values default to 0 if ommited
- sect='s offset values default to 0x7c00 if ommited
- FDOS's bootsector loaded at 0x1fe0
- drive / partition parsing: bugfix, so lables with ',' are recognized
properly
- big documentation update
Signed-off-by: Michal Soltys <soltys@ziu.info>
-rw-r--r-- | com32/chain/chain.c | 7 | ||||
-rw-r--r-- | com32/chain/options.c | 61 | ||||
-rw-r--r-- | com32/chain/options.h | 3 | ||||
-rw-r--r-- | doc/chain.txt | 359 |
4 files changed, 317 insertions, 113 deletions
diff --git a/com32/chain/chain.c b/com32/chain/chain.c index 12372aab..e983dcba 100644 --- a/com32/chain/chain.c +++ b/com32/chain/chain.c @@ -378,7 +378,7 @@ static int pem_setchs(const struct disk_info *di, *(uint32_t *)dp->end != ochs2; } -static int pe_mangle(struct part_iter *_iter) +static int pentry_mangle(struct part_iter *_iter) { int wb = 0, werr = 0; uint32_t cebr_lba = 0; @@ -522,7 +522,7 @@ int find_dp(struct part_iter **_iter) } /* main options done - only thing left is explicit partition specification, * if we're still at the disk stage with the iterator AND user supplied - * partition number (including disk). + * partition number (including disk pseudo-partition). */ if (!iter->index && opt.partition) { partition = strtol(opt.partition, NULL, 0); @@ -713,7 +713,7 @@ int main(int argc, char *argv[]) /* Perform initial partition entry mangling */ if (opt.hide || opt.mbrchs) - pe_mangle(iter); + pentry_mangle(iter); /* hide_unhide(iter);*/ /* Load the boot file */ @@ -817,6 +817,7 @@ int main(int argc, char *argv[]) if (try_mangles_bpb(iter, data + sidx)) goto bail; + /* This *must* be after BPB mangling */ if (opt.cmldr && mangles_cmldr(data + sidx)) goto bail; } diff --git a/com32/chain/options.c b/com32/chain/options.c index f12a9755..6fb07fd8 100644 --- a/com32/chain/options.c +++ b/com32/chain/options.c @@ -8,11 +8,15 @@ int soi_s2n(char *ptr, unsigned int *seg, unsigned int *off, - unsigned int *ip) + unsigned int *ip, + unsigned int def) { - unsigned int segval = 0, offval = 0x7c00, ipval = 0x7c00, val; + unsigned int segval = 0, offval, ipval, val; char *p; + offval = def; + ipval = def; + segval = strtoul(ptr, &p, 0); if (p[0] == ':' && p[1] && p[1] != ':') offval = strtoul(p+1, &p, 0); @@ -53,20 +57,21 @@ void usage(void) "\ Usage:\n\ chain.c32 [options]\n\ - chain.c32 {fd|hd}<disk> [<partition>] [options]\n\ - chain.c32 mbr{:|=}<id> [<partition>] [options]\n\ - chain.c32 guid{:|=}<guid> [<partition>] [options]\n\ - chain.c32 label{:|=}<label> [<partition>] [options]\n\ - chain.c32 boot{,| }[<partition>] [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 specify default value):\n\ - file=<loader> Load and execute file\n\ +\nOptions #1 ('no' prefix specifies default value):\n\ + file=<file> Load and execute <file>\n\ seg=<s[:o[:i]]> Load file at <s:o>, jump to <s:i>\n\ - nofilebpb Treat file in memory as BPB compatible\n\ + - defaults to 0:0x7C00:0x7C00\n\ + - ommited o/i values default to 0\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 0x7C00\n\ + - ommited o/i values default to 0x7C00\n\ maps Map loaded sector into real memory\n\ nosethid[den] Set BPB's hidden sectors field\n\ nosetgeo Set BPB's sectors per track and heads fields\n\ @@ -74,6 +79,9 @@ Usage:\n\ - <off> defaults to autodetection\n\ - only 0x24 and 0x40 are accepted\n\ nosetbpb Enable set{hid,geo,drv}\n\ + nofilebpb Treat file in memory as BPB compatible\n\ +", "\ +\nOptions #2 ('no' prefix specifies default value):\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\ @@ -85,7 +93,7 @@ Usage:\n\ nowarn Wait for a keypress to continue chainloading\n\ - useful to see emited warnings\n\ ", "\ -\nComposite options:\n\ +\nOptions #3 ('no' prefix specifies default value):\n\ isolinux=<loader> Load another version of ISOLINUX\n\ ntldr=<loader> Load Windows NTLDR, SETUPLDR.BIN or BOOTMGR\n\ cmldr=<loader> Load Recovery Console of Windows NT/2K/XP/2003\n\ @@ -122,7 +130,7 @@ int parse_args(int argc, char *argv[]) } else if (!strcmp(argv[i], "nofile")) { opt.file = NULL; } else if (!strncmp(argv[i], "seg=", 4)) { - if (soi_s2n(argv[i] + 4, &opt.fseg, &opt.foff, &opt.fip)) + if (soi_s2n(argv[i] + 4, &opt.fseg, &opt.foff, &opt.fip, 0)) goto bail; } else if (!strncmp(argv[i], "bss=", 4)) { opt.file = argv[i] + 4; @@ -132,6 +140,7 @@ int parse_args(int argc, char *argv[]) opt.setdrv = true; opt.drvoff = ~0u; opt.filebpb = true; + /* opt.save = true; */ } else if (!strncmp(argv[i], "isolinux=", 9)) { opt.file = argv[i] + 9; opt.isolinux = true; @@ -164,9 +173,7 @@ int parse_args(int argc, char *argv[]) opt.fseg = 0x60; /* FREEDOS wants this address */ opt.foff = 0; opt.fip = 0; - opt.sseg = 0x9000; - opt.soff = 0; - opt.sip = 0; + opt.sseg = 0x1FE0; opt.file = argv[i] + 8; opt.sethid = true; opt.setgeo = true; @@ -180,9 +187,7 @@ int parse_args(int argc, char *argv[]) opt.fseg = 0x70; /* MS-DOS 2.00 .. 6.xx wants this address */ opt.foff = 0; opt.fip = v == 7 ? 0x200 : 0; /* MS-DOS 7.0+ wants this ip */ - opt.sseg = 0x9000; - opt.soff = 0; - opt.sip = 0; + opt.sseg = 0x8000; opt.file = argv[i] + v; opt.sethid = true; opt.setgeo = true; @@ -288,7 +293,7 @@ int parse_args(int argc, char *argv[]) } else if (!strncmp(argv[i], "sect=", 5) || !strcmp(argv[i], "sect")) { if (argv[i][4]) { - if (soi_s2n(argv[i] + 5, &opt.sseg, &opt.soff, &opt.sip)) + if (soi_s2n(argv[i] + 5, &opt.sseg, &opt.soff, &opt.sip, 0x7c00)) goto bail; if ((opt.sseg << 4) + opt.soff + SECTOR - 1 > ADDRMAX) { error("Arguments of 'sect=' are invalid - resulting address too big.\n"); @@ -326,13 +331,15 @@ int parse_args(int argc, char *argv[]) || !strncmp(argv[i], "boot,", 5) || !strcmp(argv[i], "fs")) { opt.drivename = argv[i]; - p = strchr(opt.drivename, ','); - if (p) { - *p = '\0'; - opt.partition = p + 1; - } else if (argv[i + 1] && argv[i + 1][0] >= '0' - && argv[i + 1][0] <= '9') { - opt.partition = argv[++i]; + if (strncmp(argv[i], "label", 5)) { + p = strchr(opt.drivename, ','); + if (p) { + *p = '\0'; + opt.partition = p + 1; + } else if (argv[i + 1] && argv[i + 1][0] >= '0' + && argv[i + 1][0] <= '9') { + opt.partition = argv[++i]; + } } } else { usage(); diff --git a/com32/chain/options.h b/com32/chain/options.h index e400eca5..acd50e62 100644 --- a/com32/chain/options.h +++ b/com32/chain/options.h @@ -1,7 +1,8 @@ #ifndef _COM32_CHAIN_OPTIONS_H #define _COM32_CHAIN_OPTIONS_H -int soi_s2n(char *ptr, unsigned int *seg, unsigned int *off, unsigned int *ip); +int soi_s2n(char *ptr, unsigned int *seg, unsigned int *off, + unsigned int *ip, unsigned int def); void usage(void); int parse_args(int argc, char *argv[]); diff --git a/doc/chain.txt b/doc/chain.txt index 5cba3a59..5f28fbeb 100644 --- a/doc/chain.txt +++ b/doc/chain.txt @@ -1,112 +1,307 @@ chain.c32 documentation Although syslinux is capable of (very simple) native chainloading (through .bss -and .bs options - see doc/syslinux.txt), it also has a very roboust and -feature-rich com32 module designed for such purpose. This module should allow -you to boot virtually anything. +and .bs options - see doc/syslinux.txt), it also features a very roboust and +rich com32 module designed for such purpose. +Chain module can perform few basic tasks: -!FIXME: initial move from chain.c below +- load and jump to a sector +- 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 +It can chainload data from both GPT and DOS partitions, as well as boot the +first sector from a raw disk. -Chainload a hard disk. +In more details, the flow of code is as follows: -Usage: chain [options] - chain hd<disk#> [<partition>] [options] - chain fd<disk#> [options] - chain mbr:<id> [<partition>] [options] - chain guid:<guid> [<partition>] [options] - chain label:<label> [<partition>] [options] - chain boot [<partition>] [options] +1. Parse arguments. +2. Find drive and/or partition to boot from. +3. Hide / unhide systems and/or fix chs values in partition entries on the + drive syslinux is booting from (options: 'hide', 'hideall', 'mbrchs'). +4. Load file to boot from (options: 'file', 'seg'). +5. Load sector to boot from (options: 'sect', 'maps'), if it doesn't conflict + with #5. +6. Prepare handover area (options: 'hand', 'maps'), if it doesn't conflict + with #5 & #6, and syslinux is booting a partition. +7. Adjust ds:si and ds:bp to point to either a handover, a sector (options: + 'hptr', 'maps', 'sect', 'file') or nowhere. +8. Patch loaded file if necessary ('isolinux', 'grub', 'grldr', 'filebpb') +9. Patch loaded sector if necessary ('setdrv', 'sethid', 'setgeo', 'setbpb', + 'save', 'cmldr') +10. Chainload (options: 'swap'). -For example, "chain msdos=io.sys" will load DOS from the current Syslinux -filesystem. "chain hd0 1" will boot the first partition on the first hard -disk. +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. -When none of the "hdX", "fdX", "mbr:", "guid:", "label:", "boot" or "fs" -options are specified, the default behaviour is equivalent to "boot". -"boot" means to use the current Syslinux drive, and you can also specify -a partition. -The mbr: syntax means search all the hard disks until one with a -specific MBR serial number (bytes 440-443) is found. +Module invocation: -Partitions 1-4 are primary, 5+ logical, 0 = boot MBR (default.) +chain [drive/partition] [options] -"fs" will use the current Syslinux filesystem as the boot drive/partition. -When booting from PXELINUX, you will most likely wish to specify a disk. + DRIVE / PARTITION SPECIFICATION -Options: +Drive can be specified as 'hd#', 'fd#', 'boot', 'mbr', or 'guid'. -file=<loader> - loads the file <loader> **from the Syslinux filesystem** - instead of loading the boot sector. +- 'mbr' will select a drive by a signature. +- 'guid' will select a drive by a guid +- 'boot' is the drive syslinux was booted from. This is the default value, if + nothing else is specified. +- 'hd#' and 'fd#' are standard ways to specify drive number as seen by bios, + starting from 0. -seg=<segment> - loads at and jumps to <seg>:0000 instead of 0000:7C00. +Option 'guid' is shared with partition selection (see below). If you happened +to have non-unique guids, they are searched in disk0, partitions of disk0, +disk1 ... order. -isolinux=<loader> - chainload another version/build of the ISOLINUX bootloader and patch - the loader with appropriate parameters in memory. - This avoids the need for the -eltorito-alt-boot parameter of mkisofs, - when you want more than one ISOLINUX per CD/DVD. +The priority of those options are the same as in the above list. -ntldr=<loader> - equivalent to seg=0x2000 file=<loader> sethidden, - used with WinNT's loaders +If you specify the same value more than once, the last value will be used. -cmldr=<loader> - used with Recovery Console of Windows NT/2K/XP. - same as ntldr=<loader> & "cmdcons\0" written to - the system name field in the bootsector +'mbr' and 'guid' take extra parameter - you should use ':' or '=' as a +delimiter. -freedos=<loader> - equivalent to seg=0x60 file=<loader> sethidden, - used with FreeDOS' kernel.sys. -msdos=<loader> -pcdos=<loader> - equivalent to seg=0x70 file=<loader> sethidden, - used with DOS' io.sys. +Partition can be specified as '#', 'guid', 'label' or 'fs'. -grub=<loader> - same as seg=0x800 file=<loader> & jumping to seg 0x820, - used with GRUB Legacy stage2 files. +- 'guid' option will select a partition by a guid (not a type guid !) +- 'label' will select a partition by a label (searching is done in + disk order) +- 'fs' will select a partition from which syslinux was executed +- '#' is the standard method. Partitions 1-4 are primary, 5+ logical, 0 = boot + MBR (default). -grubcfg=<filename> - set an alternative config filename in stage2 of Grub Legacy, - only applicable in combination with "grub=<loader>". +The priority of those options are the same as in the above list. -grldr=<loader> - pass the partition number to GRUB4DOS, - used with GRUB4DOS' grldr. +If you use a number to select a partition it should be specified after a drive +using space or comma as delimiters (after 'hd#', 'fd#', 'mbr', 'guid' or 'boot'). -swap - if the disk is not fd0/hd0, install a BIOS stub which swaps - the drive numbers. + OPTIONS + file=<file> + *nofile -hide - change type of primary partitions with IDs 01, 04, 06, 07, - 0b, 0c, or 0e to 1x, except for the selected partition, which - is converted the other way. +It's often convenient to load a file directly and transfer control to it, +instead of the sector from the disk. Note, that the <file> must reside on +syslinux partition. -sethidden - update the "hidden sectors" (partition offset) field in a - FAT/NTFS boot sector. +If you choose this option without specifying any addresses explicitly (see +options 'sect=' and 'seg='), the file will cause sector to not be loaded at all +(as their memory placement would overlap). -keeppxe - keep the PXE and UNDI stacks in memory (PXELINUX only). + seg=<segment>:<offset>:<ip> + *seg=0:0x7c00:0x7c00 +This triplet lets you alter the addresses a file will use. Loading is done to +<segment:offset>, jumping to <segment:ip>. When you chainload some other +bootloader or kernel, it's almost always mandatory. - file=<loader> Load and execute file; boot sector is also\n\ - msdos7=<loader> Load MS-DOS 7+ IO.SYS\n\ - seg=<s[:o[:i]]> Load file at <s:o>, jump to <s:i>\n\ - segbs=<s[:o[:i]]> Load boot sector at <s:o>, jump to <s:i>;\n\ - sethidden Set the FAT/NTFS hidden sectors field\n\ - setgeometry Set the FAT/NTFS sectors per track and heads fields\n\ - setdrive@<offset> Set the FAT/NTFS drive unit field at <offset>;\n\ - setdrive option alone defaults to 0x24\n\ - setbpb Enable set{hidden,geometry} options\n\ - writebs Write updated boot sector to the disk\n\ - filebpb Also mangle file with bpb options\n\ - bsnomap Don't map boot sector into real memory.\n\ +The defaults, if option is not specified, are 0:0x7c00:0x7c00 +If some of the fields are ommited (e.g. 0x2000::), they default to 0. + + sect=<segment>:<offset>:<ip> + nosect + *sect=0:0x7c00:0x7c00 + +This triplet lets you alter the addresses a sector will use. File is loaded at +<segment:offset>, the jump is made to <segment:ip>. This option is mostly used +in tandem with 'file=' and 'seg=' options, as some loaders/kernels will expect +relocated sector at some particular address (e.g. DRKM). + +'nosect' will cause sector to not be loaded at all. In plenty cases, when a file +is being chainloaded, sector is not necessary. + +The defaults if option is not specified, are 0:0x7c00:0x7c00. +If some of the fields are ommited (e.g. 0x2000::), segment defaults to 0, +offset and ip to 0x7c00. + + *maps + nomaps + +In some cases, it's useful to fix BPB values in NTFS/FATxx bootsectors and +evntually write them back, but otherwise boot sector itself is not necessary to +continue booting. 'nomaps' allows that - a sector will be loaded, but won't be +mmapped into real memory. Any overlap tests (vs. handover or file areas) are +not performed, being meaningless in such case. + + sethid[den] + *nosethid[den] + + setgeo + *nosetgeo + + setdrv[@<addr>] + *nodrv + +Microsoft side of the world is paritculary bitchy about certain BPB values. +Depending on the system and chainloading method (sector or file), some or all +of those fields must match reality - and after e.g. drive clonning or +when using usb stick in different computers - that is often not the case. + +The "reality" means: + +"hidden sectors" - valid offset of the partition from the beginning of the disk +"geometry" - valid disk geometry as reported by BIOS +"drive" - valid drive number + +'sethidden' + updates the partition offset to match the current disk position +'setgeo' + updates "heads" and "sectors per track" values as reported by BIOS +'setdrv' + will update the drive value at proper offset. Only 0x24 and 0x40 are + accepted as valid values. You can use '@', '=' and ':' as delimiters. + If the address is not specified, it's autodetected. + + setbpb + *nosetbpb + +Handy shortcut for setdrv, setgeo and sethid. + + filebpb + *nofilebpb + +Chainloaded file can simply be an image of a sector. In such case, it could be +useful to also fix its BPB values. + + save + *nosave + +Fixing BPB values only in memory might not be enough. This option allows +writing of the corrected sector. You will probably want to use this option +together with 'setbpb' or other ones using that implicitly. + +- this option never applies to a loaded file +- chain module will never save anything to disk by default +- writing is only performed, if the values actually changed + + hand + *hand + +By default, a handover area is always prepared if possible and potentially +useful - meaning it doesn't overlap with other areas, and syslinux chainloads a +partition. It's often not necessary though - usually, a chainloaded file or +kernel don't care about it anymore, so a user can disable it explicitly with +this option. + + hptr + *nohptr + +In case when both file and sector are loaded, ds:si and ds:bp will point to +sector address before the chainloading. This option lets user force those +registers to point to handover area. This is useful when both the file and the +sector are actually a sector's image and the sector is mmapped. + + swap + *noswap + +This option will install a tiny stub code used to swap drive numbers, if the +drive we use during chainloading is not fd0 or hd0. + + hide[all] + *nohide + +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 boot drive. +Writing is only performed, if the values actually changed. + + mbrchs + *nombrchs + +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 +'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 +them at all. Writing is only performed, if the values actually changed. + + keepexe + *nokeepexe + +If you're booting over a network using pxelinux - this lets you keep UNDI +stacks in memory. + + warn + *nowarn + +This option will wait for a keypress right before continuing the chainloading. +Useful to see warnings emited by the chain module. + + isolinux=<file> + sets: file=<file> nohand nosect + +Chainload another version/build of the ISOLINUX bootloader and patch the loader +with appropriate parameters in memory. This avoids the need for the +-eltorito-alt-boot parameter of mkisofs, when you want more than one ISOLINUX +per CD/DVD. + + ntldr=<file> + sets: file=<file> seg=0x2000 setbpb nohand + +Prepares to load ntldr directly. You might want to add 'save' option to store +corrected BPB values. + + cmldr=<file> + sets: file=<file> seg=0x2000 setbpb nohand + +Prepares to load recovery console directly. In-memory copy of bootsector is +patched with "cmdcons\0". Remarks the same as in 'ntldr='. + + freedos=<file> + sets: file=<file> seg=0x60 sect=0x1FE0 setbpb nohand + +Prepares to load freedos kernel directly. You will likely want to add 'save' +option, as those kernels seem to require proper geometry written back to disk. +Sector address is chosen based on where freedos' bootsectors relocate themselves, +although it seems the kernel doesn't rely on one. +You might also want to employ 'hide' option, if you have problems with properly +assigned C: drive. + + pcdos=<file> + msdos=<file> + sets: file=<file> seg=0x70 sect=0x8000 setbpb nohand + +Similary to 'freedos=', This prepares to load MSDOS 2.00 - 6.xx or derivatives. +Sector address is chosen arbitrarily. Otherwise comments as above. + + msdos7=<file> + sets: file=<file> seg=0x70::0x200 sect=0x8000 setbpb nohand + +Only for MSDOS 7+ versions (98se ~ 7.xx, millenium ~ 8.xx). Comments as above. +TODO/TEST + + drmk=<file> + sets: file=<file> seg=0x70 sect=0x2000:0:0 setbpb nohand + +This is used for loading of *only* Dell's DOS derivatives. It does require boot +sector at 0x2000 and overall valid BPB values. As with other DOSish cases, +likely candidates for use are 'save' and 'hide'. + + grub=<file> + grubcfg=<config> + sets: file=<file> seg=0x800::0x200 nohand nosect + +Chainloads grub legacy's stage2, performing additional corrections on the file +in memory. Additionally, alternate config file can be specified through +'grubcfg=' option + + grldr=<file> + sets: file=<file> nohand nosect + +Chainloads GRUB4DOS grldr, performing additional corrections on the file +in memory. + + bss=<file> + sets: bss=<file> nomaps setbpb filebpb + +This attempts to emulate syslinux's native BSS option to certain extent. This +loads both the file and the sector and adjusts BPB values in both. As only basic BPB +fields are corrected, both the file and the sector should be identical enough +(except boot code, drive number, geometry, hidden sectors). Don't forget about +'save' and 'swap' options. + +This will likely get expanded in future. |