352 lines
12 KiB
Plaintext
352 lines
12 KiB
Plaintext
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.
|
|
|