Doc/chain
Contents
- 1 Introduction
- 2 Syntax
- 3 Drive
- 4 Partition
- 5 Options
- 5.1 swap
- 5.2 prefmbr
- 5.3 hide
- 5.4 fixchs
- 5.5 gpthcrc and gptlcrc
- 5.6 strict
- 5.7 file
- 5.8 seg
- 5.9 sect
- 5.10 maps
- 5.11 hand
- 5.12 hptr
- 5.13 setbpb
- 5.14 filebpb
- 5.15 save
- 5.16 keeppxe
- 5.17 break
- 5.18 warn
- 5.19 exit
- 5.20 isolinux
- 5.21 ntldr
- 5.22 cmldr
- 5.23 reactos
- 5.24 freedos
- 5.25 msdos and pcdos
- 5.26 msdos7
- 5.27 drmk
- 5.28 grub
- 5.29 grldr
- 5.30 bs
- 5.31 bss
- 6 See Also
Introduction
Although Syslinux is capable of (very simple) native chainloading (through .bss and .bs files - see doc/syslinux), it also features a very robust and rich com32 module designed for such purpose.
The chain.c32 module can perform some 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 be used 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 [4.00+] and MBR (aka. DOS) partitions, as well as boot the first sector from a raw disk.
A rough overview of the code is as follows:
- Parse arguments.
- Find drive and/or partition to boot from.
- Perform partition-level patching - for example (un)hiding, fixing CHS values, etc.
- Load a file to boot from.
- Load a sector to boot from, if it doesn't conflict with #4.
- Prepare handover area, if it doesn't conflict with #4 and #5.
- Prepare registers.
- Patch loaded file if necessary.
- Patch loaded sector if necessary.
- Chainload.
In its most basic form, chain.c32 loads either an MBR
or a specified boot sector 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:
- the 'break' option is in effect; or,
- options '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 the respective options for more details.
Syntax
chain [drive/partition] [options]
In case of repeated arguments, the rightmost ones take precedence.
Note that some options cannot be combined with some other options.
OPTION | TYPE | BIOS | MBR/GPT | PT | VBR |
---|---|---|---|---|---|
boot | flag | Syslinux's boot drive | |||
mbr | argument | Match ID | |||
guid | argument | Match ID | Match ID | ||
label | argument | Match ID | |||
hd#,# | argument | Device # | Device # | ||
fs | flag | Syslinux's boot volume | |||
fd# | argument | Device # |
Drive
Drives can be specified as either:
- mbr
- select a disk by its signature;
- guid
- select a disk by its guid (GPT only);
- boot
- the drive SYSLINUX was booted from. This is the default value, if nothing else is specified.
- hd#
- drive number as seen by BIOS, starting from 0.
- fd#
- floppy drive number as seen by BIOS, starting from 0.
Option 'guid' is shared with partition selection. If there are non-unique guids, they are searched first in disk0, then partitions of disk0, then disk1, ... order.
'mbr' and 'guid' take an extra parameter; use either ':' or '=' as delimiter.
Partition
Partition can be specified as either:
- guid
- select a partition by a specified guid value (not by guid type !);
- label
- select a partition by a specified label (searching by disk order);
- fs
- the partition SYSLINUX was booted from;
- #
- partition number within disk; the standard method. Partitions 1-4 are primary, 5+ are logical, 0 (zero) is the MBR (default).
If a partition is selected by number, it should be specified after a disk drive notation by using either a space or a comma character as delimiter (after 'hd#', 'fd#', 'mbr', 'guid' or 'boot').
Options
OPTION | TYPE | BIOS | MBR/GPT | PT | VBR | FILE | OTHER |
---|---|---|---|---|---|---|---|
swap | flag | Set as first device | |||||
prefmbr | flag | Prefer MBR over GPT | |||||
hide | multiflag | Modify partition ID | |||||
fixchs | flag | Fix CHS | |||||
gpthcrc | flag | GPT header checksum | |||||
gptlcrc | flag | GPT list checksum | |||||
strict | multiflag | Sanity check level | |||||
file | argument | Select file to load | |||||
seg | argument | Address | |||||
sect | argument | Address | |||||
maps | flag | Map in address | |||||
hand | flag | Use handover (area) | |||||
hptr | flag | Point registers to handover area | |||||
setbpb | flag | Patch BPB | |||||
filebpb | flag | Patch BPB | |||||
save | flag | Write BPB | |||||
keeppxe | flag | Keep UNDI stack loaded | |||||
break | flag | Service-only run | |||||
warn | flag | Wait for a key-press | |||||
exit | flag | Force end of command line | |||||
isolinux | shortcut | Load a different ISOLINUX version | |||||
ntldr | shortcut | Windows NTLDR | |||||
cmldr | shortcut | Windows Recovery Console | |||||
reactos | shortcut | Reactos freeldr.sys | |||||
freedos | shortcut | FreeDOS kernel.sys | |||||
pcdos | shortcut | PCDOS ibmbio.com | |||||
msdos | shortcut | MSDOS 2-6.xx io.sys | |||||
msdos7 | shortcut | MSDOS7+ io.sys | |||||
drmk | shortcut | DELLDOS dellbio.bin | |||||
grub | shortcut | GRUB legacy's stage2 | |||||
grldr | shortcut | GRUB4DOS grldr | |||||
bs | shortcut | Emulate SYSLINUX's BS | |||||
bss | shortcut | Emulate SYSLINUX's BSS |
swap
swap *noswap
§ [3.70+] Install a tiny stub code that swaps device numbers, if the device we use during chainloading is not 'fd0' nor 'hd0'.
prefmbr
prefmbr *noprefmbr
§ In case non-standard hybrid MBR/GPT layout is present, this flag makes the chain module prefer MBR layout over GPT.
hide
[un]hide[all] → sets: strict=2 *nohide |
§ [3.71+] Modify the partition ID ("type") in the partition table (typically, "0x0n"↔"0x1n"). In certain situations it is useful to hide partitions; for example to make sure DOS gets "C:". 'hide' will hide hidable primary partitions, except the one we are booting from. Similarly, 'hideall' will hide all hidable partitions, except the one we are booting from. Hiding is performed only on the selected disk. Options starting with 'un' will simply unhide partitions (primary ones or all, accordingly). The writing is only performed if the values actually changed. See also 'break'.
fixchs
fixchs → sets: strict=2 *nofixchs |
§ Fix all partitions' CHS numbers so as to make the partition table totally compatible with the current BIOS. This option can be useful, for example, to silence FreeDOS complaining about "logical CHS differs from physical", or sfdisk about "found (...) expected (...)". Functionally, it seems to be mostly cosmetic, as Microsoft's world (when 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. The writing is only performed if the values actually changed. See also 'break'.
gpthcrc and gptlcrc
*gpthcrc → Perform gpt header crc check nogpthcrc → Skip crc check *gptlcrc → Perform gpt list crc check nogptlcrc → Skip crc check |
§ Force boot when checksums of GPT header and/or partition list are invalid. This works independently from the 'strict' option.
strict
strict[=<0|1|2>] *strict=1 relax
- '
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
'.
§ [6.03+] Control the level of sanity checks used during the traversal of partition table(s). This is potentially useful in (buggy) corner cases, for example 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.
file
file=</><path/to/><myfile> *nofile
§ [3.70+] It is often convenient to load a file directly and transfer control to it, instead of the sector from the disk. Note that <myfile> must reside on the Syslinux's filesystem volume.
Choosing a file without explicitly specifying any addresses (see options 'sect' and 'seg') will cause the sector to not be loaded at all (as their memory placement would overlap).
seg
seg=<segment>:<offset>:<ip> *seg=0:0x7c00:0x7c00
§ [3.70+]
Alter the addresses a file will use. It is loaded at
'<segment:offset>
'; the entry point is at '<segment:ip>
'.
When chainloading some other bootloader or kernel, this option is almost always mandatory.
If this option is not specified, the defaults are '0:0x7c00:0x7c00
'.
If any field is omitted (e.g. '0x2000::'), it defaults to 0.
sect
sect=<segment>:<offset>:<ip> *sect=0:0x7c00:0x7c00 nosect → sets: nomaps |
§
Alter the addresses a sector will use. It is loaded at
'<segment:offset>
; the entry point is at '<segment:ip>
'.
'sect' is mostly used in tandem with options 'file' and 'seg', as some loaders/kernels expect a relocated sector at some particular address (e.g. DRMK).
'nosect' will cause the sector to not be loaded at all. In many cases, when a file is being chainloaded, specifying a sector is not necessary.
If this option is not specified, the defaults are '0:0x7c00:0x7c00
'.
If any field is omitted (e.g. '0x2000::'), it defaults to 0.
maps
*maps nomaps
§ In some cases, it is useful to fix BPB values in NTFS/FATxx boot sectors and eventually write them back, but otherwise the boot sector itself is not necessary so as to continue the booting process. 'nomaps' allows such situation: a sector will be loaded, but it won't be mapped into real memory. Any overlap tests (vs. handover or file areas) are not performed, being meaningless in such case.
hand
*hand nohand
§ By default, a handover area is prepared if possible - meaning, if it doesn't overlap with other areas. This is often not necessary though; usually, a chainloaded file or kernel does not care about it anymore, so a user can disable it explicitly with 'nohand'.
hptr
hptr *nohptr
§
In case both, file and sector, are loaded, then 'ds:si
' and 'ds:bp
'
will point to the sector address before chainloading. This option forces
those registers to point to the handover area. This is useful when both the
file and the sector are actually a sector's image and the sector is mapped.
setbpb
setbpb *nosetbpb
§ Microsoft's side of the world is particularly sensitive to certain BPB values. Depending on the system and on the chainloading method (i.e. sector or file), some or all of those fields must match "reality"; but after performing certain operations such as disk cloning, or when using a USB stick in different computers, that's often not the case (i.e. some BPB values might not match the real media).
Matching the "reality" means evaluating:
- "hidden sectors"
- Valid offset of the partition from the beginning of the disk.
- "geometry"
- Valid drive geometry as reported by BIOS.
- "drive"
- Valid drive number.
This option will automatically determine the type of BPB and fix what it can, according to the detected BPB. If the detection of the BPB is not possible, this function does nothing.
filebpb
filebpb *nofilebpb
§ A chainloaded file can simply be an image of a sector. In such case, it could be useful to also fix its BPB values.
save
save → sets: strict=2 *nosave |
§ Fixing BPB values (with 'setbpb') only in memory might not be enough. This option allows writing the corrected values to the sector.
By default, the chain module will not save anything (such as BPB values) to disk, other than options such as 'hide' or 'fixchs', which are directly related to partition entries.
When 'save' is used:
- it can apply to a sector, never to a loaded file;
- the writing is only performed if the values actually changed.
keeppxe
keepexe *nokeepexe
§ [PXELINUX only] When booting over a network using PXELINUX, 'keeppxe' will keep UNDI stacks in memory.
break
break → sets: nofile nomaps nohand *nobreak |
§ [4.05+]
Trigger a service-only run;
the chain module will do everything requested as usual,
but it will not perform the actual chainloading.
The 'break' option disables the handover,
file loading and sector mapping,
as these are pointless in such scenario
(although the file might be re-enabled in some future version,
if writing to actual files becomes possible).
Mainly useful for options such as 'fixchs',
'[un]hide[all]
' and 'setbpb'.
warn
warn *nowarn
§ Wait for a key-press, right before continuing the chainloading. Useful to see warnings emitted by the chain module.
exit
§ [6.04+] Impose the end of the command to be parsed by chain.c32. In some cases (e.g. when using gfxboot) the resulting command line seems to end with some "garbage" that chain.c32 cannot understand, creating unexpected behavior. By adding 'exit' to the end of the command, chain.c32 disregards anything after this option and should work as expected. Usually, this option is not required.
isolinux
isolinux=<myfile> → sets: file=<myfile> nohand nosect isolinux |
§ [ISOLINUX only; 3.83+]
Chainload to 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
ntldr=<myfile> → sets: file=<myfile> seg=0x2000 setbpb nohand |
§ [3.70+] Prepare to load ntldr directly. Add the 'save' option so as to store corrected BPB values.
cmldr
cmldr=<myfile> → sets: file=<myfile> seg=0x2000 setbpb nohand cmldr |
§ [3.85+]
Prepare to load Windows Recovery Console directly.
The in-memory copy of the bootsector is patched
with ' cmdcons\0
'.
Same remarks as in 'ntldr'.
reactos
reactos=<myfile> → sets: file=<myfile> seg=0x0F80 setbpb nohand |
§ [6.04+] Prepare to load ReactOS's freeldr directly. Add the 'save' option so as to store corrected BPB values.
freedos
freedos=<myfile> → sets: file=<myfile> seg=0x60 sect=0x1FE0 setbpb nohand |
§ [3.70+] Prepare to load FreeDOS kernel directly. The 'save' option is likely needed, as these kernels seem to require a proper geometry written back to disk. The sector address is chosen based on where FreeDOS' bootsectors relocate themselves, although it seems the kernel doesn't rely on it.
Consider using the 'hide' option, if the OS has problems with properly assigning the "C:" drive letter.
msdos and pcdos
pcdos=<myfile> msdos=<myfile> → sets: file=<myfile> seg=0x70 sect=0x8000 setbpb nohand |
§ [3.70+] Similarly to 'Freedos', prepare to load MSDOS 2.00 - 6.xx or derivatives. The sector address is chosen arbitrarily. Otherwise, same remarks as in 'Freedos'.
msdos7
msdos7=<myfile> → sets: file=<myfile> seg=0x70::0x200 sect=0x8000 setbpb nohand |
§ Only for MSDOS 7+ versions (98se ~ 7.xx, Me ~ 8.xx). Otherwise, same remarks as in 'Freedos'.
drmk
drmk=<myfile> → sets: file=<myfile> seg=0x70 sect=0x2000:0:0 setbpb nohand |
§ [4.03+] Used for loading of Dell's DOS derivatives only. It requires a boot sector at 0x2000 and overall valid BPB values. As in other DOS-ish cases, likely candidates for use are options 'save' and 'hide'.
grub
grub=<myfile> [grubcfg=<myconfig>] → sets: file=<myfile> seg=0x800::0x200 nohand nosect grub |
§ [4.00+]
Chainload to grub legacy's stage2,
performing additional corrections on the file in memory.
[4.02+] Optionally, an alternative <myconfig>
file can be specified via the 'grubcfg
' option.
grldr
grldr=<myfile> → sets: file=<myfile> nohand nosect grldr |
§ [3.85+] Chainload to GRUB4DOS grldr, performing additional corrections on the file in memory.
bs
bs=<myfile> → sets: file=<myfile> nosect filebpb |
§ Emulate SYSLINUX's native BS option. Load the file and, if possible, also adjust its BPB values. Everything is made in reference to the selected disk/partition.
bss
bss=<myfile> → sets: file=<myfile> nomaps setbpb bss |
§ Emulate SYSLINUX's native BSS option. Load both, the file and the sector, adjust BPB values in the loaded sector, and then copy all possible BPB fields to the loaded file. Everything is made in reference to the selected disk/partition.