| chain.c32 documentation |
| |
| Although syslinux is capable of (very simple) native chainloading (through .bss |
| 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: |
| |
| - 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 |
| - 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. |
| |
| In more details, the rough overview of code is as follows: |
| |
| 1. Parse arguments. |
| 2. Find drive and/or partition to boot from. |
| 3. Perform partition-level patching - for example hiding, unhiding, fixing chs values, etc. |
| 4. Load a file to boot from. |
| 5. Load a sector to boot from, if it doesn't conflict with #5. |
| 6. Prepare handover area, if it doesn't conflict with #5 & #6. |
| 7. Prepare registers. |
| 8. Patch loaded file if necessary. |
| 9. Patch loaded sector if necessary. |
| 10. Chainload. |
| |
| 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: |
| |
| - 'break' is in effect |
| |
| or |
| |
| - 'nofile' and 'nomaps' (or 'nosect') are in effect |
| |
| This is useful for invocations such as: |
| |
| chain.c32 hdN M setbpb save break |
| chain.c32 hdN fixchs break |
| chain.c32 hdN unhideall break |
| |
| Please see respective options for more details. |
| |
| |
| Module invocation: |
| |
| chain [drive/partition] [options] |
| |
| In case of repeated arguments, rightmost ones take precedence. |
| |
| |
| DRIVE / PARTITION SPECIFICATION |
| |
| Drive can be specified as 'hd#', 'fd#', 'boot', 'mbr', or 'guid'. |
| |
| - 'mbr' will select a drive by its signature. |
| - 'guid' will select a drive by its guid (GPT only). |
| - '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. |
| |
| Option 'guid' is shared with partition selection (see below). If you happen |
| to have non-unique guids, they are searched in disk0, partitions of disk0, |
| disk1 ... order. |
| |
| 'mbr' and 'guid' take extra parameter - you should use ':' or '=' as a |
| delimiter. |
| |
| Partition can be specified as '#', 'guid', 'label' or 'fs'. |
| |
| - '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). |
| |
| 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'). |
| |
| |
| OPTIONS |
| file=<file> |
| *nofile |
| |
| 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. |
| |
| 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). |
| |
| seg=<segment>:<offset>:<ip> |
| *seg=0:0x7c00:0x7c00 |
| |
| This triplet lets you alter the addresses a file will use. It's loaded at |
| <segment:offset>, the entry point is at <segment:ip>. When you chainload some |
| other bootloader or kernel, it's almost always mandatory. |
| |
| The defaults, if option is not specified, are 0:0x7c00:0x7c00 |
| If any of the fields are omitted (e.g. 0x2000::), they default to 0. |
| |
| sect=<segment>:<offset>:<ip> |
| *sect=0:0x7c00:0x7c00 |
| nosect |
| nosect sets: nomaps |
| |
| This triplet lets you alter the addresses a sector will use. It's loaded at |
| <segment:offset>, the entry point is at <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 omitted (e.g. 0x2000::), they default to 0. |
| |
| *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. |
| |
| setbpb |
| *nosetbpb |
| |
| Microsoft side of the world is paritculary sensitive to 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 |
| |
| This option will automatically determine the type of BPB and fix what is possible |
| to fix, relatively to detected BPB. If it's impossible to detect BPB, function |
| will do nothing. |
| |
| 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 |
| save sets: strict=2 |
| |
| 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'. |
| |
| - this option never applies to a loaded file |
| - chain module will not save anything to disk by default (besides options such |
| as hide or fixchs - so options related directly to partition entries) |
| - writing is only performed, if the values actually changed |
| |
| *hand |
| nohand |
| |
| By default, a handover area is always prepared if possible - meaning it doesn't |
| overlap with other areas. 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] |
| unhide[all] |
| *nohide |
| [un]hide[all] sets: strict=2 |
| |
| 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 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. |
| |
| fixchs |
| *nofixchs |
| fixchs sets: strict=2 |
| |
| 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 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 |
| them at all. Writing is only performed, if the values actually got changed. |
| |
| keepexe |
| *nokeepexe |
| |
| If you're booting over a network using pxelinux - this lets you keep UNDI |
| stacks in memory (pxelinux only). |
| |
| warn |
| *nowarn |
| |
| This option will wait for a keypress right before continuing the chainloading. |
| Useful to see warnings emited by the chain module. |
| |
| prefmbr |
| *noprefmbr |
| |
| In the case of presence of non-standard hybrid MBR/GPT layout, this flag makes |
| chain module prefer MBR layout over GPT. |
| |
| strict[=<0|1|2>] |
| *strict=1 |
| relax |
| |
| Those options control the level of sanity checks used during the traversal of |
| partition table(s). This is useful in buggy corner cases, when the disk size is |
| reported differently across different computers or virtual machines (if it |
| happens at all, the size usually differs by 1 sector). Normally the partition |
| iterator would report an error and abort in such case. Another case scenario is |
| disk corruption in some later EMBR partition. |
| |
| - strict=0 inhibits any checks |
| - strict=1 enables checks, but ignores those that involve disk size |
| - strict=2 enables all checks |
| - relax and nostrict are equivalent to strict=0 |
| - norelax and strict are equivalent to strict=2 |
| |
| |
| break |
| *nobreak |
| break 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. |
| 'break' 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 'fixchs', '[un]hide[all]' and setbpb. |
| |
| isolinux=<file> |
| sets: file=<file> nohand nosect isolinux |
| |
| 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 cmldr |
| |
| Prepares to load recovery console directly. In-memory copy of bootsector is |
| patched with "cmdcons\0". Remarks the same as in 'ntldr='. |
| |
| reactos=<file> |
| sets: file=<file> seg=0:0x8000:0x8100 setbpb nohand |
| |
| Prepares to load ReactOS's freeldr directly. You might want to add 'save' |
| option to store corrected BPB values. |
| |
| 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 it. |
| |
| 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, Me ~ 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 in other DOS-ish cases, |
| likely candidates for use are 'save' and 'hide'. |
| |
| grub=<file> [grubcfg=<config>] |
| sets: file=<file> seg=0x800::0x200 nohand nosect grub |
| |
| 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 grldr |
| |
| Chainloads GRUB4DOS grldr, performing additional corrections on the file |
| in memory. |
| |
| bss=<file> |
| sets: file=<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 |
| fields to the loaded file. Everything is made with reference to the selected |
| disk/partition. |
| |
| bs=<file> |
| sets: file=<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 |
| disk/partition. |
| |