From Syslinux Wiki
Jump to: navigation, search


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:

  1. Parse arguments.
  2. Find drive and/or partition to boot from.
  3. Perform partition-level patching - for example (un)hiding, fixing CHS values, etc.
  4. Load a file to boot from.
  5. Load a sector to boot from, if it doesn't conflict with #4.
  6. Prepare handover area, if it doesn't conflict with #4 and #5.
  7. Prepare registers.
  8. Patch loaded file if necessary.
  9. Patch loaded sector if necessary.
  10. 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.


  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.

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 #


Drives can be specified as either:

select a disk by its signature;
select a disk by its guid (GPT only);
the drive SYSLINUX was booted from. This is the default value, if nothing else is specified.
drive number as seen by BIOS, starting from 0.
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 can be specified as either:

select a partition by a specified guid value (not by guid type !);
select a partition by a specified label (searching by disk order);
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').


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
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



§ [3.70+] Install a tiny stub code that swaps device numbers, if the device we use during chainloading is not 'fd0' nor 'hd0'.



§ In case non-standard hybrid MBR/GPT layout is present, this flag makes the chain module prefer MBR layout over GPT.


  [un]hide[all]        		→ sets: strict=2

§ [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               		→ sets: strict=2

§ 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|strict]' option.


  • '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.



§ [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).



§ [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.


  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.



§ 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.



§ 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'.



§ 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.



§ 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.
Valid drive geometry as reported by BIOS.
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.



§ 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                 		→ sets: strict=2

§ 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.



§ [PXELINUX only] When booting over a network using PXELINUX, 'keeppxe' will keep UNDI stacks in memory.


  break                		→ sets: nofile nomaps nohand

§ [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'.



§ Wait for a key-press, right before continuing the chainloading. Useful to see warnings emitted by the chain module.


§ [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.


  → 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.


  → 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.


  → 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'.


  → 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.


  → 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

  → 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'.


  → 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'.


  → 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=<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.


  → sets: file=<myfile> nohand nosect grldr

§ [3.85+] Chainload to GRUB4DOS grldr, performing additional corrections on the file in memory.


  → 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.


  → 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.

See Also