Output of file : LILO07.TAR contained in archive :
LILO07.ZIP
lilo/README 644 0 0 50616 5310565731 10730 0 ustar root root LILO - Generic Boot Loader for Linux ("LInux LOader") by Werner Almesberger
=============================================================================
This is an ALPHA test release of a new boot loader. Be sure to have some
means to boot your system from a different media if you install LILO on your
hard disk.
NOTE: Most of the documentation has moved into the LaTeX document doc.tex.
This is only a minimal description for those who can't print or pre-
view LaTeX documents.
Features
--------
- does not depend on the file system. (Tested with Minix, EXT FS and MS-DOS
FS.)
- can be used to boot from floppies and from hard disks.
- can replace the master boot record.
- can boot non-Linux systems (MS-DOS, DR DOS, OS/2, ...) and unstripped
kernels.
- supports up to 16 different boot images that can be selected at boot
time. The root disk/partition can be set independently for each
image.
- boot sector, file map and boot images can be all on different disks or
partitions.
Restrictions and known problems
-------------------------------
- SCSI disks are not fully supported yet. (But there's progress.)
- booting non-Linux systems from the second hard disk ("D:") is not yet
supported.
Files
-----
Files contained in lilo.7.tar.Z:
README This file.
INCOMP List of incompatibilities.
Makefile Makefile for everything else.
*.c, *.h LILO map installer source.
*.S LILO boot loader source.
activate.c Simple boot partition setter.
dparam.s Disk parameter dumper source.
disktab Sample disk parameter table.
install.new Replacement of /etc/lilo/install for new-style
configurations.
Files created after make (among others):
boot.b Combined boot sector.
chain.b Chain loader.
lilo LILO installer.
activate Simple boot partition setter.
dparam.com MS-DOS executable of the disk parameter dumper.
!! STOP READING HERE IF YOU CAN USE THE LaTeX VERSION OF THE DOCUMENTATION !!
The LaTeX part is generally more up to date and contains more useful
hints and examples. The following sections have been trimmed to make
it easier to maintain them, e.g. by removing as many version-dependen-
cies as possible.
Installation
------------
LILO 0.7 is compatible with all kernels that don't support presetting
of a swap device. This change has probably occurred at some 0.97 version.
If the swap device preset code is disabled, you can also use 0.96c-pl1
(or newer) kernels.
This section describes one possible installation of LILO. Please read
"Booting basics" in the LaTeX document for the whole story.
Non-SCSI installation:
Step 1: Extract all files from lilo.7.tar.Z, run make to compile and assemble
all parts.
Step 2: Read the "LILO installer" section in this README and be sure to
understand what the command-line options do.
Step 3: Do make install to copy all LILO files to /etc/lilo
Step 4: Install lilo on a floppy disk:
lilo -b /dev/fd0 -i boot.b -v -v -v /your_kernel_image
Step 5: Reboot. If this doesn't work or if you don't want to install LILO on
your hard disk anyway, you can stop here.
Step 6: Get a working bootimage and a rootimage. If you have reason to be
paranoid about your boot sector, mount the rootimage and copy your
current boot sector to a file on it, e.g.
dd if=/dev/hda2 of=/fd/boot_sector bs=512 count=1
Step 7: Create a shell script /etc/lilo/install that installs LILO on your
hard disk, e.g.
# cat >/etc/lilo/install
#!/bin/sh
$ROOT/etc/lilo/lilo
-C /etc/lilo/config $*
^D
# chmod 755 /etc/lilo/install
Then create a configuration file /etc/lilo/config, e.g.
# cat >/etc/lilo/config
install=/etc/lilo/boot.b
...
^D
Step 8: Now, you can check what LILO would do if you
were about to install it on your hard disk:
/etc/lilo/install -v -v -v -t
Step 9: If necessary, install a boot partition switcher. Run /etc/lilo/install
to install LILO on your hard disk. If necessary, mark that partition
"active".
Step 10: Reboot.
SCSI installation:
Like non-SCSI installation, but you have to put the parameters of your
SCSI drive into the file /etc/lilo/disktab.
IMPORTANT: You have to repeat the installation procedure whenever any of the
boot images is replaced or moved (e.g. after the kernel is re-
compiled.)
LILO Installer
--------------
The LILO installer accepts the following command-line options:
-b boot_device
Sets the name of the device that contains the boot sector. If -b is
omitted, the boot sector is read from (and possibly written to) the
device that is currently mounted as root. A BIOS device code can be
specified.
-c
Tries to merge read requests for adjacent sectors into a single read
request. This drastically reduces load time and keeps the map
smaller.
-C config_file
Specifies the new-style configuration file that is used by the map
installer. If -C is omitted, old-style configuration is used.
-d tsecs
Specifies the number of tenths of seconds LILO should wait before
booting the first image. This is useful on systems that immediately
boot from the hard disk after enabling the keyboard. LILO doesn't
wait if -d is omitted.
-D
Selects dump mode. Dumps are used during migration from earlier
versions of LILO. -D also implies -t and disables all other
informational messages.
-f disktab_file
Specifies the name of the disk parameter table. The map installer
looks for /etc/lilo/disktab if -f is omitted.
-i boot_sector
Install the specified file as the new boot sector. If -i is omitted,
the old boot sector is modified. A BIOS device code can be specified.
-l
Generate linear sector addresses instead of sector/head/cylinder
addresses. Linear addresses are translated at run time and do not
depend on disk geometry. This is experimental and is not (yet)
intended for common use.
-m map_file
Specifies the location of the map file. If -m is omitted, a file
/etc/lilo/map is used. A BIOS device code can be specified.
-q
List the currently mapped files.
-r root_dir
Change the root directory to root_dir before doing anything else.
This is typically used when running off a floppy, with the normal
root mounted at some directory.
-s backup_file
Copy the old boot sector to backup_file instead of
/etc/lilo/boot.
-S backup_file
Like -s, but overwrite an old backup copy if it already exists.
-t
Test only. This performs the entire installation procedure except
replacing the map file and writing the modified boot sector. This
can be used in conjunction with the -v option to verify that LILO
will use sane values.
-v
Turns on lots of progress reporting. Repeating -v will turn on more
reporting. (-v -v -v -v -v is the highest verbosity level and
displays all sector mappings before and after compaction.)
There are two ways how image files can be specified: the traditional
approach is to specify them on the command line, typically in
/etc/lilo/install. The new, preferred method uses a configuration file
/etc/lilo/config. There is a section that describes the migration
procedure.
Old-style configuration
-----------------------
If no image files are specified on the command line, the currently mapped
files are listed. Only the options -m, -v and -r can be used in this mode.
If at least one file name is specified, a new map is created for those files
and they are registered in the boot sector. If the root device has been
set in the images, it is copied into the descriptors in the boot sector.
Changing the root device specification in a boot image after the map file
has been built has no effect.
If no root device has been set (or if this is not a traditional boot image),
the current root device is used. The root device can be overridden by
appending it to the image specification, e.g.
lilo foo,/dev/hda1
^ ^
image root
Either numbers or device names can be used.
It is perfectly valid to use different root settings for the same image,
because LILO stores them in the image descriptors and not in the images
themselves. Example:
lin-hd=/linux,/dev/hda2 \
lin-fd=/linux,/dev/fd0
The image files can reside on any media that is accessible at boot time.
There's no need to put them on the root device, although this certainly
doesn't hurt.
LILO uses the first file name (without its path) of each image specification
to identify that image. A different name can be used by prefixing the
specification with =, e.g.
msdos=/etc/lilo/chain.b+/dev/sda1@/dev/sda
--
New-style configuration
-----------------------
For new-style configuration, the file /etc/lilo/install always looks like
this:
$ROOT/etc/lilo/lilo -C /etc/lilo/config $*
The configuration information is stored in the file /etc/lilo/config and
consists of variable assignments. The following syntax rules apply:
- flag variables consist of a single word and are followed by whitespace
or the end of the file.
- string variables consist of the variable name, optional whitespace, an
equal sign, optional whitespace, the value and required whitespace or
the end of the file.
- a non-empty sequence of blanks, tabs, newlines and comments counts as
whitespace.
- variable names are case-insensitive. Values are usually case-sensitive,
but there are a few exceptions. (See below.)
- tabs and newlines are special characters and may not be part of a
variable name or a value. The use of other control characters and
non-ASCII characters is discouraged.
- blanks and equal signs may only be part of a variable name or a value
if they are escaped by a backslash. An equal sign may not be the only
character in a name or value.
- an escaped tab is converted to an escaped blank. An escaped newline is
removed from the input stream.
- comments begin with a number sign and end with the next newline. All
characters (including backslashes) until the newline are ignored.
/etc/lilo/config begins with a possibly empty options section. All options
can also be set from the command line, but storing permanent options in the
configuration file is more convenient. The following options are recognized:
boot=boot_device is equivalent to -b boot_device.
compact is equivalent to -c.
delay=tsecs is equivalent to -d tsecs.
linear is equivalent to -l.
install=boot_sector is equivalent to -i boot_sector.
disktab=disktabfile is equivalent to -f disktab_file}.
map=map_file is equivalent to -m map_file}.
verbose=level is equivalent to level repetitions of -v. If -v is
specified on the command line, level is increased.
backup=backup_file is equivalent to -s backup_file.
force-backup=backup_file is equivalent to -S backup_file.
backup=backup_file is ignored if -S backup_file appears in the same
configuration file.
If the option -q is specified on the command line, the currently mapped
files are listed. Otherwise, a new map is created for the images described
in /etc/lilo/config and they are registered in the boot sector. Each image
description begins with a special variable and is followed by optional
variables. The following variables can be used for all image descriptions
that describe a Linux kernel:
root=root_device specifies the device that should be mounted as root.
If this variable is omitted, the root device setting that is contained
in the boot image is used. It can be changed with the rdev aka setroot
program.
vga=mode specifies the VGA text mode that should be selected when
booting. The following values are recognized (case is ignored):
normal select normal 80x25 text mode.
extended select 80x50 text mode.
ask stop and ask for user input (at boot time). A system where this
option is being used is unable to automatically reboot.
use the corresponding text mode. A list of available
modes can be obtained by booting with vga=ask and pressing [Enter].
If this variable is omitted, the VGA mode setting that is contained in
the boot image is used. Some versions of setroot support manipulation
of the VGA text mode setting in the boot image.
ramdisk=size specifies the size of the optional RAM disk. A value of zero
indicates that no RAM disk should be created. If this variable is omitted,
the RAM disk size that is configured into the boot image is used.
The variables VGA and RAMDISK are only available when running a kernel that
supports them, e.g. 0.98pl6 and later. If one of ROOT, VGA or RAMDISK is
omitted in the configuration file and the corresponding value in the boot
image is changed, LILO will use the new value.
It is perfectly valid to use different root settings for the same image,
because LILO stores them in the image descriptors and not in the images
themselves. Example:
image = /linux
label = lin-hd
root = /dev/hda2
image = /linux
label = lin-fd
root = /dev/fd0
The image files can reside on any media that is accessible at boot time.
There's no need to put them on the root device, although this certainly
doesn't hurt.
LILO uses the first file name (without its path) of each image specification
to identify that image. A different name can be used by setting the variable
LABEL (see the example above).
Boot image types
----------------
LILO can boot the following types of images:
- "classic" boot images from a file
- "classic" boot images from a device
- unstripped kernel executables
- the boot sector of some other operating system
The image type is determined either by the syntax that is used for the image
specification (old-style configuration) or by the name of the initial
variable of the configuration section (new-style configuration).
Booting "classic" boot images from a file
-----------------------------------------
If defined, the root device definition is taken from the boot image.
The image is specified as follows:
OLD-STYLE
file_name [ :BIOS_code ]
I.e. /linux
NEW-STYLE
image=name
The following additional variables are recognized: root, vga, ramdisk and
label.
Example:
image = /linux
Booting "classic" boot images from a device
-------------------------------------------
The root device setting in the image is ignored. The range of sectors
that should be mapped, has to be specified. Either a range (start-end)
or a start and a distance (start+number) have to be specified. start
and end ae zero-based. If only the start if specified, only that sector
is mapped.
OLD-STYLE
device_name [ :BIOS_code] #start [ -end | +number ]
I.e. /dev/fd0#1+512
NEW-STYLE
image=name
The following additional variables are recognized: root, vga, ramdisk,
label and range.
Example:
image = /dev/fd0
range = 1+512
Booting unstripped kernel executables
-------------------------------------
Unstripped kernel executables contain no root device information.
The setup code of the kernel has also to be added to the kernel. First,
it has to be copied to a suitable place and its header has to be removed,
e.g.
(dd of=/dev/null bs=32 count=1; dd)
>/etc/lilo/setup.b
OLD-STYLE
The image specification looks like this:
setup_name [ :BIOS_code ] +kernel_name [ :BIOS_code ]
I.e. /etc/lilo/setup.b+/usr/src/linux/tools/system
NEW-STYLE
unstripped=name
The following additional variables are recognized: root, vga, ramdisk,
label, boot and setup.
boot=boot_sector specifies the floppy boot sector that should be loaded.
It is used to provide defaults for settings like the root device, etc.
The boot sector file can be created like the setup file. (See above.)
The recommended name for the floppy boot sector file is
/etc/lilo/bsect.b. If this variable is omitted, a zero-filled sector is
loaded instead.
setup=setup_file specifies the setup file that should be loaded. This
variable is required.
Example:
unstripped = /usr/src/linux/tools/system
setup = /etc/lilo/setup.b
Booting a foreign operating system
----------------------------------
LILO can even boot other operating systems, e.g. MS-DOS. This feature
is new and may not yet work totally reliably. (Reported to work with
PC-DOS 4.0, MS-DOS 5.0 and DR-DOS 6.0.) To boot an other operating
system, the name of a loader program, the device that contains the boot
sector and the device that contains the master boot record have to be
specified.
The boot sector is merged with the partition table and stored in the map
file.
Currently, only the loader chain.b exists.
OLD_STYLE
loader+boot_dev [ :BIOS_code ] @ [ part_dev ]
I.e. /etc/lilo/chain.b+/dev/hda2@/dev/hda
NEW-STYLE
other=name
The following additional variables are recognized: label, loader, table.
loader=chain_loader specifies the chain loader that should be used. If
this variable is omitted, /etc/lilo/chain.b is used.
table=device specifies the device that contains the partition table.
LILO does not pass partition information to the booted operating
system if this variable is omitted. (Some operating systems have other
means to determine from which partition they has been booted.)
Example:
other = /dev/hda2
table = /dev/hda
LILO may create some device special files in your /tmp directory that are
not removed if an error occurs. They are named /tmp/dev..
Disk parameter table
--------------------
For floppies and IDE disks (or MFM, RLL, ESDI, etc.), LILO can obtain the
disk geometry information from the kernel. Unfortunately, this is not
possible with SCSI disks. The file /etc/lilo/disktab is used to describe
such disks. For each device (/dev/sda -> 0x800, /dev/sda1 -> 0x801, etc.),
the BIOS code, the disk geometry and the offset of the first sector of
that partition (measured in sectors) have to be specified, e.g.
# /etc/lilo/disktab - LILO disk parameter table
#
# This table contains disk parameters for SCSI disks and non-
# standard parameters of IDE disks. Parameters in disktab
# _always_ override auto-detected disk parameters.
# Dev. BIOS Secs/ Heads/ Cylin- Part.
# num. code track cylin. ders offset
0x800 0x80 32 64 631 0 # /dev/sda
0x801 0x80 32 64 631 32 # /dev/sda1
0x802 0x80 32 64 631 204800 # /dev/sda2
(Those parameters are just a random example from my system. However, many
SCSI controllers re-map the drives to 32 sectors and 64 heads. The number
of cylinders does not have to be exact, but it shouldn't be lower than the
number of effectively available cylinders.)
Note that the device number and the BIOS code have to be specified as
hexadecimal numbers with the 0x prefix.
The disk geometry parameters can be obtained by booting MS-DOS and running
the program DPARAM.COM with the hexadecimal BIOS code of the drive as its
argument, e.g. dparam 0x80 for the first hard disk. It displays the number
of sectors per track, the number of heads per cylinder and the number of
cylinders.
The partition offset is printed by the Linux kernel when the SCSI disk is
detected at boot time. Example:
sd0 :
part 1 start 32 size 204768 end 204799
part 2 start 204800 size 1087488 end 1292287
The first partition has an offset of 32 sectors, the second has an
offset of 204800 sectors.
Because many SCSI controllers don't support more than 1 GB when using the
BIOS interface, LILO can't access files that are located beyond the 1 GB
limit of large SCSI disks and reports errors in these cases.
Migration from old-style to new-style configuration
---------------------------------------------------
An existing pre-LILO 0.7 configuration can easily be replaced by a new-style
configuration. The command-line option -D dumps the current settings on
standard output. This is a typical migration procedure:
- upgrade to LILO 0.7
- cd to /etc/lilo
- run ./install -D >config
- add new variables VIDEO and RAMDISK to /etc/lilo/config if you want to.
- run ./lilo -C config -D | diff -c config -
to verify the correctness of the dump. LILO may change the order of
variables and the placement of whitespace in the second dump. It also
removes comments.
- rename /etc/lilo/install to /etc/lilo/install.old and copy install.new
from your LILO source directory to /etc/lilo/install
- add commands to create boot and setup files to the new /etc/lilo/install
if you're booting unstripped kernels.
- run /etc/lilo/install
Bugs and such
-------------
Please send all bug reports to [email protected]
lilo/INCOMPAT 644 0 0 4724 5310504407 11155 0 ustar root root Incompatibilities between LILO 0.7 and earlier versions
=======================================================
There are a number of incompatibilities between LILO 0.7 and earlier
versions that cause working /etc/lilo/install scripts to fail or that
change earlier behaviour without warning.
Root device presetting
----------------------
The way how the root device is preset differs from LILO 0.7 and
earlier versions if using /etc/lilo/config. If the boot images are
listed on the command line, LILO 0.7 emulates the old behaviour.
Old behaviour:
- if the root device was specified after the image descriptor
(e.g. foo=/bar,/dev/hda1), that device was used.
- if a root device was set in the boot image and no device was
specified at the command line, the setting from the boot
image was used. Later changes of the settings (e.g. with rdev
aka setroot) had no effect.
- if no root device was set in the boot image, LILO used the
current root partition instead. Again, changing the setting
later had no effect.
New behaviour:
- if the ROOT variable is set, that value is used and the
setting in the boot image is ignored.
- otherwise, the value found in the boot image at boot time is
used. This means that changing the root device setting after
map creation has the desired effect.
Swap device settings
--------------------
Presetting the swap device (e.g. /linux,/dev/root,/dev/swap) is no
longer supported. Linus has already stopped providing that feature
in recent kernels.
Kernels that expect swap device settings in the boot sector may no
longer work. I'm not sure when presettable swap devices were removed,
but generally 0.96 and early 0.97 kernels may be considered
incompatible.
The memory location where the swap device preset value used to be
stored has been occupied by the VGA mode value in 0.98pl6 and
possibly also in SLS versions of 0.98pl5.
Workaround: Create a /etc/lilo/config file and set the VGA variable
to zero to disable using a swap device at boot time.
BIOS code overrides
-------------------
Appending BIOS codes to file names (e.g. /foo/bar:0x80) is no longer
supported. /etc/lilo/disktab can be used for most purposes where
BIOS code overrides might have been useful.
Command-line arguments of the map installer
-------------------------------------------
Older versions of the map installer accepted multiple ocurrences of
the same flag. LILO 0.7 and later versions are only guaranteed to
accept repetition of -v.
lilo/CHANGES 644 0 0 13463 5310560724 11037 0 ustar root root Changes from version 6 to 7
---------------------------
Boot sector
-----------
- supports video mode and RAM disk size settings.
- loads original boot sector to make possible additional settings
available.
- now uses defaults from the boot sector even if the boot sector
has been changed after map creation.
Map installer
-------------
- new configuration based on /etc/lilo/config
- can get SCSI geometry without using /etc/lilo/disktab (doesn't
work with 0.98pl6)
- removed support for BIOS codes (name:code)
- removed support for setting the swap device.
- new command-line options: -q, -C and -D
Documentation
-------------
- updated to cover new-style configuration
- extended the plain-ASCII README
Changes from version 5 to 6
---------------------------
Boot sector
-----------
- added command-line argument passing.
- now clears BSS of traditional images too.
- chain.b is now more careful about register values when invoking
the boot sector of the other OS.
- added an interface for externally provided command lines.
- added experimental recognition of linear addresses.
Map installer
-------------
- fixed opening the disktab file. (Using -f didn't work.)
- fixed use of BIOS codes for the map file: the tilde is now appended
before the BIOS code.
- added a chdir("/") when using -r
- added more sanity checks.
- added generation of linear addresses.
Documentation
-------------
- removed all references to swap device settings in the kernel because
recent kernels don't support that any longer.
- added a troubleshooting section.
- several minor fixes and improvements.
Changes from version 4 to 5
---------------------------
Map installer
-------------
- added automatic boot sector backup.
- fixed variable block size detection. (Didn't work with the 0.97-pl2
kernel.)
- added the chroot (-r) option.
- made the partition table part of a foreign OS boot descriptor
optional.
Documentation and installation
------------------------------
- most of README has moved into doc.tex (LaTeX)
- added a utility to activate a partition.
- make install now reminds the user to update the map.
- dd is now used in a more efficient way in the Makefile.
(Fewer subshells, etc.)
Changes from version 3 to 4
---------------------------
Boot sector
-----------
- added a configurable delay.
- added a diagnostic title message.
Map installer
-------------
- fixed all known include file conflicts.
- added support for variable block sizes. (Not used yet.)
- added some more sanity checks.
- added a tool to determine SCSI disk parameters.
Documentation and installation
------------------------------
- extended coverage of SCSI disks.
- make install now backs up chain.b and boot.b of any older LILO
installation. (To say: your system remains bootable even if you
forget to run /etc/lilo/install after the update or if this fails
for some reason.)
- moved the changes section from README into CHANGES.
- a set of pre-compiled executables of lilo, boot.b, chain.b and
dparam.com is available too.
Changes from version 2 to 3
---------------------------
Boot sector
-----------
- can initialize BSS of unstripped kernels.
- also accepts [Tab] to show the list of known images.
Map installer
-------------
- fixed parsing of the root device specification.
- fixed setting of the root device when the boot image doesn't
define it.
- reduced the number of installable images from 19 to 16. (Because the
descriptors have grown.)
Documentation
-------------
- added a booting basics section.
- many minor changes.
Changes from version 1 to 2
---------------------------
Boot sector
-----------
- added command-line editing.
- added debugging support (-DDEBUG).
- added support for compacted maps.
- some cosmetic changes.
Map installer
-------------
- major rewrite.
- files that contain "holes" are now handled properly.
- added map compaction.
- devices are now created on the fly only if they can't be found in /dev.
- improved sanity checking.
- can now boot other operating systems.
- can now boot unstripped kernel executables.
- added support for a disk parameter file.
- reduced the number of installable images from 21 to 19.
- changed the command-line syntax.
- root and boot can now be specified on the command line.
Documentation
-------------
- many changes, including correction of some minor errors.
Changes from version 0 to 1
---------------------------
Boot sector
-----------
- tested as master boot record.
- improved the boot prompt invocation method.
- increased the number of installable images to 21.
- added a help facility.
- improved read error handling and error reporting in the boot loader.
- added a second stage boot loader.
Map installer
-------------
- fixed some minor bugs in the map installer. Removed all compiler
warnings.
- added labeling of images.
- added version checking for the boot sector.
- replaced option -r by -m. -r will be available for a while for
compatibility.
- added booting from device files (that have boot images written on them).
- BIOS device codes can now be specified for boot image files too.
- added concatenation of images. (This is a test feature that will be
changed in the future.)
Documentation
-------------
- some minor documentation errors have been corrected.
- the README now warns that the map has to be rebuilt after the images are
replaced or moved.
- added a files, a hints and an examples section.
lilo/doc/doc.tex 644 0 0 203440 5310565726 12123 0 ustar root root \documentstyle{article}
\parindent=0pt
\parskip=4pt
\hyphenation{hexa-decimal}
% Okay, what follows is more TeX than LaTeX ...
\def\hditem#1{\hbox to 1.2in{#1\hfil}}
\def\boottwo#1{$$
\bf
\begin{tabular}{|ll|}
\hline
\hditem{\rm Master Boot Record} & \hditem{\rm Operating system} \\
\hline
#1 \\
\hline
\end{tabular}
$$}
\def\bootthree#1{$$
\bf
\begin{tabular}{|lll|}
\hline
\hditem{\rm Master Boot Record} & \hditem{\rm Boot sector} &
\hditem{\rm Operating system} \\
\hline
#1 \\
\hline
\end{tabular}
$$}
\def\bootfour#1{$$
\bf
\begin{tabular}{|llll|}
\hline
\hditem{\rm Master Boot Record} & \hbox to 1.1in{\rm Boot sector\hfil} &
\hditem{\rm Operating systems} & \hbox to 0.4in{\hfil} \\
\hline
#1 \\
\hline
\end{tabular}
$$}
\def\sep{\rightarrowfill &}
\def\empty{&}
\def\branch{\hfill$\longrightarrow$ &}
\def\cont{---\,$\cdots$}
\def\key#1{$[$#1$]$}
\def\LILO{LILO}
\begin{document}
\title{\LILO \\
Generic boot loader for Linux \\
Version 0.7}
\author{Werner Almesberger \\
{\tt [email protected] }}
\maketitle
\setcounter{tocdepth}{1}
\tableofcontents
~\\
\LILO\ is a versatile boot loader for Linux. It does not depend on a specific
file system, can boot Linux boot images and unstripped Linux kernels from
floppy disks and from hard disks and can even boot other operating
systems\footnote{MS-DOS, DR DOS, OS/2, 386BSD, SCO UNIX, $\ldots$}.
One of up to sixteen different boot images can be selected at boot time.
The root
device can be set independently for each of them. \LILO\ can even be
used as the master boot record.
This document introduces the basics of disk organization and booting,
continues with an overview of common boot techniques and finally describes
installation and use of \LILO\ in greater detail. The troubleshooting
section at the end describes diagnostic messages and contains suggestions
for most problems that have been observed in the past.
Please read the sections about installation and configuration if you're
already using an older version of \LILO. This distribution is accompanied
by a file named {\tt INCOMPAT} that describes further incompatibilities
to older versions.
\section{Disk organization}
When designing a boot concept, it is important to understand all the
subtleties of how MS-DOS organizes disks. The most simple case are
floppy disks. They consist of a boot sector, some administrative
data (FAT or super block, etc.) and the data area. Because that
administrative data is irrelevant as far as booting is concerned, it is
regarded as part of the data area for simplicity.
$$
\begin{tabular}{|c|c|}
\hline
Boot sector & \hbox to 1.5in{\hfil} \\
\cline{1-1}
\multicolumn{2}{|c|}{} \\
\multicolumn{2}{|c|}{Data area} \\
\multicolumn{2}{|c|}{} \\
\hline
\end{tabular}
$$
The entire disk appears as one device (i.e. {\tt /dev/fd0}) on Linux.
The MS-DOS boot sector has the following structure:
$$
\begin{tabular}{r|c|}
\cline{2-2}
\tt 0x000 & Jump to the program code\\
\cline{2-2}
\tt 0x003 & \\
& Disk parameters \\
& \\
\cline{2-2}
\tt 0x02C/0x03E & \\
& Program code \\
& \\
& \\
\cline{2-2}
\tt 0x1FE & Magic number (0xAA55)\\
\cline{2-2}
\end{tabular}
$$
\LILO\ uses a similar boot sector, but it does not contain the disk
parameters part. This is no problem for Minix or EXT file systems, because
they don't look at the boot sector, but putting a \LILO\ boot sector on an
MS-DOS file system would make it inaccessible for MS-DOS.
Hard disks are organized in a more complex way than floppy disks. They
contain several data areas called partitions. Up to four so-called
primary partitions can exist on an MS-DOS hard disk. If more partitions
are needed, a primary partition is used as an extended partition that
contains several logical partitions.
The first sector of each hard disk contains a partition table and an
extended partition and {\bf each} logical partition contains a partition
table too.\footnote{Is it legal to have more than one extended partition ?
Linux appears to be able to handle this, but is DOS ?}
$$
\begin{tabular}{|l|l|l|}
\hline
\multicolumn{3}{|l|}{Partition table\hbox to 2in{\hfil\tt /dev/hda~}} \\
\cline{2-3}
& \multicolumn{2}{l|}{Partition 1\hfill {\tt /dev/hda1}} \\
& \multicolumn{2}{l|}{} \\
\cline{2-3}
& \multicolumn{2}{l|}{Partition 2\hfill {\tt /dev/hda2}} \\
& \multicolumn{2}{l|}{} \\
\hline
\end{tabular}
$$
The entire disk can be accessed as {\tt /dev/hda}, {\tt /dev/hdb},
{\tt /dev/sda}, etc. The primary partitions are {\tt /dev/hda1 $\ldots$
/dev/hda4}.
$$
\begin{tabular}{|l|l|l|}
\hline
\multicolumn{3}{|l|}{Partition table\hbox to 2in{\hfil\tt /dev/hda~}} \\
\cline{2-3}
& \multicolumn{2}{l|}{Partition 1\hfill {\tt /dev/hda1}} \\
& \multicolumn{2}{l|}{} \\
\cline{2-3}
& \multicolumn{2}{l|}{Partition 2\hfill {\tt /dev/hda2}} \\
& \multicolumn{2}{l|}{} \\
\cline{2-3}
& \multicolumn{2}{l|}{Extended partition\hfill {\tt /dev/hda3}} \\
\cline{3-3}
& & Extended partition table \\
\cline{3-3}
& & Partition 3\hfill {\tt /dev/hda5}\\
& & \\
\cline{3-3}
& & Extended partition table \\
\cline{3-3}
& & Partition 4\hfill {\tt /dev/hda6}\\
& & \\
\hline
\end{tabular}
$$
This hard disk has two primary partitions and an extended partition
that contains two logical partitions. They are accessed as
{\tt /dev/hda5 $\ldots$}
Note that the partition tables of logical partitions are not accessible
as the first blocks of some devices, while the main partition table,
all boot sectors and the partition tables of extended partitions are.
Partition tables are stored in partition boot sectors. Only the partition
boot sector of the entire disk is usually used as a boot sector. It is
also frequently called the master boot record (MBR).
$$
\begin{tabular}{r|c|}
\cline{2-2}
\tt 0x000 & \\
& Program code \\
& \\
& \\
\cline{2-2}
\tt 0x1BE & Partition table \\
& \\
\cline{2-2}
\tt 0x1FE & Magic number (0xAA55) \\
\cline{2-2}
\end{tabular}
$$
The \LILO\ boot sector is designed to be usable as a partition boot sector.
Therefore, the \LILO\ boot sector can be stored at the following locations:
\begin{itemize}
\item boot sector of a Linux floppy disk. ({\tt /dev/fd0}, $\ldots$)
\item MBR of the first hard disk. ({\tt /dev/hda}, $\ldots$)
\item boot sector of a primary Linux file system partition on the first hard
disk. ({\tt /dev/hda1}, $\ldots$)
\item partition boot sector of an extended partition on the first hard disk.
({\tt /dev/hda1}, $\ldots$)\footnote{Most FDISK-type programs don't
believe in booting from an extended partition and refuse to
activate it. \LILO\ is accompanied by a simple program
({\sf activate}) that doesn't have this restriction.}
\end{itemize}
It {\bf can't} be stored at any of the following locations:
\begin{itemize}
\item boot sector of a non-Linux floppy disk or primary partition.
\item a Linux swap partition.
\item boot sector of a logical partition in an extended partition.
\item on the second hard disk. (Unless for backup installations,
if the current first disk will be removed or disabled, or if some
other boot loader that is capable of loading boot sectors from
other drives is being used.)
\end{itemize}
\section{Booting basics}
When booting from a floppy disk, the first sector of the disk, the so-called
boot sector, is loaded. That boot sector contains a small program that loads
the respective operating system. MS-DOS boot sectors also contain
a data area, where the disk parameters (number of sectors, number of
heads, etc.) are stored.
When booting from a hard disk, the very first sector of that disk, the
so-called master boot record (MBR) is loaded. This sector contains a
loader program and the partition table of the disk. The loader program
usually loads the boot sector, as if the system was booting from a floppy.
Note that there is no functional difference between the MBR and the boot
sector other than that the MBR contains the partition information but
doesn't contain any (MS-DOS) disk parameter information.
The first 446 (0x1BE) bytes of the MBR are used by the loader program.
They are followed by the partition table, with a length of 64 (0x40)
bytes. The last two bytes contain a magic number that is sometimes used to
verify that a given sector really is a boot sector.
There is a large number of possible boot configurations. The most common
ones are described in the following sections.
\subsection{MS-DOS alone}
\bootthree{DOS-MBR \sep MS-DOS \sep COMMAND.COM}
This is what usually happens when MS-DOS boots from a hard disk: the DOS-MBR
determines the active partition and loads the MS-DOS boot sector. This boot
sector loads MS-DOS and finally passes control to {\tt COMMAND.COM}. (This is
greatly simplified.)
\subsection{BOOTLIN}
\bootfour{DOS-MBR \sep MS-DOS \sep COMMAND.COM \empty \\
\empty \branch BOOTLIN \sep Linux}
A typical BOOTLIN setup: everything happens like when booting MS-DOS, but in
{\tt CONFIG.SYS},
BOOTLIN is invoked. This approach has the pleasant property that no boot
sectors have to be altered.
Installation:
\begin{itemize}
\item boot Linux.
\item copy a bootable kernel image to your MS-DOS partition.\footnote{%
With Mtools or the MS-DOS FS.}
\item install {\tt BOOT.SYS} and {\tt BOOTLIN.SYS} on your MS-DOS
partition and add them to your {\tt CONFIG.SYS}.
(The READMEs describe how this is done.)
\item reboot.
\end{itemize}
Deinstallation:
\begin{itemize}
\item remove {\tt BOOT.SYS} and {\tt BOOTLIN.SYS} from your {\tt CONFIG.SYS}.
\end{itemize}
\subsection{\LILO\ started by DOS-MBR}
\bootthree{DOS-MBR \sep LILO \sep Linux \\
\branch {\rm other OS} \empty}
This is a ``safe'' \LILO\ setup: \LILO\ is booted by the DOS-MBR. No other boot
sectors have to be touched. If the other OS (or one of them, if there are
several other operating systems being used) should be booted, the other
partition has to be marked ``active'' with {\sf (e)fdisk} or {\sf activate}.
Installation:
\begin{itemize}
\item install \LILO\ with its boot sector on the Linux partition.
\item use {\sf (e)fdisk} or {\sf activate} to make that partition active.
\item reboot.
\end{itemize}
Deinstallation:
\begin{itemize}
\item make a different partition active.
\item install whatever should replace \LILO\ or Linux.
\end{itemize}
\subsection{Several alternate branches}
\bootfour{DOS-MBR \sep MS-DOS \sep COMMAND.COM \empty \\
\empty \branch BOOTLIN \sep Linux \\
\branch LILO \sep Linux \empty \\
\empty \branch MS-DOS \cont \empty}
An extended form of the above setup: the MBR is not changed and both branches
can either boot Linux or MS-DOS. (\LILO\ could also boot any other
operating system.)
\subsection{\LILO\ started by {\sf BOOTACTV}}
\bootthree{BOOTACTV \sep LILO \sep Linux \\
\branch {\rm other OS} \empty}
Here, the MBR is replaced by {\sf BOOTACTV} (or any other interactive boot
partition selector) and the choice between Linux and the
other operating system(s) can be made at boot time. This approach should be
used if \LILO\ fails to boot the other operating system(s).\footnote{%
And the author would like to be notified if booting the other operating
system(s) doesn't work with \LILO, but if it works with an other boot partition
selector.}
Installation:
\begin{itemize}
\item boot Linux.
\item make a backup copy of your MBR on a floppy disk, e.g. \\
\verb"dd if=/dev/hda of=/fd/MBR bs=512 count=1"
\item install \LILO\ with the boot sector on the Linux partition.
\item install {\sf BOOTACTV} as the MBR, e.g. \\
\verb"dd if=bootactv.bin of=/dev/hda bs=446 count=1"
\item reboot.
\end{itemize}
Deinstallation:
\begin{itemize}
\item boot Linux.
\item restore the old MBR, e.g. \\
\verb"dd if=/MBR of=/dev/hda bs=446 count=1"
\end{itemize}
If replacing the MBR appears undesirable and if a second Linux partition
exists (e.g. {\tt /usr}, {\bf not} a swap partition), {\sf BOOTACTV} can
be merged with
the partition table and stored as the ``boot sector'' of that partition.
Then, the partition can be marked active to be booted by the DOS-MBR.
Example:
\begin{verbatim}
# dd if=/dev/hda of=/dev/hda3 bs=512 count=1
# dd if=bootactv.bin of=/dev/hda3 bs=446 count=1
\end{verbatim}
Warning: whenever the disk is re-partitioned, the merged boot sector on that
``spare'' Linux partition has to be updated too.
\subsection{{\sf Shoelace} started by {\sf BOOTACTV}}
\bootthree{BOOTACTV \sep Shoelace \sep Linux \\
\branch {\rm other OS} \empty}
{\sf Shoelace}, \LILO's predecessor, can be started by {\sf BOOTACTV} as well,
of course.
The same indirection as outlined above is possible. There are probably many
other ways to install {\sf Shoelace}.\footnote{{\sf Shoelace} is considered
obsolete and should not be used for new installations.}
\subsection{\LILO\ alone}
\boottwo{LILO \sep Linux \\
\branch {\rm other OS}}
\LILO\ can also take over the entire boot procedure. If installed as the MBR,
\LILO\ is responsible for either booting Linux or any other OS. This approach
has the disadvantage, that the old MBR is overwritten and has to be restored
(either from a backup copy, with \verb"FDISK /MBR" on MS-DOS 5.0 or by
overwriting
it with {\sf BOOTACTV}) if Linux should ever be removed from the system.
You should verify that \LILO\ is able to boot your other operating system(s)
before relying on this method.
Installation:
\begin{itemize}
\item boot Linux.
\item make a backup copy of your MBR on a floppy disk, e.g. \\
\verb"dd if=/dev/hda of=/fd/MBR bs=512 count=1"
\item install \LILO\ with its boot sector as the MBR.
\item reboot.
\end{itemize}
Deinstallation:
\begin{itemize}
\item boot Linux.
\item restore the old MBR, e.g. \\
\verb"dd if=/fd/MBR of=/dev/hda bs=446 count=1"
\end{itemize}
If you've installed \LILO\ to be the master boot record, you have to
explicitly specify the boot sector ({\tt -b $\ldots$}) when updating the map.
Otherwise, it
will try to use the boot sector of your current root partition, which
may even work, but will leave your system unbootable.
\subsection{Names}
The following names have been used to describe boot sectors or parts of
operating systems:
\begin{description}
\item[\bf DOS-MBR] is the original MS-DOS MBR. It scans the partition
table for a partition that is marked ``active'' and loads the boot
sector of that partition. Programs like MS-DOS' {\sf FDISK}, Owen Le Blanc's
{\sf fdisk} for Linux (on MCC-interim or 0.97 rootimage, or named
{\sf efdisk} on
the 0.96 rootimage) or {\sf activate} (accompanies \LILO)
can change the active marker in the partition table.
\item[\bf MS-DOS] denotes the MS-DOS boot sector that loads the other parts
of the system ({\tt IO.SYS}, etc.).
\item[\bf COMMAND.COM] is the standard command interpreter of MS-DOS.
\item[\bf BOOTLIN] is a program that loads a Linux boot image from an
MS-DOS partition into memory and executes it. It is usually invoked
from {\tt CONFIG.SYS} and used in conjunction with a {\tt CONFIG.SYS}
configuration switcher, like BOOT.SYS.\footnote{BOOTLIN is
available for anonymous FTP from \\
{\tt tsx-11.mit.edu:/pub/linux/INSTALL/dos\_utils/bootlin4.zip} or \\
{\tt nic.funet.fi:/pub/OS/Linux/tools/bootlin.zip}, BOOT.SYS is
available for anonymous FTP from
{\tt nic.funet.fi:/pub/OS/Linux/tools/boot142.zip} or \\
{\tt wuarchive.wustl.edu:/mirrors/msdos/sysutl/boot142.zip}.}
\item[\bf LILO] can either load a Linux kernel or the boot sector of any
other operating system. It has a first stage boot sector that
loads the remaining parts of \LILO\ from various locations.
\item[\bf BOOTACTV] permits interactive selection of the partition from
which the boot sector should be read. If no key is pressed within a
given interval, the partition marked active is booted. {\sf BOOTACTV} is
included in the {\sf pfdisk} package. There are also several similar
programs, like PBOOT and OS-BS.\footnote{{\sf pfdisk} is available for
anonymous FTP from \\
{\tt tsx-11.mit.edu:/pub/linux/attic/sources/sbin/pfdisk.tar.Z} or \\
{\tt nic.funet.fi:/pub/OS/Linux/tools/pfdisk.tar.Z}. PBOOT can be
found at the same sites in \\
{\tt tsx-11.mit.edu:/pub/linux/INSTALL/dos\_utils/pboot.zip} \\
{\tt nic.funet.fi:/pub/OS/Linux/tools/pboot.zip}.}
\item[\bf Shoelace] is a different boot loader for Linux. It is
functionally similar to \LILO, but it can only use the Minix file system.
Because of that, {\sf Shoelace} is obsolete and should not be used for
new installations.
\end{description}
\section{Choosing the ``right'' boot concept}
Although \LILO\ can be installed in many different ways, the choice is
usually limited by the present setup and therefore there is
typically only a small number of configurations which fit naturally
into an existing system.
For each concept, example {\tt /etc/lilo/config} and {\tt /etc/lilo/install}
files are provided.
{\tt /etc/lilo/install} is a shell script that actually performs the
installation (and updates) of the boot sector and the map file. It
has to be created by the user when installing \LILO\ and has to be
run whenever \LILO\ or the kernel is changed. (See section \ref{install}.)
{\tt /etc/lilo/config} is the new, preferred configuration method. It
contains the same information as {\tt /etc/lilo/install} in a more
readable way. When using {\tt /etc/lilo/config}, a standard
{\tt /etc/lilo/install} can be used, see section \ref{new-config}.
Each of the {\tt /etc/lilo/install} files installs the following boot images:
\begin{itemize}
\item a traditional Linux boot image ({\tt /linux}).
\item an alternate traditional Linux boot image ({\tt /linux.backup}).
\item a chain loader to boot MS-DOS.
\end{itemize}
In all examples, the names of the AT-type hard disk devices
({\tt /dev/hda$\ldots$}) are used. Everything applies to SCSI disks
({\tt /dev/sda$\ldots$}) too.
\subsection{One disk, Linux on a primary partition}
If at least one primary partition of the first hard disk is used as a
Linux file system ({\tt /}, {\tt /usr}, etc. but {\bf not} as a swap
partition), the \LILO\ boot sector should be stored on that partition
and it should be booted by the original master boot record or by a
program like {\sf BOOTACTV}.
$$
\begin{tabular}{r|c|c|}
\cline{2-3}
& \multicolumn{2}{|l|}{MBR\hbox to 1.3in{\hfill\tt /dev/hda~}} \\
\cline{3-3}
& & MS-DOS\hfill\tt /dev/hda1 \\
\cline{3-3}
$\rightarrow$ & & Linux {\tt /}\hfill\tt /dev/hda2 \\
\cline{2-3}
\end{tabular}
$$
A typical {\tt /etc/lilo/config} file would look like this:
\begin{verbatim}
compact
install = /etc/lilo/boot.b
image = /linux
image = /linux.backup
other = /dev/hda1
table = /dev/hda
label = msdos
\end{verbatim}
or, old-style ({\tt /etc/lilo/install}):
\begin{verbatim}
$ROOT/etc/lilo/lilo -c -i /etc/lilo/boot.b $* \
/linux \
/linux.backup \
msdos=/etc/lilo/chain.b+/dev/hda1@/dev/hda
\end{verbatim}
\subsection{One disk, Linux on an extended partition}
If no primary partition is available for Linux, but at least one logical
partition of an extended partition on the first hard disk contains a
Linux file system, the \LILO\ boot sector should be stored in the partition
sector of the extended partition and it should be booted by the original
master boot record or by a program like {\sf BOOTACTV}.
$$
\begin{tabular}{r|c|c|c|}
\cline{2-4}
& \multicolumn{3}{|l|}{MBR\hbox to 1.3in{\hfill\tt /dev/hda~}} \\
\cline{3-4}
& & \multicolumn{2}{|l|}{MS-DOS\hfill\tt /dev/hda1} \\
\cline{3-4}
$\rightarrow$ & & \multicolumn{2}{|l|}{Extended\hfill\tt /dev/hda2} \\
\cline{4-4}
& & & Linux\hfill\tt /dev/hda5 \\
\cline{4-4}
& & & $\ldots$\hfill\tt /dev/hda6 \\
\cline{2-4}
\end{tabular}
$$
A typical {\tt /etc/lilo/config} file for this configuration would look
like this:
\begin{verbatim}
boot = /dev/hda2
compact
install = /etc/lilo/boot.b
image = /linux
image = /linux.backup
other = /dev/hda1
table = /dev/hda
label = msdos
\end{verbatim}
or, old-style ({\tt /etc/lilo/install}):
\begin{verbatim}
$ROOT/etc/lilo/lilo -b /dev/hda2 -c -i /etc/lilo/boot.b $* \
/linux \
/linux.backup \
msdos=/etc/lilo/chain.b+/dev/hda1@/dev/hda
\end{verbatim}
\subsection{Two disks, Linux (at least partially) on the first disk}
This case is equivalent to the configurations, where only one disk
is in the system. The Linux boot sector resides on the first hard
disk and the second disk is used later.
Only the location of the boot sector matters -- everything
else ({\tt /etc/lilo/boot.b},
{\tt /etc/lilo/map}, the root file system, a swap partition, other
Linux file systems, etc.) can be located anywhere on the second disk.
\subsection{Two disks, Linux on the second disk, the first disk has an
extended partition}
If there is no Linux partition on the first disk, but there is an
extended partition, the \LILO\ boot sector can be stored in the partition
sector of the extended partition and it should be booted by the original
master boot record or by a program like {\sf BOOTACTV}.
$$
\begin{tabular}{r|c|c|c|c|c|c|}
\multicolumn{1}{r}{}
& \multicolumn{3}{c}{\bf First disk} &
\multicolumn{1}{r}{\qquad}
& \multicolumn{2}{c}{\bf Second disk} \\
\cline{2-4}\cline{6-7}
& \multicolumn{3}{|l|}{MBR\hbox to 1.3in{\hfill\tt /dev/hda~}} &
& \multicolumn{2}{|l|}{MBR\hbox to 1.3in{\hfill\tt /dev/hdb~}} \\
\cline{3-4}\cline{7-7}
& & \multicolumn{2}{|l|}{MS-DOS\hfill\tt /dev/hda1} &
& & Linux\hfill\tt /dev/hdb1 \\
\cline{3-4}\cline{7-7}
$\rightarrow$ & & \multicolumn{2}{|l|}{Extended\hfill\tt /dev/hda2} &
& & $\ldots$\hfill\tt /dev/hdb2 \\
\cline{4-4}
& & & $\ldots$\hfill\tt /dev/hda5 & & & \\
\cline{4-4}
& & & $\ldots$\hfill\tt /dev/hda6 & & & \\
\cline{2-4}\cline{6-7}
\end{tabular}
$$
A typical {\tt /etc/lilo/config} file for this configuration would look
like this:
\begin{verbatim}
boot = /dev/hda2
compact
install = /etc/lilo/boot.b
image = /linux
image = /linux.backup
other = /dev/hda1
table = /dev/hda
label = msdos
\end{verbatim}
or, old-style ({\tt /etc/lilo/install}):
\begin{verbatim}
$ROOT/etc/lilo/lilo -b /dev/hda2 -c -i /etc/lilo/boot.b $* \
/linux \
/linux.backup \
msdos=/etc/lilo/chain.b+/dev/hda1@/dev/hda
\end{verbatim}
The program {\sf activate}, that accompanies \LILO, has to be used to set the
active marker on an extended partition, because MS-DOS' {\sf FDISK} and
{\sf (e)fdisk}
refuse to do that. (Which is generally a good idea.)
\subsection{Two disks, Linux on the second disk, the first disk has no
extended partition}
If there is neither a Linux partition nor an extended partition on the first
disk, where a \LILO\ boot sector could be stored, then there's only one place
left: the master boot record.
In this configuration, \LILO\ boots all other operating systems too.
$$
\begin{tabular}{r|c|c|c|c|c|}
\multicolumn{1}{r}{}
& \multicolumn{2}{c}{\bf First disk} &
\multicolumn{1}{r}{\qquad}
& \multicolumn{2}{c}{\bf Second disk} \\
\cline{2-3}\cline{5-6}
$\rightarrow$ & \multicolumn{2}{|l|}{MBR\hbox to 1.3in{
\hfill\tt /dev/hda~}} &
& \multicolumn{2}{|l|}{MBR\hbox to 1.3in{\hfill\tt /dev/hdb~}} \\
\cline{3-3}\cline{6-6}
& & MS-DOS\hfill\tt /dev/hda1 &
& & Linux\hfill\tt /dev/hdb1 \\
\cline{3-3}\cline{6-6}
& & $\ldots$\hfill\tt /dev/hda2 &
& & $\ldots$\hfill\tt /dev/hdb2 \\
\cline{2-3}\cline{5-6}
\end{tabular}
$$
You should back up your old MBR before installing \LILO\ and verify that
\LILO\ is able to boot your other operating system(s) before relying on
this approach.
A typical {\tt /etc/lilo/config} file for this configuration would look
like this:
\begin{verbatim}
boot = /dev/hda
compact
install = /etc/lilo/boot.b
image = /linux
image = /linux.backup
other = /dev/hda1
table = /dev/hda
label = msdos
\end{verbatim}
or, old-style ({\tt /etc/lilo/install}):
\begin{verbatim}
$ROOT/etc/lilo/lilo -b /dev/hda -c -i /etc/lilo/boot.b $* \
/linux \
/linux.backup \
msdos=/etc/lilo/chain.b+/dev/hda1@/dev/hda
\end{verbatim}
\section{Technical overview}
This section contains a description of several internals of \LILO. It is
not necessary to understand them in order to install \LILO.
\subsection{Load sequence}
\label{load}
The boot sector is loaded by the ROM-BIOS at address 0x07C00. It moves
itself to address 0x9A000, sets up the stack (growing downwards from
0x9B000 to 0x9A200), loads the secondary boot loader at address
0x92000 and transfers control to it. It displays an ``L'' after moving
itself and an ``I'' before starting the secondary boot loader.
The secondary boot loader loads the descriptor table at 0x9D200 and checks
for user input. If either the default is used or if the user has specified
an alternate image, the floppy boot sector of that image is loaded at 0x90000%
\footnote{The floppy boot sector is only used as a source of setup
information.},
the setup part is loaded at 0x90200 and
the kernel part is loaded at 0x10000. If the image being booted is not an
unstripped kernel, the memory area 0x10000-0x8FFFF is zeroed before
loading. During the load operation, the sectors
of the map file are loaded at 0x9D000.
If the loaded image is a traditional boot image, control is transferred to
its setup code. If it is an unstripped kernel, its BSS is zeroed first.
If a different operating system is booted, things are a bit more difficult:
the chain loader is loaded at 0x90200 and the boot sector of the other OS
is loaded at 0x90400. The chain loader moves the partition table (loaded at
0x903BE as part of the chain loader) to 0x00600 and the boot sector to
0x07C00. After that, it passes control to the boot sector.
The secondary boot loader displays an ``L'' after being started and an ``O''
after loading the descriptor table.
$$
\begin{tabular}{l|c|l}
\cline{2-2}
\tt 0x00000 & & 1982 bytes \\
\cline{2-2}
\tt 0x007BE & Partition table & 64 bytes \\
\cline{2-2}
\tt 0x007FE & & 29 kB \\
\cline{2-2}
\tt 0x07C00 & Boot load area & 512 bytes \\
\cline{2-2}
\tt 0x07E00 & & 32.5 kB \\
\cline{2-2}
\tt 0x10000 & & 320 kB \\
& Kernel & \\
& & \\
& & \\
\cline{2-2}
\tt 0x60000 & & 192 kB \\
& & \\
& & \\
\cline{2-2}
\tt 0x90000 & Floppy boot sector & 512 bytes \\
\cline{2-2}
\tt 0x90200 & Setup (kernel) & 39.5 kB (2 kB used) \\
\cline{2-2}
\tt 0x9A000 & Primary boot loader & 512 bytes \\
\cline{2-2}
\tt 0x9A200 & Stack & 3.5 kB \\
\cline{2-2}
\tt 0x9B000 & Secondary boot loader & 8 kB (3.5 kB used) \\
\cline{2-2}
\tt 0x9D000 & Map load area & 512 bytes \\
\cline{2-2}
\tt 0x9D200 & Descriptor table & 1 kB \\
\cline{2-2}
\tt 0x9D600 & & 10.5 kB \\
& & \\
\cline{2-2}
\multicolumn{3}{l}{\tt 0xA0000} \\
\end{tabular}
$$
The area 0x92020-0x92023 is overlaid by command-line information while
the secondary boot loader is running.
\subsection{File references}
This section describes the references among files involved in the boot
procedures.
$$
\input bootloader
$$
The boot sector contains the primary boot loader, the address of both
descriptor table sectors and the addresses of the sectors of the secondary
boot loader. The boot sector is copied from {\tt boot.b}.
The primary boot loader can store up to four sector addresses of the
secondary boot loader.
$$
\input map
$$
The map file consists of so-called sections and of special data sectors.
Each section
spans an integral number of disk sectors and contains addresses of sectors
of other files.\footnote{There are two exceptions: 1. If a ``hole'' is being
covered or if the floppy boot sector of an unstripped kernel has been omitted,
the address of the zero sector is used. This sector is part of the
map file. 2. When booting a different operating system, the first sector is
the merged chain loader that has been written to the map file before that
section.} The last address slot of each sector is either unused (if the map
ends in this sector) or contains the address of the next sector in the
section.
The three sectors at the beginning of the map file are special: the first
two
sectors contains the boot image descriptor table and the third sector
is filled with zero bytes. This sector is mapped whenever a file contains
a ``hole''.
$$
\input image
$$
A traditional boot image consists simply of a sequence of sectors that are
loaded. Images that are loaded from a device are treated exactly the same
way as images that are loaded from a file.
$$
\input unstripped
$$
Unstripped kernels consist of the floppy boot sector, the setup part and
of the kernel file. The
descriptor also contains information about the start and the size of the
BSS segment. The boot loader clears BSS before starting the kernel.
$$
\input other
$$
When booting another operating system, the chain loader ({\tt chain.b}) is
merged with the partition table\footnote{If the partition table is omitted,
that area is filled with zero bytes.} and written into the map file. The
map section of this boot image starts after that sector and contains only
the address of a dummy floppy boot sector (the zero sector, but its
contents are irrelevant), the loader
sector and of the boot sector of the other operating system.
\subsection{External interface}
\LILO\ is able to receive its command line from a program that is booted
before it. This externally provided command line is only used if the
user does not use the normal mechanism to invoke the boot prompt.
The following register contents are expected:
\begin{description}
\item[\bf DL] contains the value 0xFE.
\item[\bf ES:SI] points to the string ``LILO''. The string must be in
upper case and no terminating character is needed. The string must not
cross segment boundaries.
\item[\bf ES:BX] points to a NUL-terminated string that is used as the
command line. This string has a maximum length of 78 characters (not
including the terminating NUL) and must not cross segment boundaries.
\end{description}
There are two values of the externally provided command line that have a
special meaning:
\begin{itemize}
\item an empty string ({\bf ES:BX} points to a NUL byte) is interpreted
as a request to enter the boot prompt and to accept keyboard input.
\item a string that consists only of blanks is interpreted as a request
to boot the default boot image.
\end{itemize}
\section{The boot prompt}
Immediately after it's loaded, \LILO\ checks, whether one of the following
is happening:
\begin{itemize}
\item any of the \key{Shift}, \key{Control} or \key{Alt} keys is being
pressed.
\item \key{CapsLock} or \key{ScrollLock} is set.
\end{itemize}
If this is the case, \LILO\ displays the \verb"boot:" prompt and waits for
the name of a boot image. Otherwise, it boots the default boot image\footnote{%
The default boot image is either the first boot image or the image that
has been selected at the boot prompt.}
or -- if a
delay has been specified -- waits for one of the listed activities
until that amount of time has passed.
At the boot prompt, the name of the image to boot can be entered. Typing
errors can be corrected with \key{BackSpace}, \key{Delete},
\key{Ctrl U} and \key{Ctrl X}. A list of known images can be obtained by
pressing \key{?} (on the US keyboard) or \key{Tab}.
If \key{Enter} is pressed and no file name has been entered, the default
image is booted.
When using a modern kernel\footnote{0.98pl3 or newer.}, \LILO\ is also
able to pass command-line options
to it. Command-line options are words that follow the name of the boot
image and that are separated by spaces. Currently, the kernel
recognizes the option {\tt root={\it device\/}} and
{\sf init} from the next
{\sf poeigl} package will most likely recognize an option {\tt single}
(among others).
{\tt single} boots the system in single-user mode. This bypasses all
system initialization procedures and directly starts a root shell on the
console. Multi-user mode can be entered by exiting the single-user shell
or by rebooting.
{\tt root={\it device\/}} changes the root device. This overrides
settings that may have been made in the boot image and on the
\LILO\ command line. {\it device\/} is the hexadecimal device number.%
\footnote{%
This is a list of device numbers of some frequently used devices: \\
\begin{tabular}{lllllll}
\qquad
& {\tt /dev/fd0} & 200\qquad & \tt /dev/hda1 & 301\qquad & /dev/sda1 & 801 \\
& {\tt /dev/fd1} & 201 & \tt /dev/hda2 & 302 & /dev/sda2 & 802 \\
& \multicolumn{2}{c}{$\cdots$} & \multicolumn{2}{c}{$\cdots$} &
\multicolumn{2}{c}{$\cdots$} \\
& & & \tt /dev/hdb1 & 341 & /dev/sdb1 & 811 \\
& & & \tt /dev/hdb2 & 342 & /dev/sdb2 & 812 \\
& \multicolumn{2}{c}{} & \multicolumn{2}{c}{$\cdots$} &
\multicolumn{2}{c}{$\cdots$} \\
\end{tabular}}
Example:
\begin{verbatim}
boot: linux single root=200
\end{verbatim}
\section{Map installer}
The map installer program {\tt /etc/lilo/lilo} updates the boot sector
and creates the map file. It is usually run from the shell script
{\tt /etc/lilo/install}. If the map installer detects an error, it
terminates immediately and does not touch the boot sector and the map
file.
Whenever the \LILO\ map installer updates a boot sector, the original boot sector
is copied
to {\tt /etc/lilo/boot.{\it number\/}}, where {\it number\/} is the
hexadecimal device number. If such a file already exists, no backup
copy is made.
The \LILO\ map installer may create some device special files in your
{\tt /tmp} directory that
are not removed if an error occurs. They are named
{\tt /tmp/dev.{\it number}}.
\subsection{Command-line arguments}
The \LILO\ map installer accepts the following command-line options:
\begin{description}
\item[\tt -b \it boot\_device]~ \\
Sets the name of the device that contains the boot sector. If {\tt -b}
is omitted, the boot sector is read from (and possibly written to) the
device that is currently mounted as root.
\item[\tt -c]~ \\
Tries to merge read requests for adjacent sectors into a single read
request. This drastically reduces load time and keeps the map
smaller. Using {\tt -c} is especially recommended when booting from
a floppy disk.
\item[\tt -C \it config\_file]~ \\
Specifies the new-style configuration file that is used by the map
installer (see section \ref{new-config}). If {\tt -C} is omitted,
old-style configuration is used.
\item[\tt -d \it tsecs]~ \\
Specifies the number of tenths of seconds \LILO\ should wait before
booting the first image. This is useful on systems that immediately
boot from the hard disk after enabling the keyboard. \LILO\ doesn't wait
if {\tt -d} is omitted.
\item[\tt -D]~ \\
Selects dump mode. Dumps are used during migration from earlier versions
of \LILO\ (see section \ref{migration}). {\tt -D} also implies {\tt -t}
and disables all other informational messages.
\item[\tt -f \it disktab\_file]~ \\
Specifies the name of the disk parameter table (see section \ref{disktab}).
The map installer looks for {\tt /etc/lilo/disktab} if {\tt -f} is omitted.
\item[\tt -i \it boot\_sector]~ \\
Install the specified file as the new boot sector. If {\tt -i} is omitted,
the old boot sector is modified. A BIOS device code can be specified.
{\tt -i} is usually a permanent part of the invocation of the map installer
in {\tt /etc/lilo/install}.
\item[\tt -l]~ \\
Generate linear sector addresses instead of sector/head/cylinder addresses.
Linear addresses are translated at run time and do not depend on disk
geometry. This is experimental and is not (yet) intended for common use.
\item[\tt -m \it map\_file]~ \\
Specifies the location of the map file. If {\tt -m} is omitted, a file
{\tt /etc/lilo/map} is used. A BIOS device code can be specified.
\item[\tt -q]~ \\
List the currently mapped files.
\item[\tt -r \it root\_directory]~ \\
Chroot to the specified directory before doing anything else. This is
useful when running the map installer while the normal root file system
is mounted somewhere else, e.g. when recovering from an installation
failure with a bootimage/rootimage.\footnote{I.e. if your root partition
is mounted on {\tt /mnt}, you can update the map by simply running
{\tt /mnt/etc/lilo/install} with the argument {\tt -r /mnt}. If you're
normally using the default boot sector, you have to specify it
explicitly in this case: {\tt -b /dev/{\it device\_name}}. So the
complete command may be something like this: \\
\verb"/mnt/etc/lilo/install -r /mnt -b /dev/hda1" \\
You also have to set the environment variable {\tt ROOT} before running
the update script, e.g.: \\
\verb"export ROOT=/mnt"}
The current directory is changed to the new root directory, so using
relative paths may not work.
\item[\tt -s \it backup\_file]~ \\
Copy the original boot sector to {\it backup\_file\/} (which may also be
a device, e.g. {\tt /dev/null}) instead of
{\tt /etc/lilo/boot.{\it number}}
\item[\tt -S \it backup\_file]~ \\
Like {\tt -S}, but overwrite an old backup copy if it exists.
\item[\tt -t]~ \\
Test only. This performs the entire installation procedure except
replacing the map file and writing the modified boot sector. This
can be used in conjunction with the {\tt -v} option to verify that
\LILO\ will use sane values.
\item[\tt -v]~ \\
Turns on lots of progress reporting. Repeating {\tt -v} will turn on more
reporting. ({\tt -v -v -v -v -v} is the highest verbosity level and
displays all sector mappings before and after compaction.)
\end{description}
There are two ways how image files can be specified: the traditional
approach is to specify them on the command line, typically in
{\tt /etc/lilo/install}. The new, preferred method uses a configuration
file {\tt /etc/lilo/config}. Section \ref{migration} describes the
migration procedure.
\subsubsection{Old-style configuration}
If no image files are specified on the command line, the currently mapped
files are listed. Only the options {\tt -m}, {\tt -v} and {\tt -r} can be
used in this mode.
If at least one file name is specified, a new map is created for those files
and they are registered in the boot sector. If the root device has been
set in the images, it is copied into the descriptors in the boot sector.
Changing the root device specification in a boot image after the map file
has been built has no effect.
If no root device has been set\footnote{Or if this is not a traditional
boot image.}, the current root device is used. The root device
can be overridden by appending it to the image specification, e.g.
$$
\verb"lilo "\underbrace{\strut\verb"foo"}_{\rm image}\verb","%
\underbrace{\strut\verb"/dev/hda1"}_{\rm root}
$$
or
$$
\verb"lilo "\underbrace{\strut\verb"foo"}_{\rm image}\verb","%
\underbrace{\strut\verb"0x302"}_{\rm root}
$$
It is perfectly valid to use different root settings for the same
image, because \LILO\ stores them in the image descriptors and not in the
images themselves. Example:
\begin{verbatim}
lin-hd=/linux,/dev/hda2 \
lin-fd=/linux,/dev/fd0
\end{verbatim}
The image files can reside on any media that is accessible at boot time.
There's no need to put them on the root device, although this certainly
doesn't hurt.
\LILO\ uses the first file name (without its path) of each image specification
to identify that image. A different name can be used by prefixing the
specification with {\it label\/}{\tt =}, e.g.
\begin{verbatim}
msdos=/etc/lilo/chain.b+/dev/sda1@/dev/sda
\end{verbatim}
\subsection{New-style configuration}
\label{new-config}
For new-style configuration, the file {\tt /etc/lilo/install} always looks
like this:
\begin{verbatim}
$ROOT/etc/lilo/lilo -C /etc/lilo/config $*
\end{verbatim}
The configuration information is stored in the file {\tt /etc/lilo/config}
and consists of variable assignments. The following syntax rules apply:
\begin{itemize}
\item flag variables consist of a single word and are followed by
whitespace or the end of the file.
\item string variables consist of the variable name, optional whitespace,
an equal sign, optional whitespace, the value and required whitespace
or the end of the file.
\item a non-empty sequence of blanks, tabs, newlines and comments counts
as whitespace.
\item variable names are case-insensitive. Values are usually case-sensitive,
but there are a few exceptions. (See below.)
\item tabs and newlines are special characters and may not be part of a
variable name or a value. The use of other control characters and
non-ASCII characters is discouraged.
\item blanks and equal signs may only be part of a variable name or a
value if they are escaped by a backslash. An equal sign may not be
the only character in a name or value.
\item an escaped tab is converted to an escaped blank. An escaped newline
is removed from the input stream.
\item comments begin with a number sign and end with the next newline.
All characters (including backslashes) until the newline are ignored.
\end{itemize}
{\tt /etc/lilo/config} begins with a possibly empty options section. All
options can also be set from the command line, but storing permanent
options in the configuration file is more convenient. The following
options are recognized:
\begin{description}
\item[\tt boot=\it boot\_device] is equivalent to {\tt -b \it boot\_device}.
\item[\tt compact] is equivalent to {\tt -c}.
\item[\tt delay=\it tsecs] is equivalent to {\tt -d \it tsecs}.
\item[\tt linear] is equivalent to {\tt -l}.
\item[\tt install=\it boot\_sector] is equivalent to
{\tt -i \it boot\_sector]}.
\item[\tt disktab=\it disktab\_file] is equivalent to
{\tt -f \it disktab\_file}.
\item[\tt map=\it map\_file] is equivalent to {\tt -m \it map\_file}.
\item[\tt verbose=\it level] is equivalent to {\it level} repetitions of
{\it -v}. If {\tt -v} is specified on the command line, {\it level} is
increased.
\item[\tt backup=\it backup\_file] is equivalent to {\tt -s \it backup\_file}.
\item[\tt force-backup=\it backup\_file] is equivalent to
{\tt -S \it backup\_file}. {\tt backup=\it backup\_file} is ignored if
{\tt -S \it backup\_file} appears in the same configuration file.
\end{description}
If the option {\tt -q} is specified on the command line, the currently mapped
files are listed. Otherwise, a new map is created for the images described
in {\tt /etc/lilo/config} and they are registered in the boot sector. Each
image description begins with a special variable and is followed by optional
variables. The following variables can be used for all image descriptions
that describe a Linux kernel:
\begin{description}
\item[\tt root=\it root\_device] specifies the device that should be
mounted as root. If this variable is omitted, the root device setting
that is contained in the boot image is used. It can be changed with the
{\sf rdev} aka {\sf setroot} program.
\item[\tt vga=\it mode] specifies the VGA text mode that should be selected
when booting. The following values are recognized (case is ignored):
\begin{description}
\item[\tt normal] select normal 80x25 text mode.
\item[\tt extended] select 80x50 text mode.
\item[\tt ask] stop and ask for user input (at boot time). A system
where this option is being used is unable to automatically reboot.
\item[\it number] use the corresponding text mode. A list of available
modes can be obtained by booting with {\tt vga=ask} and pressing
\key{Enter}.
\end{description}
If this variable is omitted, the VGA mode setting that is contained in the
boot image is used. Some versions of {\sf setroot} support manipulation
of the VGA text mode setting in the boot image.
\item[\tt ramdisk=\it size] specifies the size of the optional RAM disk.
A value of zero indicates that no RAM disk should be created. If this
variable is omitted, the RAM disk size that is configured into the boot
image is used.
\end{description}
The variables {\tt vga} and {\tt ramdisk} are only available when running a
kernel that supports them, e.g. 0.98pl6 and later. If one of {\it root},
{\it vga} or {\it ramdisk} is omitted in the configuration file and the
corresponding value in the boot image is changed, \LILO\ will use the new
value.
It is perfectly valid to use different root settings for the same
image, because \LILO\ stores them in the image descriptors and not in the
images themselves. Example:
\begin{verbatim}
image = /linux
label = lin-hd
root = /dev/hda2
image = /linux
label = lin-fd
root = /dev/fd0
\end{verbatim}
The image files can reside on any media that is accessible at boot time.
There's no need to put them on the root device, although this certainly
doesn't hurt.
\LILO\ uses the first file name (without its path) of each image specification
to identify that image. A different name can be used by setting the variable
{\tt label} (see the example above).
\subsection{Boot image types}
\LILO\ can boot the following types of images:
\begin{itemize}
\item ``traditional'' boot images from a file.
\item ``traditional'' boot images from a block device. (I.e. a floppy
disk.)
\item unstripped kernel executables.
\item the boot sector of some other operating system.
\end{itemize}
The image type is determined either by the syntax that is used for the image
specification (old-style configuration) or by the name of the initial
variable of the configuration section (new-style configuration).
\subsubsection{Booting ``traditional'' boot images from a file}
If present, the root device definition is taken from the boot image.
The image is specified as follows:
{\bf Old-style:}
$$\hbox{{\it file\_name}\big[\verb":"{\it BIOS\_code}\big]}$$
Example: \verb"/linux"
{\bf New-style:}
$$\hbox{\tt image=\it name}$$
The following additional variables are recognized: {\tt root}, {\tt vga},
{\tt ramdisk} and {\tt label}.
Example:
\begin{verbatim}
image = /linux
\end{verbatim}
\subsubsection{Booting ``traditional'' boot images from a device}
The root device setting in the image is ignored.\footnote{That
device may not be available at the time \LILO\ is installed and it
is therefore impossible to read the settings from the image file.}
The range of sectors
that should be mapped, has to be specified. Either a range
({\it start\/\tt -\it end\/}) or a start and a distance
({\it start\/\tt +\it number\/}) have to be specified. {\it start\/}
and {\it end\/} are zero based. If only
the start if specified, only that sector is mapped.
{\bf Old-style:}
$$\hbox{{\it device\_name}\big[\verb":"{\it BIOS\_code}\big]\verb"#"%
{\it start}\big[\verb"-"{\it end}\big\vert\verb"+"{\it number}\big]}$$
Example: \verb"/dev/fd0#1+512"
{\bf New-style:}
$$\hbox{\tt image=\it name}$$
The following additional variables are recognized: {\tt root}, {\tt vga},
{\tt ramdisk}, {\tt label} and {\tt range}.
Example:
\begin{verbatim}
image = /dev/fd0
range = 1+512
\end{verbatim}
\subsubsection{Booting unstripped kernel executables}
\label{unsker}
Unstripped kernel executables contain no root device information.
The setup code of the kernel has also to be added to the kernel. First,
it has to be copied to a suitable place and its header has to be removed,
e.g.
\begin{verbatim}
dd if=/usr/src/linux/boot/setup of=/etc/lilo/setup.b \
bs=32 skip=1
\end{verbatim}
If this command is placed at the beginning of {\tt /etc/lilo/install},
{\tt setup.b} is automatically updated whenever that script is run
because anything else changes.
{\bf Old-style:}
The image specification looks like this:
$$\hbox{{\it setup\_name}\big[\verb":"{\it BIOS\_code}\big]\verb"+"%
{\it kernel\_name}\big[\verb":"{\it BIOS\_code}\big]}$$
Example: \verb"/etc/lilo/setup.b+/usr/src/linux/tools/system"
{\bf New-style:}
$$\hbox{\tt unstripped=\it name}$$
The following additional variables are recognized: {\tt root}, {\tt vga},
{\tt ramdisk}, {\tt label}, {\tt boot} and {\tt setup}.
\begin{description}
\item[\tt boot=\it boot\_sector] specifies the floppy boot sector that should
be loaded. It is used to provide defaults for settings like the root device,
etc. The boot sector file can be created like the setup file. (See above.)
The recommended name for the floppy boot sector file is
{\tt /etc/lilo/bsect.b}.
If this variable is omitted, a zero-filled sector is loaded instead.
\item[\tt setup=\it setup\_file] specifies the setup file that should
be loaded. This variable is required.
\end{description}
Example:
\begin{verbatim}
unstripped = /usr/src/linux/tools/system
setup = /etc/lilo/setup.b
\end{verbatim}
\subsubsection{Booting a foreign operating system}
\LILO\ can even boot other operating systems, i.e. MS-DOS. This feature
is new and may not yet work totally reliably. (Reported to work with
PC-DOS 4.0, MS-DOS 5.0, DR-DOS 6.0, OS/2 2.0, 386BSD and SCO UNIX.)
To boot an other operating
system, the name of a loader program, the device that contains the boot
sector and the device that contains the partition table have to be
specified.
The boot sector is merged with the partition table and stored in the map file.
Currently, only the loader {\tt chain.b} exists. {\tt chain.b} simply
starts the specified boot sector.\footnote{The boot sector is loaded by
\LILO's secondary boot loader before control is passed to the code of
{\tt chain.b}.}
{\bf Old-style:}
$$\hbox{{\it loader\/}\verb"+"{\it boot\_dev}\big[\verb":"{\it BIOS\_code}\big]%
\verb"@"\big[{\it part\_dev}\big]}$$
Example: \verb"/etc/lilo/chain.b+/dev/hda2@/dev/hda"
The name of the device that contains the partition table can be omitted if
the respective operating system has other means to determine from which
partition it has been booted.
(E.g. MS-DOS usually stores the geometry of the boot disk or partition in
its boot sector.)
{\bf New-style:}
$$\hbox{\tt other=\it name}$$
The following additional variables are recognized: {\tt label}, {\tt loader},
{\tt table}.
\begin{description}
\item[\tt loader=\it chain\_loader] specifies the chain loader that should
be used. If this variable is omitted, {\tt /etc/lilo/chain.b} is used.
\item[\tt table=\it device] specifies the device that contains the partition
table. \LILO\ does not pass partition information to the booted operating
system if this variable is omitted. (Some operating systems have other
means to determine from which partition they has been booted.)
\end{description}
Example:
\begin{verbatim}
other = /dev/hda2
table = /dev/hda
\end{verbatim}
\subsection{Disk parameter table}
\label{disktab}
For floppies and IDE disks (or MFM, RLL, ESDI, etc.), \LILO\ can obtain the
disk geometry information from the kernel. Unfortunately, this is not
possible with SCSI disks. The file {\tt /etc/lilo/disktab} is used to describe
such disks. For each device ({\tt /dev/sda} $\rightarrow$ 0x800,
{\tt /dev/sda1} $\rightarrow$ 0x801, etc.),
the BIOS code, the disk geometry and the offset of the first sector of
that partition (measured in sectors) have to be specified, e.g.
\begin{verbatim}
# /etc/lilo/disktab - LILO disk parameter table
#
# This table contains disk parameters for SCSI disks and non-
# standard parameters of IDE disks. Parameters in disktab
# _always_ override auto-detected disk parameters.
# Dev. BIOS Secs/ Heads/ Cylin- Part.
# num. code track cylin. ders offset
0x800 0x80 32 64 631 0 # /dev/sda
0x801 0x80 32 64 631 32 # /dev/sda1
0x802 0x80 32 64 631 204800 # /dev/sda2
\end{verbatim}
(Those parameters are just a random example from my system. However, many
SCSI controllers
re-map the drives to 32 sectors and 64 heads. The number of cylinders
does not have to be exact, but it shouldn't be lower than the number of
effectively available cylinders.)
Note that the device number and the BIOS code have to be specified as
hexadecimal numbers with the ``0x'' prefix.
The disk geometry parameters can be obtained by booting MS-DOS and
running the program {\tt DPARAM.COM} with the hexadecimal BIOS code of
the drive as its argument, e.g. \verb"dparam 0x80" for the first hard
disk. It displays the number of sectors per
track, the number of heads per cylinder and the number of cylinders.
The partition offset is printed by the Linux kernel when the SCSI disk
is detected at boot time. Example:
\begin{verbatim}
sd0 :
part 1 start 32 size 204768 end 204799
part 2 start 204800 size 1087488 end 1292287
\end{verbatim}
The first partition has an offset of 32 sectors, the second has an
offset of 204800 sectors.
Because many SCSI controllers don't support more than 1 GB when using
the BIOS interface, \LILO\ can't access files that are located beyond the
1 GB limit of large SCSI disks and reports errors in these cases.
\section{Installation and updates}
\subsection{First-time installation}
\label{install}
\LILO\ 0.7 is compatible with all kernels that don't support presetting
of a swap device. This change has probably occurred at some 0.97 version.
If the swap device preset code is disabled, you can also use 0.96c-pl1
(or newer) kernels. First, you have to install the \LILO\ files:
\begin{itemize}
\item extract all files from {\tt lilo.{\it version}.tar.Z}\footnote{%
Don't use {\tt /etc/lilo} for the \LILO\ source. Standard installation
procedures fail if the source is in the same directory as the production
binaries.}
\item run\quad{\tt make}\quad to compile and assemble all parts.
\item run\quad{\tt make install}\quad to copy all \LILO\ files to
{\tt /etc/lilo}.
{\tt /etc/lilo} should now contain the following files: {\tt boot.b},
{\tt chain.b}, {\tt disktab} and {\tt lilo}.
\end{itemize}
If you want to use \LILO\ on a SCSI disk, you have to determine the
parameters of your SCSI disk(s) and put them into the file
{\tt /etc/lilo/disktab}. See section \ref{disktab} for details.
The next step is to test \LILO\ with the boot sector on a floppy disk:
\begin{itemize}
\item insert a blank (but low-level formatted) floppy disk into
{\tt /dev/fd0}.
\item chdir to {\tt /etc/lilo}.
\item run {\tt ./lilo -b /dev/fd0 -i boot.b -v -v -v {\it kernel\_image(s)}}%
\footnote{If you've already installed \LILO\ on your system, you might not want
to overwrite your old map file.
Use the {\tt -m} option to specify an alternate map file name.}
\item reboot. \LILO\ should now load its boot loaders from the floppy disk
and then continue loading the kernel from the hard disk.
\end{itemize}
Now, your have to decide, which boot concept you want to use. Let's assume
you have a Linux partition on {\tt /dev/hda2} and you want to install your
\LILO\ boot sector there. The DOS-MBR loads the \LILO\ boot sector.
\begin{itemize}
\item get a working bootimage and a rootimage, or a bootable rootimage.
Verify that you can boot
with this setup and that you can mount your Linux partition(s) with it.
\item if the boot sector you want to overwrite with \LILO\ is of any value
(e.g. it's the MBR or it contains a boot loader you might want to use
if you encounter problems with \LILO), you should mount your rootimage
and make a backup copy of your boot sector to a file on that floppy,
e.g. \verb"dd if=/dev/hda of=/fd/boot_sector bs=512 count=1"
\item create a shell script {\tt /etc/lilo/install} that installs and
updates \LILO\ on your hard disk, e.g.\\
\verb"$ROOT/etc/lilo/lilo "{\it possibly\_some\_options\/}%
\verb" -C /etc/lilo/config $* \" \\
Then create the configuration file {\tt /etc/lilo/config}, e.g. \\
\verb"install = /etc/lilo/boot.b" \\
\verb" "{\it image specifications} \\
\verb" "$\ldots$ \\
Be sure to use absolute paths for all files. Relative paths may cause
unexpected behaviour when using the {\tt -r} option.
\item Now, you can check what \LILO\ would do if you were about to install
it on your hard disk: \\
\verb"/etc/lilo/install -v -v -v -t"
\item If you need some additional boot utility (i.e. {\sf BOOTACTV}), you
should install that now.
\item Run {\tt /etc/lilo/install} to install \LILO\ on your hard disk.
\item If you have to change the active partition, use {\sf (e)fdisk} or
activate to do that.
\item Reboot.
\end{itemize}
\subsection{\LILO\ update}
When updating to a new version of \LILO, the initial steps are the same as
for a first time installation: extract all files, run {\tt make} to build
the executables and run {\tt make install} to move the files to
{\tt /etc/lilo}.
The old versions of {\tt boot.b} and {\tt chain.b} are automatically
renamed to {\tt boot.old} and {\tt chain.old}. This is done to ensure
that you can boot even if the installation procedure is not finished.
{\tt boot.old} and {\tt chain.old} can be deleted after the map file
is rebuilt.
Because the locations of {\tt boot.b} and {\tt chain.b} have changed
and because the map file format may be different too, you have to update
the boot sector and the map file. Run {\tt /etc/lilo/install} to do this.
\subsection{Migration from old-style to new-style configuration}
\label{migration}
An existing pre-\LILO\ 0.7 configuration can easily be replaced by a
new-style configuration. The command-line option {\tt -D} dumps the
current settings on standard output. This is a typical migration
procedure:
\begin{itemize}
\item upgrade to \LILO\ 0.7
\item \verb"cd" to {\tt /etc/lilo}
\item run \verb"./install -D >config"
\item add new variables {\tt video} and {\tt ramdisk} to
{\tt /etc/lilo/config} if you want to.
\item run \verb"./lilo -C config -D | diff -c config -" \\
to verify the correctness of the dump.\footnote{\LILO\ may change the
order of variables and the placement of whitespace in the second dump.
It also removes comments.}
\item rename {\tt /etc/lilo/install} to {\tt /etc/lilo/install.old} and
copy {\tt install.new} from your \LILO\ source directory to
{\tt /etc/lilo/install}
\item add commands to create boot and setup files to the new
{\tt /etc/lilo/install} if you're booting unstripped kernels.
\item run {\tt /etc/lilo/install}
\end{itemize}
\subsection{Kernel update}
Whenever any of the kernel files that are accessed by \LILO\ is moved or
overwritten, the map has to be re-built.\footnote{It is advisable to
keep a second, stable, boot image that can be booted if you forget
to update the map after a change to your usual boot image.} Run
{\tt /etc/lilo/install} to do this.
If the boot or setup code has changed and if you're booting unstripped kernels,
you also have to update {\tt bsect.b} and {\tt setup.b}. This should be done in
{\tt /etc/lilo/install}, as described in section \ref{unsker}.
If you're frequently re-compiling the kernel, you should put an invocation of
{\tt /etc/lilo/install} into the kernel's top Makefile.
Example ({\tt $\ldots$/linux/Makefile}):
\begin{verbatim}
...
Image: boot/bootsect boot/setup tools/system tools/build
cp tools/system system.tmp
strip system.tmp
tools/build boot/bootsect boot/setup system.tmp \
$(ROOT_DEV) >/linux
/etc/lilo/install
rm system.tmp
sync
...
\end{verbatim}
Recent kernels already have a make target ``lilo'' that copies the kernel
to {\tt /vmlinux} and runs {\tt /etc/lilo/install}
\section{Troubleshooting}
All parts of \LILO\ display some messages that can be used to diagnose
problems.
\subsection{Map installer errors}
Most messages of the map installer ({\tt /etc/lilo/lilo}) should be
self-explanatory. Some messages that indicate common errors are
listed below:
\begin{description}
\item[\tt Can't put the boot sector on logical partition \it number]~\\
An attempt has been made to put \LILO's boot sector on the current
root FS partition which is on a logical partition. This usually
doesn't have the desired effect, because common MBRs can only boot
primary partitions. This check can be bypassed by explicitly
specifying the boot partition with the {\tt -b} option.
\item[\tt First sector of {\it device} doesn't have a valid boot signature]%
~\\
The first sector of the specified device does not appear to be a valid
boot sector. You might have confused the device name.\footnote{Because
different partition programs may display the partitions in a different
order, it is possible that what you think is your first partition isn't
{\tt /dev/hda1}, etc. A good method to verify the content of a partition
is to try to mount it.}
\item[\tt geo\_comp\_addr: Cylinder number is too big ({\it number} $>$
1023)]~\\
A file is located beyond the 1023th cylinder of a hard disk. \LILO\ can't
access such files, because the BIOS limits cylinder numbers to the range
0$\ldots$1023. Try moving the file to a different place, preferably a
partition that is entirely within the first 1023 cylinders of the disk.
\item[\tt Hole found in map file ({\it location\/})]~\\ The map installer is
confused about the disk organization. If you're running version 0.4 of
\LILO, upgrade to 0.5. Otherwise, please report this error.
\item[\it item\/ \tt doesn't have a valid LILO signature]~\\ The specified
item has been located, but is not part of \LILO. If {\it item} is the
first boot sector, you've
probably forgotten to specify the {\tt -i} option to install the
\LILO\ boot sector.
\item[\it item \tt has an invalid stage code (\it number\/\tt)]~\\ The
specified item has probably been corrupted. Try re-building
\LILO.
\item[\it item \tt is version {\it number}. Expecting version {\it number}.]%
~\\
The specified entity is either too old or too new. Make sure all parts
of \LILO\ (map installer, boot loaders and chain loaders) are from the
same distribution. If {\it item} is the first boot sector, you have to
run the map installer with the {\tt -i} option to update it.\footnote{%
The expected version number may be lower than the version number of the
\LILO\ package.}
\item[\tt Kernel {\it name} is too big]~\\ The kernel image (without the setup
code) is bigger than 512 kbytes. \LILO\ would overwrite itself when trying
to load such a kernel. Try removing some unused drivers and compiling
the kernel again.
\item[\tt Partition entry not found]~\\ The partition from which an other
operating system should be booted isn't listed in the specified
partition table. This either means that an incorrect partition
table has been specified or that you're trying to boot from a
logical partition. The latter usually doesn't work. You can bypass
this check by omitting the partition table specification (e.g.
\verb"/dev/hda2@" or omitting the variable \verb"table").
\item[\tt Sorry, don't know how to handle device \it number]~\\ \LILO\ uses
files that are located on a device (typically a SCSI disk) for which
there is no easy way to determine the disk geometry. Such devices have
to be described in the file {\tt /etc/lilo/disktab}.
\end{description}
\subsection{\LILO\ start message}
When \LILO\ loads itself, it displays the word ``LILO''. Each letter is
printed before or after performing some specific action. If \LILO\ fails
at some point, the letters printed so far can be used to identify the
problem. (See also section \ref{load}.)
\begin{description}
\item[\rm ({\it nothing\/})] No part of \LILO\ has been loaded.
\LILO\ either isn't installed or the partition on which its boot
sector is located isn't active.
\item[\tt L] The first stage boot loader has been loaded and started,
but it can't load the second stage boot loader. This usually indicates
a media failure or a geometry mismatch (e.g. bad parameters in
{\tt /etc/lilo/disktab}).
\item[\tt LI] The first stage boot loader was able to load the second
stage boot loader, but has failed to activate it. This can either be
caused by a geometry mismatch or by moving {\tt /etc/lilo/boot.b} without
running the map installer.
\item[\tt LIL] The second stage boot loader has been started, but it
can't load the descriptor table from the map file. This is typically
caused by a media failure or by a geometry mismatch.
\item[\tt LILO] All parts of \LILO\ have been successfully loaded.
\end{description}
\subsection{Disk error codes}
If the BIOS signals an error when \LILO\ is trying to load a boot
image, the respective error code is displayed. The following BIOS
error codes are known:
\begin{description}
\item[\tt 0x00] {\it Internal error}. This code is generated by
the sector read routine of the \LILO\ boot loader whenever an
internal inconsistency is detected. This might be caused by corrupt
files, try re-building the map file.
\item[\tt 0x01] {\it Illegal command}. This shouldn't happen.
\item[\tt 0x02] {\it Address mark not found}. This usually indicates
a media problem. Try again several times.
\item[\tt 0x03] {\it Write-protected disk}. This shouldn't happen.
\item[\tt 0x04] {\it Sector not found}. This typically indicates a
geometry mismatch. If you're booting a raw-written disk image, verify
whether it was created for disks with the same geometry as the one
you're using. If you're booting from a SCSI disk, you should check,
whether the contents of your {\tt /etc/lilo/disktab} file corresponds
to the real disk geometry. (See section \ref{disktab}.)
\item[\tt 0x06] {\it Change line active}. This should be a transient
error. Try booting a second time.
\item[\tt 0x08] {\it DMA overrun}. This shouldn't happen. Try booting
again.
\item[\tt 0x09] {\it DMA attempt across 64k boundary}. This shouldn't
happen. Try omitting the {\tt -c} option and report this problem to
the author.
\item[\tt 0x0C] {\it Invalid media}. This shouldn't happen and might
be caused by a media error. Try booting again.
\item[\tt 0x10] {\it CRC error}. A media error has been detected. Try
booting several times,
running the map installer a second time (to write ``good data'' over
the bad spot), mapping out the bad sectors/tracks and, if all else
fails, replacing the media.
\item[\tt 0x20] {\it Controller error}. This shouldn't happen.
\item[\tt 0x40] {\it Seek failure}. This might be a media problem. Try
booting again.
\item[\tt 0x80] {\it Disk timeout}. The disk or the drive isn't ready.
Either the media is bad or the disk isn't spinning. If you're booting
from a floppy, you might not have closed the drive door. Otherwise,
trying to boot again might help.
\end{description}
\end{document}
lilo/doc/bootloader.fig 644 0 0 2704 5252233107 13403 0 ustar root root #FIG 2.1
80 2
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
269 209 339 139 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
269 219 339 289 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
269 224 339 329 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
269 229 339 369 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 0 0
199 239 199 199 279 199 279 239 9999 9999
2 1 1 1 -1 0 0 0 4.000 7 0 0
339 314 419 314 9999 9999
2 1 1 1 -1 0 0 0 4.000 7 0 0
339 354 419 354 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
339 274 414 274 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
419 234 419 394 339 394 339 234 419 234 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
349 254 269 214 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
339 169 419 169 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
339 182 339 199 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
419 199 419 179 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 0 0
339 179 339 129 419 129 419 179 9999 9999
2 1 0 1 -1 0 0 0 0.000 7 0 0
199 239 279 239 9999 9999
4 0 5 10 0 -1 0 0.000 0 7 36 354 409 boot.b
4 0 1 10 0 -1 0 0.000 0 9 34 359 249 Primary
4 0 1 10 0 -1 0 0.000 0 7 47 354 264 boot loader
4 0 1 10 0 -1 0 0.000 0 7 47 354 344 boot loader
4 0 1 10 0 -1 0 0.000 0 9 41 354 329 Secondary
4 0 1 10 0 -1 0 0.000 0 7 47 209 219 Boot sector
4 0 5 10 0 -1 0 0.000 0 7 18 364 199 map
4 0 1 10 0 -1 0 0.000 0 9 25 359 144 Image
4 0 1 10 0 -1 0 0.000 0 9 46 349 159 descriptors
lilo/doc/image.fig 644 0 0 3016 5310554273 12335 0 ustar root root #FIG 2.1
80 2
6 414 139 494 379
2 1 0 1 -1 0 0 0 0.000 7 0 0
414 269 414 139 494 139 494 264 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
414 259 494 259 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
414 269 414 289 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
414 219 494 219 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
414 179 494 179 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 0 0
414 329 414 379 494 379 494 329 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
414 339 494 339 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
414 309 414 329 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
494 309 494 329 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
494 269 494 289 9999 9999
-6
2 1 1 1 -1 0 0 0 4.000 -1 0 0
299 259 379 259 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
379 299 379 219 299 219 299 299 379 299 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
369 289 414 349 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
359 254 319 264 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
299 199 299 179 239 179 239 199 299 199 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 0 1
0 0 1.000 4.000 8.000
299 229 269 199 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
369 234 414 204 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
368 242 413 227 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
369 224 414 164 9999 9999
4 0 1 10 0 -1 0 0.000 0 9 44 244 194 Descriptor
4 0 1 10 0 -1 0 0.000 0 9 50 309 319 Map section
4 0 1 10 0 -1 0 0.000 0 7 47 429 399 Traditional
4 0 1 10 0 -1 0 0.000 0 9 45 429 414 boot image
lilo/doc/map.fig 644 0 0 1651 5310554056 12032 0 ustar root root #FIG 2.1
80 2
2 1 1 1 -1 0 0 0 4.000 -1 0 0
459 159 539 159 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
539 199 459 199 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
459 239 539 239 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
539 279 459 279 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
459 319 539 319 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
514 274 484 284 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
539 359 539 79 459 79 459 359 539 359 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
459 119 539 119 9999 9999
4 0 1 10 0 -1 0 0.000 0 7 46 474 179 Zero sector
4 0 1 10 0 -1 0 0.000 0 7 21 484 214 First
4 0 1 10 0 -1 0 0.000 0 7 28 479 264 Second
4 0 1 10 0 -1 0 0.000 0 7 23 484 334 Third
4 0 1 10 0 -1 0 0.000 0 7 29 479 299 section
4 0 1 10 0 -1 0 0.000 0 7 29 479 229 section
4 0 1 10 0 -1 0 0.000 0 7 29 479 349 section
4 0 1 10 0 -1 0 0.000 0 9 25 484 109 Image
4 0 1 10 0 -1 0 0.000 0 9 46 474 139 descriptors
lilo/doc/other.fig 644 0 0 2551 5310555000 12364 0 ustar root root #FIG 2.1
80 2
6 414 99 494 139
2 2 0 1 -1 0 0 0 0.000 0 0 0
494 139 494 99 414 99 414 139 494 139 9999 9999
4 0 1 10 0 -1 0 0.000 0 9 35 434 114 Original
4 0 1 10 0 -1 0 0.000 0 9 60 424 129 partition table
-6
2 1 1 1 -1 0 0 0 4.000 -1 0 0
299 259 379 259 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
369 279 389 269 399 254 399 239 379 229 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
299 199 299 179 239 179 239 199 299 199 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
379 299 379 219 299 219 299 299 379 299 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
279 139 279 99 359 99 359 139 279 139 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 0 1
0 0 1.000 4.000 8.000
366 228 316 128 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
419 129 369 229 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
273 200 298 275 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
369 289 439 289 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
519 309 519 269 439 269 439 309 519 309 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 0 0
369 269 384 269 9999 9999
2 1 2 1 -1 0 0 0 3.000 -1 0 0
384 269 399 269 9999 9999
4 0 1 10 0 -1 0 0.000 0 9 44 244 194 Descriptor
4 0 1 10 0 -1 0 0.000 0 9 50 309 319 Map section
4 0 5 10 0 -1 0 0.000 0 7 42 294 119 chain.b
4 0 1 10 0 -1 0 0.000 0 7 52 309 244 Chain loader
4 0 1 10 0 -1 0 0.000 0 7 47 454 289 Boot sector
lilo/doc/unstripped.fig 644 0 0 4352 5310555312 13447 0 ustar root root #FIG 2.1
80 2
6 239 219 299 239
2 2 0 1 -1 0 0 0 0.000 0 0 0
299 239 299 219 239 219 239 239 299 239 9999 9999
4 0 1 10 0 -1 0 0.000 0 9 44 244 234 Descriptor
-6
6 434 259 514 499
2 1 0 1 -1 0 0 0 0.000 7 0 0
434 389 434 259 514 259 514 384 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
434 379 514 379 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
434 389 434 409 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
434 339 514 339 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
434 299 514 299 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 0 0
434 449 434 499 514 499 514 449 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
434 459 514 459 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
434 429 434 449 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
514 389 514 409 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
514 429 514 444 9999 9999
-6
6 409 99 489 219
2 2 0 1 -1 0 0 0 0.000 0 0 0
489 219 489 99 409 99 409 219 489 219 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
409 139 489 139 9999 9999
2 1 1 1 -1 0 0 0 4.000 -1 0 0
409 179 489 179 9999 9999
-6
2 1 1 1 -1 0 0 0 4.000 -1 0 0
299 299 379 299 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
359 294 319 304 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
269 239 299 269 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
379 339 379 259 299 259 299 339 379 339 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
374 264 409 124 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
374 269 409 164 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
374 274 409 204 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
374 279 434 264 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
374 284 434 304 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
374 289 434 349 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
374 304 434 484 9999 9999
2 2 0 1 -1 0 0 0 0.000 0 0 0
389 139 389 99 309 99 309 139 389 139 9999 9999
2 1 0 1 -1 0 0 0 0.000 -1 1 0
0 0 1.000 4.000 8.000
369 264 369 139 9999 9999
4 0 5 10 0 -1 0 0.000 0 9 42 424 234 setup.b
4 0 1 10 0 -1 0 0.000 0 9 50 309 354 Map section
4 0 1 10 0 -1 0 0.000 0 9 47 359 439 Unstripped
4 0 1 10 0 -1 0 0.000 0 9 52 359 454 kernel image
4 0 5 10 0 -1 0 0.000 0 7 42 304 159 bsect.b
lilo/doc/Makefile 644 0 0 352 5251030473 12177 0 ustar root root LATEX=latex
FIG2DEV=fig2dev
IMAGES=bootloader.tex map.tex image.tex unstripped.tex other.tex
.SUFFIXES: .fig .tex .dvi
.fig.tex:
$(FIG2DEV) -L latex $*.fig $*.tex
doc.dvi: doc.tex $(IMAGES)
$(LATEX) doc
again:
$(LATEX) doc
lilo/Makefile 644 0 0 5507 5310445653 11467 0 ustar root root CC=cc
CPP=$(CC) -E
AS86=as86 -0 -a
LD86=ld86 -0
CFLAGS=-Wall -g `if [ -f /usr/include/linux/genhd.h ]; then echo -DNEW_INCLUDES; fi`
LDFLAGS=
OBJS=lilo.o map.o geometry.o boot.o device.o common.o bsect.o cfg.o
.SUFFIXES: .img .b
all: lilo boot.b chain.b dparam.com activate # dos_d.b
.c.o:
$(CC) -c $(CFLAGS) $*.c
.s.o:
$(AS86) -w -o $*.o $*.s
.o.img:
$(LD86) -s -o $*.img $*.o
.img.b:
dd if=$*.img of=$*.b bs=32 skip=1
activate: activate.c
$(CC) -o activate activate.c $(LDFLAGS)
dparam.com: dparam.img
dd if=dparam.img of=dparam.com bs=288 skip=1
lilo: $(OBJS)
$(CC) -o lilo $(LDFLAGS) $(OBJS)
boot.b: first.b second.b
(dd if=first.b bs=512 conv=sync; dd if=second.b) >boot.b
first.s: first.S lilo.h lilo shared.S
$(CPP) `./lilo -X` first.S -o first.s
second.s: second.S lilo.h lilo shared.S
$(CPP) `./lilo -X` second.S -o second.s
chain.s: chain.S lilo.h first.lis
$(CPP) chain.S -o chain.s
dos_d.s: chain.S lilo.h
$(CPP) chain.S -DDOS_D -o dos_d.s \
-DGO=0x`sed '/go/s/^.*go 0 \(....\) A.*$$/\1/p;d' first.lis`
xxx.s: chain.S lilo.h
$(CPP) chain.S -DXXX -o xxx.s
first.o first.lis: first.s
$(AS86) -w -o first.o -l first.lis first.s
first.img: first.o
second.img: second.o
chain.img: chain.o
dos_d.img: dos_d.o
xxx.img: xxx.o
dparam.img: dparam.o
first.b: first.img
second.b: second.img
chain.b: chain.img
xxx.b: xxx.img
install: all
if [ ! -d /etc/lilo ]; then mkdir /etc/lilo; fi
if [ -f /etc/lilo/boot.b ]; then \
mv /etc/lilo/boot.b /etc/lilo/boot.old; fi
if [ -f /etc/lilo/chain.b ]; then \
mv /etc/lilo/chain.b /etc/lilo/chain.old; fi
# if [ -f /etc/lilo/xxx.b ]; then \
# mv /etc/lilo/xxx.b /etc/lilo/xxx.old; fi
# if [ -f /etc/lilo/dos_d.b ]; then \
# mv /etc/lilo/dos_d.b /etc/lilo/dos_d.old; fi
cp lilo boot.b chain.b /etc/lilo
# xxx.b dos_d.b
if [ ! -f /etc/lilo/disktab ]; then cp disktab /etc/lilo; fi
if [ -f /etc/lilo/install ]; then echo; \
echo "Please don't forget to run /etc/lilo/install to\\c"; \
echo " update boot sector and map file."; fi
dep:
sed '/\#\#\# Dependencies/q' tmp_make
$(CPP) -MM *.c >>tmp_make
# (for n in *.c; do $(CPP) -MM $$n; done) >>tmp_make
mv tmp_make Makefile
clean:
-rm *.o *.img *.lis first.s second.s chain.s dos_d.s tmp_make \
first.b second.b
spotless: clean
-rm lilo boot.b chain.b dos_d.b
### Dependencies
activate.o : activate.c
boot.o : boot.c common.h lilo.h geometry.h map.h boot.h
bsect.o : bsect.c config.h common.h lilo.h cfg.h device.h map.h geometry.h boot.h \
bsect.h
cfg.o : cfg.c common.h lilo.h cfg.h
common.o : common.c common.h lilo.h
device.o : device.c config.h common.h lilo.h device.h
geometry.o : geometry.c config.h lilo.h common.h device.h geometry.h
lilo.o : lilo.c config.h common.h lilo.h geometry.h bsect.h cfg.h
map.o : map.c lilo.h common.h geometry.h map.h
lilo/activate.c 644 0 0 2345 5245467340 11774 0 ustar root root #include
#include
#include
#include
#include
#define PART_BEGIN 0x1be
#define PART_NUM 4
#define PART_SIZE 16
#define PART_ACTIVE 0x80
#define PART_INACTIVE 0
static void die(char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
vfprintf(stderr,fmt,ap);
va_end(ap);
fprintf(stderr,"\n");
exit(1);
}
int main(int argc,char **argv)
{
struct stat st;
int fd,number,count;
unsigned char flag;
if (argc != 3) {
fprintf(stderr,"usage: %s device partition\n",argv[0]);
fprintf(stderr," i.e. %s /dev/hda 2\n",argv[0]);
exit(1);
}
number = atoi(argv[2]);
if (number < 1 || number > 4)
die("%s: not a valid partition number (1-4)",argv[2]);
if ((fd = open(argv[1],O_WRONLY)) < 0)
die("open %s: %s",argv[1],strerror(errno));
if (fstat(fd,&st) < 0) die("stat %s: %s",argv[1],strerror(errno));
if (!S_ISBLK(st.st_mode)) die("%s: not a block device",argv[1]);
for (count = 1; count <= PART_NUM; count++) {
if (lseek(fd,PART_BEGIN+(count-1)*PART_SIZE,0) < 0)
die("lseek: %s",strerror(errno));
flag = count == number ? PART_ACTIVE : PART_INACTIVE;
if (write(fd,&flag,1) != 1) die("write: %s",strerror(errno));
}
return 0;
}
lilo/boot.c 644 0 0 13444 5310545054 11151 0 ustar root root /* boot.c - Boot image composition */
/* Written 1992 by Werner Almesberger */
#include
#include
#include
#include
#include
#include
#include
#include
#include "config.h"
#include "common.h"
#include "geometry.h"
#include "map.h"
#include "boot.h"
static GEOMETRY geo;
static struct stat st;
static void check_size(char *name,int sectors)
{
if (sectors > SETUPSECS+MAX_KERNEL_SECS)
die("Kernel %s is too big",name);
}
void boot_image(char *spec,IMAGE_DESCR *descr)
{
BOOT_SECTOR buff;
int fd,sectors;
if (verbose > 0) printf("Boot image: %s\n",spec);
if (dump) printf("image = %s\n",spec);
fd = geo_open(&geo,spec,O_RDONLY);
map_begin_section();
if (fstat(fd,&st) < 0) die("fstat %s: 5s",spec,strerror(errno));
if (read(fd,(char *) &buff,SECTOR_SIZE) != SECTOR_SIZE)
die("read %s: %s",spec,strerror(errno));
if (buff.par_l.root_dev) descr->root_dev = buff.par_l.root_dev;
map_add(&geo,0,(st.st_size+SECTOR_SIZE-1)/SECTOR_SIZE);
check_size(spec,sectors = map_end_section(&descr->start));
geo_close(&geo);
if (verbose > 1)
printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s");
}
void boot_device(char *spec,char *range,IMAGE_DESCR *descr)
{
char *here;
int start,secs;
int sectors;
if (verbose > 0) printf("Boot device: %s, range %s\n",spec,range);
if (dump) printf("image = %s\n range = %s\n",spec,range);
(void) geo_open(&geo,spec,O_NOACCESS);
map_begin_section();
if (here = strchr(range,'-')) {
*here++ = 0;
start = to_number(range);
if ((secs = to_number(here)-start+1) < 0) die("Invalid range");
}
else {
if (here = strchr(range,'+')) {
*here++ = 0;
start = to_number(range);
secs = to_number(here);
}
else {
start = to_number(range);
secs = 1;
}
}
map_add(&geo,start,secs);
check_size(spec,sectors = map_end_section(&descr->start));
geo_close(&geo);
if (verbose > 1)
printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s");
}
void boot_unstripped(char *boot,char *setup,char *kernel,IMAGE_DESCR *descr)
{
struct exec exec;
int fd,sectors;
if (!setup) die("Please specify a setup file for %s",kernel);
if (verbose > 0)
printf("Unstripped: boot %s, setup %s,\n kernel %s\n",boot ? boot :
"(default)",setup,kernel);
if (dump) {
printf("unstripped = %s\n setup = %s\n",kernel,setup);
if (boot) printf(" boot = %s\n",boot);
}
map_begin_section();
if (!boot) map_add_zero();
else {
(void) geo_open(&geo,boot,O_RDONLY);
map_add(&geo,0,1);
geo_close(&geo);
}
(void) geo_open(&geo,setup,O_RDONLY);
map_add(&geo,0,SETUPSECS);
geo_close(&geo);
fd = geo_open(&geo,kernel,O_RDONLY);
if (read(fd,(char *) &exec,sizeof(struct exec)) != sizeof(struct exec))
die("read %s: %s",kernel,strerror(errno));
if (exec.a_entry || exec.a_trsize || exec.a_drsize || !exec.a_syms)
die("Not an unstripped kernel: %s",kernel);
map_add(&geo,2,(exec.a_text+exec.a_data+SECTOR_SIZE-1)/SECTOR_SIZE);
if ((exec.a_text+exec.a_data) & 15)
fprintf(stderr,"Warning: Unsupported BSS - no initialization.\n");
else {
if (verbose > 2)
printf("BSS: 0x%X+%d\n",exec.a_text+exec.a_data+DEF_SYSSEG,
exec.a_bss);
descr->bss_seg = ((exec.a_text+exec.a_data) >> 4)+DEF_SYSSEG;
descr->bss_segs = exec.a_bss >> 16;
descr->bss_words = ((exec.a_bss & 0xffff)+1) >> 1;
}
geo_close(&geo);
check_size(kernel,sectors = map_end_section(&descr->start));
if (verbose > 1)
printf("Mapped %d sector%s.\n",sectors,sectors == 1 ? "" : "s");
}
void boot_other(char *loader,char *boot,char *part,IMAGE_DESCR *descr)
{
int b_fd,l_fd,p_fd,walk,found,size;
unsigned short magic;
BOOT_SECTOR buff;
if (verbose > 0)
printf("Boot other: %s%s%s, loader %s\n",boot,part ? ", on " : "",part
? part : "",loader);
if (dump) {
printf("other = %s\n",boot);
if (loader) printf(" loader = %s\n",loader);
if (part) printf(" table = %s\n",part);
}
if (!loader) loader = DFL_CHAIN;
b_fd = geo_open(&geo,boot,O_RDONLY);
if (lseek(b_fd,(long) BOOT_SIG_OFFSET,0) < 0)
die("lseek %s: %s",boot,strerror(errno));
if ((size = read(b_fd,(char *) &magic,2)) != 2)
if (size < 0) die("read %s: %s",boot,strerror(errno));
else die("Can't get magic number of %s",boot);
if (magic != BOOT_SIGNATURE)
die("First sector of %s doesn't have a valid boot signature",boot);
if ((l_fd = open(loader,O_RDONLY)) < 0)
die("open %s: %s",loader,strerror(errno));
if (!part) memset(&buff,0,SECTOR_SIZE);
else {
if ((p_fd = open(part,O_RDONLY)) < 0)
die("open %s: %s",part,strerror(errno));
if (read(p_fd,(char *) &buff,SECTOR_SIZE) != SECTOR_SIZE)
die("read %s: %s",part,strerror(errno));
}
if ((size = read(l_fd,(char *) &buff,PART_TABLE_OFFSET+1)) < 0)
die("read %s: %s",loader,strerror(errno));
check_version(&buff,STAGE_CHAIN);
if (size > PART_TABLE_OFFSET)
die("Chain loader %s is too big",loader);
if (part) {
found = 0;
for (walk = 0; walk < PARTITION_ENTRIES; walk++)
if (!PART(buff,walk).sys_ind || PART(buff,walk).start_sect != geo.start) {
if (PART(buff,walk).sys_ind != PART_DOS12 && PART(buff,walk).
sys_ind != PART_DOS16) PART(buff,walk).sys_ind = PART_INVALID;
}
else {
if (found) die("Duplicate entry in partition table");
buff.par_c.offset = walk*PARTITION_ENTRY;
PART(buff,walk).boot_ind = 0x80;
found = 1;
}
if (!found) die("Partition entry not found.");
(void) close(p_fd);
}
(void) close(l_fd);
buff.par_c.drive = geo.device;
map_begin_section();
map_add_zero();
map_add_sector(&buff);
map_add(&geo,0,1);
(void) map_end_section(&descr->start);
geo_close(&geo);
if (verbose > 1) printf("Mapped 2 (1+1) sectors.\n");
}
lilo/boot.h 644 0 0 1376 5310234205 11130 0 ustar root root /* boot.h - Boot image composition */
/* Written 1992 by Werner Almesberger */
#ifndef _BOOT_H_
#define _BOOT_H_
#include "lilo.h"
void boot_image(char *spec,IMAGE_DESCR *descr);
/* Maps a "classic" boot image. */
void boot_device(char *spec,char *range,IMAGE_DESCR *descr);
/* Maps sectors from a device as the boot image. Can be used to boot raw-written
disks. */
void boot_unstripped(char *boot,char *setup,char *kernel,IMAGE_DESCR *descr);
/* Maps an unstripped kernel image as the boot image. The setup (without the
header) is prepended. */
void boot_other(char *loader,char *boot,char *part,IMAGE_DESCR *descr);
/* Merges a loader with a partition table and appends a boot sector. This mix
is used to boot non-Linux systems. */
#endif
lilo/bsect.c 644 0 0 22031 5310510614 11270 0 ustar root root /* bsect.c - Boot sector handling */
/* Written 1992 by Werner Almesberger */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "config.h"
#include "common.h"
#include "cfg.h"
#include "device.h"
#include "map.h"
#include "boot.h"
#include "bsect.h"
static BOOT_SECTOR bsect,bsect_orig;
static DESCR_SECTORS descrs;
static DEVICE dev;
static char *boot_devnam,*map_name;
static int fd,boot_dev_nr,image = 0;
static char temp_map[PATH_MAX+1];
void bsect_open(char *boot_dev,char *map_file,char *install,int delay)
{
GEOMETRY geo;
struct stat st;
int i_fd,sectors;
char *colon;
if (stat(map_file,&st) >= 0 && !S_ISREG(st.st_mode))
die("Map %s is not a regular file.",map_file);
if (verbose > 0)
printf("Reading boot sector from %s\n",boot_dev ? boot_dev :
"current root.");
if (boot_devnam = boot_dev) {
if ((fd = open(boot_dev,O_RDWR)) < 0)
die("open %s: %s",boot_dev,strerror(errno));
if (fstat(fd,&st) < 0) die("stat %s: %s",boot_dev,strerror(errno));
if (!S_ISBLK(st.st_mode)) boot_dev_nr = 0;
else boot_dev_nr = st.st_rdev;
}
else {
if (stat("/",&st) < 0) pdie("stat /");
if ((st.st_dev & PART_MASK) > PART_MAX)
die("Can't put the boot sector on logical partition 0x%X",
st.st_dev);
fd = dev_open(&dev,boot_dev_nr = st.st_dev,O_RDWR);
}
if (read(fd,(char *) &bsect,SECTOR_SIZE) != SECTOR_SIZE)
die("read %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));
memcpy(&bsect_orig,&bsect,SECTOR_SIZE);
if (install) {
if (verbose > 0) printf("Merging with %s\n",install);
i_fd = geo_open(&geo,install,O_RDONLY);
if (read(i_fd,(char *) &bsect,MAX_BOOT_SIZE) != MAX_BOOT_SIZE)
die("read %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));
if (fstat(i_fd,&st) < 0)
die("stat %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));
map_begin_section(); /* no access to the (not yet open) map file
required, because this map is built in memory */
map_add(&geo,1,(st.st_size+SECTOR_SIZE-1)/SECTOR_SIZE-1);
sectors = map_write(bsect.par_1.secondary,MAX_SECONDARY);
if (verbose > 1)
printf("Secondary loader: %d sector%s.\n",sectors,sectors == 1 ?
"" : "s");
geo_close(&geo);
}
check_version(&bsect,STAGE_FIRST);
if ((colon = strrchr(map_name = map_file,':')) == NULL)
strcat(strcpy(temp_map,map_name),MAP_TMP_APP);
else {
*colon = 0;
strcat(strcat(strcpy(temp_map,map_name),MAP_TMP_APP),colon+1);
*colon = ':';
}
map_create(temp_map);
*(unsigned short *) &bsect.sector[BOOT_SIG_OFFSET] = BOOT_SIGNATURE;
bsect.par_1.delay = delay*100/55;
memset(&descrs,0,SECTOR_SIZE);
}
static int bsect_dispatch(char *spec,IMAGE_DESCR *descr)
{
char *here,*this;
if (here = strchr(spec,'#')) {
*here++ = 0;
cfg_init(cf_image);
boot_device(spec,here,descr);
return 0;
}
if (here = strchr(spec,'@')) {
cfg_init(cf_other);
*here++ = 0;
if (this = strchr(spec,'+')) {
*this++ = 0;
boot_other(spec,this,*here ? here : NULL,descr);
return 1;
}
boot_other(NULL,spec,*here ? here : NULL,descr);
return 1;
}
if (here = strchr(spec,'+')) {
*here++ = 0;
cfg_init(cf_unstripped);
boot_unstripped(NULL,spec,here,descr);
return 0;
}
cfg_init(cf_image);
boot_image(spec,descr);
return 0;
}
static int dev_number(char *dev)
{
struct stat st;
if (stat(dev,&st) >= 0) return st.st_rdev;
return to_number(dev);
}
static void bsect_common(char *name)
{
IMAGE_DESCR *descr;
char *here,*vga,*label;
int other;
descr = &descrs.descr[image];
*descr->password = 0;
descr->present = 0;
if (cfg_get_strg(cf_common,"root")) {
descr->present |= OVR_ROOT;
descr->root_dev = dev_number(cfg_get_strg(cf_common,"root"));
if (dump) printf(" root = 0x%04x\n",descr->root_dev);
}
if (cfg_get_strg(cf_common,"ramdisk")) {
descr->present |= OVR_RAMD;
descr->ram_disk = to_number(cfg_get_strg(cf_common,"ramdisk"));
if (dump) printf(" ramdisk = %d\n",descr->ram_disk);
}
if (vga = cfg_get_strg(cf_common,"vga")) {
#ifndef NORMAL_VGA
die("VGA mode presetting is not supported by your kernel.");
#else
descr->present |= OVR_VGA;
if (!strcasecmp(vga,"normal")) descr->vga_mode = NORMAL_VGA;
else if (!strcasecmp(vga,"extended")) descr->vga_mode = EXTENDED_VGA;
else if (!strcasecmp(vga,"ask")) descr->vga_mode = ASK_VGA;
else descr->vga_mode = to_number(vga);
#endif
if (dump) printf(" vga = %s\n",vga);
}
if (label = cfg_get_strg(cf_common,"label")) {
if (dump) printf(" label = %s\n",label);
}
else if (here = strrchr(label = name,'/')) label = here+1;
if (strlen(label) > MAX_IMAGE_NAME) die("Label \"%s\" is too long",label);
for (other = 0; other < image; other++)
if (!strcmp(descrs.descr[other].name,label))
die("Duplicate label \"%s\"",label);
strcpy(descr->name,label);
if (verbose >= 0) printf("Added %s\n",label);
if (verbose > 1) {
printf("%4s",
"",descrs.descr[image].start.device,descrs.descr[image].start.head,
descrs.descr[image].start.track,descrs.descr[image].start.sector);
if (descrs.descr[image].present & OVR_ROOT)
printf(",root=0x%04x",descrs.descr[image].root_dev);
printf("\n");
}
image++;
}
void bsect_image(char *spec)
{
IMAGE_DESCR *descr;
struct stat st;
char *here,*this,*label;
char root_number[20];
descr = &descrs.descr[image];
descr->bss_seg = 0;
descr->root_dev = 0;
if (here = strrchr(spec,',')) *here++ = 0;
if (!(this = strchr(label = spec,'='))) label = NULL;
else {
*this++ = 0;
spec = this;
}
if (bsect_dispatch(spec,descr)) cfg_init(cf_common);
else if (here || !descr->root_dev) {
if (stat("/",&st) < 0) pdie("stat /");
if (!descr->root_dev) descr->root_dev = st.st_dev;
if (here) descr->root_dev = dev_number(here);
sprintf(root_number,"0x%04x",descr->root_dev);
cfg_set(cf_common,"root",root_number);
}
if (label) cfg_set(cf_common,"label",label);
bsect_common(spec);
}
static void unbootable(void)
{
fprintf(stderr,"\nWARNING: The system is unbootable !\n");
fprintf(stderr,"%9sRun LILO again to correct this.","");
exit(1);
}
void bsect_update(char *backup_file,int force_backup)
{
char temp_name[PATH_MAX+1];
int bck_file;
if (backup_file == NULL) {
sprintf(temp_name,LILO_DIR "/boot.%04X",boot_dev_nr);
backup_file = temp_name;
}
bck_file = open(backup_file,O_RDONLY);
if (bck_file >= 0 && force_backup) {
(void) close(bck_file);
bck_file = -1;
}
if (bck_file >= 0) {
if (verbose > 0)
printf("%s exists - no backup copy made.\n",backup_file);
}
else {
if ((bck_file = creat(backup_file,0644)) < 0)
die("creat %s: %s",backup_file,strerror(errno));
if (write(bck_file,(char *) &bsect_orig,SECTOR_SIZE) != SECTOR_SIZE)
die("write %s: %s",backup_file,strerror(errno));
if (verbose > 0)
printf("Backup copy of boot sector in %s\n",backup_file);
}
if (close(bck_file) < 0) die("close %s: %s",backup_file,strerror(errno));
map_done(&descrs,bsect.par_1.descr);
if (lseek(fd,0,0) < 0)
die("lseek %s: %s",boot_devnam ? boot_devnam : dev.name,
strerror(errno));
if (verbose > 0) printf("Writing boot sector.\n");
if (write(fd,(char *) &bsect,SECTOR_SIZE) != SECTOR_SIZE)
die("write %s: %s",boot_devnam ? boot_devnam : dev.name,
strerror(errno));
if (boot_devnam == NULL) dev_close(&dev);
else if (close(fd) < 0) {
unbootable();
die("close %s: %s",boot_devnam,strerror(errno));
}
if (rename(temp_map,map_name) < 0) {
unbootable();
die("rename %s %s: %s",temp_map,map_name,strerror(errno));
}
(void) sync();
}
void bsect_cancel(void)
{
map_done(&descrs,bsect.par_1.descr);
if (boot_devnam) (void) close(fd);
else dev_close(&dev);
(void) remove(temp_map);
}
void do_image(void)
{
IMAGE_DESCR *descr;
char *name;
(descr = &descrs.descr[image])->bss_seg = 0;
cfg_init(cf_image);
(void) cfg_parse(cf_image);
if (!cfg_get_strg(cf_image,"range"))
boot_image(name = cfg_get_strg(cf_top,"image"),descr);
else boot_device(cfg_get_strg(cf_top,"image"),cfg_get_strg(cf_image,
"range"),descr);
bsect_common(name);
cfg_init(cf_top);
}
void do_unstripped(void)
{
IMAGE_DESCR *descr;
char *name;
descr = &descrs.descr[image];
cfg_init(cf_unstripped);
(void) cfg_parse(cf_unstripped);
boot_unstripped(cfg_get_strg(cf_unstripped,"boot"),cfg_get_strg(
cf_unstripped,"setup"),name = cfg_get_strg(cf_top,"unstripped"),descr);
bsect_common(name);
cfg_init(cf_top);
}
void do_other(void)
{
IMAGE_DESCR *descr;
char *name;
(descr = &descrs.descr[image])->bss_seg = 0;
cfg_init(cf_other);
cfg_init(cf_common); /* clear kernel parameters */
(void) cfg_parse(cf_other);
boot_other(cfg_get_strg(cf_other,"loader"),name = cfg_get_strg(cf_top,
"other"),cfg_get_strg(cf_other,"table"),descr);
bsect_common(name);
cfg_init(cf_top);
}
lilo/bsect.h 644 0 0 1355 5310232231 11257 0 ustar root root /* bsect.h - Boot sector handling */
/* Written 1992 by Werner Almesberger */
#ifndef _BSECT_H_
#define _BSECT_H_
void bsect_open(char *boot_dev,char *map_file,char *install,int delay);
/* Loads the boot sector of the specified device and merges it with a new
boot sector (if install != NULL). Sets the boot delay to 'delay' 1/10 sec.
Creates a temporary map file. */
void bsect_image(char *spec);
/* Adds a new boot image. */
void bsect_update(char *backup_file,int force_backup);
/* Updates the boot sector and the map file. */
void bsect_cancel(void);
/* Cancels all changes. (Deletes the temporary map file and doesn't update
the boot sector. */
void do_image(void);
void do_unstripped(void);
void do_other(void);
#endif
lilo/cfg.c 644 0 0 14337 5310534141 10742 0 ustar root root /* cfg.c - Configuration file parser */
/* Written 1992 by Werner Almesberger */
#include
#include
#include
#include
#include "common.h"
#include "cfg.h"
#define MAX_TOKEN 200
extern void do_image(void);
extern void do_unstripped(void);
extern void do_other(void);
CONFIG cf_top[] = {
{ cft_strg, "image", do_image, NULL },
{ cft_strg, "unstripped", do_unstripped, NULL },
{ cft_strg, "other", do_other, NULL },
{ cft_end, NULL, NULL, NULL }};
CONFIG cf_options[] = {
{ cft_strg, "boot", NULL, NULL },
{ cft_flag, "compact", NULL, NULL },
{ cft_strg, "delay", NULL, NULL },
{ cft_flag, "linear", NULL, NULL },
{ cft_strg, "install", NULL, NULL },
{ cft_strg, "disktab", NULL, NULL },
{ cft_strg, "map", NULL, NULL },
{ cft_strg, "verbose", NULL, NULL },
{ cft_strg, "backup", NULL, NULL },
{ cft_strg, "force-backup", NULL, NULL },
{ cft_end, NULL, NULL, NULL }};
static CONFIG cf_label[] = {
{ cft_strg, "label", NULL, NULL },
{ cft_end, NULL, NULL, NULL }};
CONFIG cf_common[] = {
{ cft_strg, "root", NULL, NULL },
{ cft_strg, "vga", NULL, NULL },
{ cft_strg, "ramdisk", NULL, NULL },
{ cft_link, NULL, &cf_label, NULL }};
CONFIG cf_image[] = {
{ cft_strg, "range", NULL, NULL },
{ cft_link, NULL, &cf_common, NULL }};
CONFIG cf_unstripped[] = {
{ cft_strg, "boot", NULL, NULL },
{ cft_strg, "setup", NULL, NULL },
{ cft_link, NULL, &cf_common, NULL }};
CONFIG cf_other[] = {
{ cft_strg, "loader", NULL, NULL },
{ cft_strg, "table", NULL, NULL },
{ cft_link, NULL, &cf_label, NULL }};
static FILE *file;
static char flag_set;
static char *last_token = NULL,*last_item = NULL,*last_value = NULL;
static int line_num;
static char *file_name = NULL;
void cfg_open(char *name)
{
if (!(file = fopen(file_name = name,"r"))) pdie(name);
line_num = 1;
}
void cfg_error(char *msg,...)
{
va_list ap;
va_start(ap,msg);
vfprintf(stderr,msg,ap);
va_end(ap);
if (!file_name) fputc('\n',stderr);
else fprintf(stderr," near line %d in file %s\n",line_num,file_name);
exit(1);
}
static char *cfg_get_token(void)
{
char buf[MAX_TOKEN+1];
char *here;
int ch,escaped;
if (last_token) {
here = last_token;
last_token = NULL;
return here;
}
while (1) {
while (ch = getc(file), ch == ' ' || ch == '\t' || ch == '\n')
if (ch == '\n') line_num++;
if (ch == EOF) return NULL;
if (ch != '#') break;
else {
while (ch = getc(file), ch != '\n')
if (ch == EOF) return NULL;
line_num++;
}
}
if (ch == '=') return stralloc("=");
here = buf;
escaped = 0;
while (here-buf < MAX_TOKEN) {
if (escaped) {
if (ch == EOF) cfg_error("\\ precedes EOF");
if (ch == '\n') line_num++;
else *here++ = ch == '\t' ? ' ' : ch;
escaped = 0;
}
else {
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#' ||
ch == '=' || ch == EOF) {
ungetc(ch,file);
*here = 0;
return stralloc(buf);
}
if (!(escaped = (ch == '\\'))) *here++ = ch;
}
ch = getc(file);
}
cfg_error("Token is too long");
return 0; /* not reached */
}
static void cfg_return_token(char *token)
{
last_token = token;
}
static int cfg_next(char **item,char **value)
{
char *this;
if (last_item) {
*item = last_item;
*value = last_value;
last_item = NULL;
return 1;
}
*value = NULL;
if (!(*item = cfg_get_token())) return 0;
if (!strcmp(*item,"=")) cfg_error("Syntax error");
if (!(this = cfg_get_token())) return 1;
if (strcmp(this,"=")) {
cfg_return_token(this);
return 1;
}
if (!(*value = cfg_get_token())) cfg_error("Value expected at EOF");
if (!strcmp(*value,"=")) cfg_error("Syntax error after %s",*item);
return 1;
}
static void cfg_return(char *item,char *value)
{
last_item = item;
last_value = value;
}
void cfg_init(CONFIG *table)
{
while (table->type != cft_end) {
switch (table->type) {
case cft_strg:
if (table->data) free(table->data);
case cft_flag:
table->data = NULL;
break;
case cft_link:
table = ((CONFIG *) table->action)-1;
break;
default:
die("Unknown syntax code %d",table->type);
}
table++;
}
}
static int cfg_do_set(CONFIG *table,char *item,char *value,int copy)
{
CONFIG *walk;
for (walk = table; walk->type != cft_end; walk++) {
if (walk->name && !strcasecmp(walk->name,item)) {
if (value && walk->type != cft_strg)
cfg_error("'%s' doesn't have a value",walk->name);
if (!value && walk->type == cft_strg)
cfg_error("Value expected for '%s'",walk->name);
if (walk->data) cfg_error("Duplicate entry '%s'",walk->name);
if (walk->type == cft_flag) walk->data = &flag_set;
else if (walk->type == cft_strg)
if (copy) walk->data = stralloc(value);
else walk->data = value;
if (walk->action) ((void (*)(void)) walk->action)();
break;
}
if (walk->type == cft_link) walk = ((CONFIG *) walk->action)-1;
}
if (walk->type != cft_end) return 1;
cfg_return(item,value);
return 0;
}
void cfg_set(CONFIG *table,char *item,char *value)
{
if (!cfg_do_set(table,item,value,1))
cfg_error("cfg_set: Can't set %s",item);
}
int cfg_parse(CONFIG *table)
{
char *item,*value;
while (1) {
if (!cfg_next(&item,&value)) return 0;
if (!cfg_do_set(table,item,value,0)) return 1;
free(item);
}
}
int cfg_get_flag(CONFIG *table,char *item)
{
CONFIG *walk;
for (walk = table; walk->type != cft_end; walk++) {
if (walk->name && !strcasecmp(walk->name,item)) {
if (walk->type != cft_flag)
die("cfg_get_flag: operating on non-flag %s",item);
return !!walk->data;
}
if (walk->type == cft_link) walk = ((CONFIG *) walk->action)-1;
}
die("cfg_get_flag: unknown item %s",item);
return 0; /* not reached */
}
char *cfg_get_strg(CONFIG *table,char *item)
{
CONFIG *walk;
for (walk = table; walk->type != cft_end; walk++) {
if (walk->name && !strcasecmp(walk->name,item)) {
if (walk->type != cft_strg)
die("cfg_get_strg: operating on non-string %s",item);
return walk->data;
}
if (walk->type == cft_link) walk = ((CONFIG *) walk->action)-1;
}
die("cfg_get_strg: unknown item %s",item);
return 0; /* not reached */
}
lilo/cfg.h 644 0 0 1206 5310423634 10722 0 ustar root root /* cfg.h - Configuration file parser */
/* Written 1992 by Werner Almesberger */
#ifndef _CFG_H_
#define _CFG_H_
typedef enum { cft_strg,cft_flag,cft_link,cft_end } CONFIG_TYPE;
typedef struct {
CONFIG_TYPE type;
char *name;
void *action;
void *data;
} CONFIG;
extern CONFIG cf_top[],cf_options[],cf_common[],cf_image[],cf_unstripped[],
cf_other[];
void cfg_open(char *name);
void cfg_error(char *msg,...);
void cfg_init(CONFIG *table);
void cfg_set(CONFIG *table,char *item,char *value);
int cfg_parse(CONFIG *table);
int cfg_get_flag(CONFIG *table,char *item);
char *cfg_get_strg(CONFIG *table,char *item);
#endif
lilo/chain.S 644 0 0 3330 5310264133 11215 0 ustar root root /* chain.S - LILO boot chainer */
/* Written 1992 by Werner Almesberger */
#include
#define LILO_ASM
#include "lilo.h"
.text
.globl _main
.org 0
_main: jmp start
.org 2
.ascii "LILO"
.word STAGE_CHAIN
.word VERSION
offset: .word 0
drive: .byte 0
.byte 0 ! head, always zero
start: cli ! set SS:SP to 0:7C00
xor ax,ax
mov ss,ax
mov ax,#0x7c00
mov sp,ax
sti
mov ax,#SETUPSEG ! move boot sector to default location
mov ds,ax
xor ax,ax
mov es,ax
mov cx,#256
mov si,#512
mov di,#BOOTSEG*16
rep
movsw
#ifdef DOS_D
seg es
cmp byte ptr BOOTSEG*16+0x26,#0x29
je dos4
mov bx,#baddos ! complain
call say
mov ax,#FIRSTSEG ! restart LILO
jmpi #GO,FIRSTSEG
dos4: seg es
mov byte ptr BOOTSEG*16+0x24,#0x81
#if 0
mov bx,#rdy
call say
mov ah,#0
int 0x16
#endif
#endif
mov cx,#0x20 ! move partition table
mov si,#PART_TABLE_OFFSET
mov di,#PART_TABLE
rep
movsw
mov si,offset ! DS:SI and ES:SI point to the partition
! table entry
add si,#PART_TABLE
mov dx,drive ! initialize DX (drive and head)
xor ax,ax ! set DS and ES to zero
#ifdef XXX
mov ax,ds
mov es,ax
mov si,#lilosig
mov bx,#cmd
mov dl,#0xfe
#else
mov ds,ax
#endif
mov ax,#0xaa55 ! boot signature (just in case ...)
jmpi #BOOTSEG*16,0 ! start boot sector
#ifdef XXX
lilosig:.ascii "LILO"
cmd: .ascii "98"
.byte 0
#endif
#ifdef DOS_D
! Display a NUL-terminated string on the console
say: mov al,(bx) ! get byte
or al,al ! NUL ?
jz aret ! yes -> done
push bx ! save pointer
mov ah,#14 ! display, tty-style
xor bh,bh
int 0x10
pop bx
inc bx ! next one
jmp say
aret: ret ! done
baddos: .ascii "Need DOS version 4 or newer."
.byte 13,10,0
#if 0
rdy: .ascii "RDY"
.byte 13,10,0
#endif
#endif
lilo/common.c 644 0 0 3154 5310223020 11435 0 ustar root root /* common.c - Common data structures and functions. */
/* Written 1992 by Werner Almesberger */
#include
#include
#include
#include
#include
#include "common.h"
#include "lilo.h"
int verbose = 0,compact = 0,linear = 0,dump = 0;
void pdie(char *msg)
{
perror(msg);
exit(1);
}
void die(char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
vfprintf(stderr,fmt,ap);
va_end(ap);
fputc('\n',stderr);
exit(1);
}
void *alloc(int size)
{
void *this;
if ((this = malloc(size)) == NULL) pdie("Out of memory");
return this;
}
char *stralloc(char *str)
{
char *this;
if ((this = strdup(str)) == NULL) pdie("Out of memory");
return this;
}
int to_number(char *num)
{
int number;
char *end;
number = strtol(num,&end,0);
if (end && *end) die("Not a number: \"%s\"",num);
return number;
}
static char *name(int stage)
{
switch (stage) {
case STAGE_FIRST:
return "First boot sector";
case STAGE_SECOND:
return "Second boot sector";
case STAGE_CHAIN:
return "Chain loader";
default:
die("Internal error: Unknown stage code %d",stage);
}
return NULL; /* makes GCC happy */
}
void check_version(BOOT_SECTOR *sect,int stage)
{
if (strncmp(sect->par_1.signature,"LILO",4))
die("%s doesn't have a valid LILO signature",name(stage));
if (sect->par_1.stage != stage)
die("%s has an invalid stage code (%d)",name(stage),sect->par_1.stage);
if (sect->par_1.version != VERSION)
die("%s is version %d. Expecting version %d.",name(stage),
sect->par_1.version,VERSION);
}
lilo/common.h 644 0 0 5236 5310474531 11464 0 ustar root root /* common.h - Common data structures and functions. */
/* Written 1992 by Werner Almesberger */
#ifndef _COMMON_H_
#define _COMMON_H_
#ifdef NEW_INCLUDES
#include
#else
#include
#endif
#include "lilo.h"
#define O_NOACCESS 3 /* open a file for "no access" */
typedef struct {
unsigned char sector,track; /* CX */
unsigned char device,head; /* DX */
unsigned char num_sect; /* AL */
} SECTOR_ADDR;
typedef struct {
char name[MAX_IMAGE_NAME+1];
char password[MAX_PW+1]; /* not yet used */
SECTOR_ADDR start;
unsigned short present; /* parameter bit map */
unsigned short ram_disk,vga_mode,root_dev; /* copied from image */
unsigned short bss_seg,bss_segs,bss_words;
/* BSS := bss_seg:0 to (bss_seg+bss_segs-1):(bss_words*2)
bss_seg == 0: no initialization */
} IMAGE_DESCR;
typedef struct {
char jump[2]; /* jump over the data */
char signature[4]; /* "LILO" */
unsigned short stage,version;
unsigned short delay,filler; /* delay: wait that many 54 msec units */
SECTOR_ADDR descr[2];
SECTOR_ADDR secondary[MAX_SECONDARY+1];
} BOOT_PARAMS_1; /* first stage boot loader */
typedef struct {
char jump[2]; /* jump over the data */
char signature[4]; /* "LILO" */
unsigned short stage,version;
} BOOT_PARAMS_2; /* second stage boot loader */
typedef struct {
char dummy[502];
unsigned short ram_disk,vga_mode,root_dev;
} BOOT_PARAMS_L; /* setup information in boot sector */
typedef struct {
char jump[2]; /* jump over the data */
char signature[4]; /* "LILO" */
unsigned short stage,version; /* stage is 0x10 */
unsigned short offset; /* partition entry offset */
unsigned char drive; /* BIOS drive code */
} BOOT_PARAMS_C; /* chain loader */
#define PART(s,n) (((struct partition *) ((char *) &(s)+PART_TABLE_OFFSET)) \
[(n)])
typedef union {
BOOT_PARAMS_1 par_1;
BOOT_PARAMS_2 par_2;
BOOT_PARAMS_L par_l;
BOOT_PARAMS_C par_c;
unsigned char sector[SECTOR_SIZE];
} BOOT_SECTOR;
typedef union {
IMAGE_DESCR descr[MAX_IMAGES]; /* boot file descriptors */
unsigned char sector[SECTOR_SIZE*2];
} DESCR_SECTORS;
extern int verbose,compact,linear,dump;
void pdie(char *msg);
/* Do a perror and then exit. */
void die(char *fmt,...);
/* fprintf an error message and then exit. */
void *alloc(int size);
/* Allocates the specified number of bytes. */
char *stralloc(char *str);
/* Like strdup, but dies on error. */
int to_number(char *num);
/* Converts a string to a number. Dies if the number is invalid. */
void check_version(BOOT_SECTOR *sect,int stage);
/* Verify that a boot sector has the correct version number. */
#endif
lilo/config.h 644 0 0 1226 5271055413 11434 0 ustar root root /* config.h - Configurable parameters */
/* Written 1992 by Werner Almesberger */
#ifndef _CONFIG_H_
#define _CONFIG_H_
#define TMP_DEV "/tmp/dev.%d" /* temporary devices are created here */
#define MAX_TMP_DEV 50 /* highest temp. device number */
#define LILO_DIR "/etc/lilo" /* base directory for LILO files */
#define DFL_DISKTAB LILO_DIR "/disktab" /* LILO's disk parameter table */
#define MAP_FILE LILO_DIR "/map" /* default map file */
#define MAP_TMP_APP "~" /* temporary file appendix */
#define DFL_CHAIN LILO_DIR "/chain.b" /* default chain loader */
#define MAX_LINE 1024 /* maximum disk parameter table line length */
#endif
lilo/device.c 644 0 0 3011 5233077165 11421 0 ustar root root /* device.c - Device access */
/* Written 1992 by Werner Almesberger */
#include
#include
#include
#include
#include
#include
#include
#include
#include "config.h"
#include "common.h"
#include "device.h"
int dev_open(DEVICE *dev,int number,int flags)
{
DIR *dp;
struct dirent *dir;
char name[PATH_MAX+1];
int count;
if ((dp = opendir("/dev")) == NULL) pdie("opendir /dev");
strcpy(name,"/dev/");
while (dir = readdir(dp)) {
strcpy(name+5,dir->d_name);
if (stat(name,&dev->st) < 0) die("stat %s: %s",name,strerror(errno));
if ((dev->st.st_mode & S_IFMT) == S_IFBLK && dev->st.st_rdev == number)
break;
}
if (dev->delete = !dir) {
for (count = 0; count <= MAX_TMP_DEV; count++) {
sprintf(name,TMP_DEV,count);
if (stat(name,&dev->st) < 0) break;
}
if (count > MAX_TMP_DEV) die("Failed to create a temporary device");
if (mknod(name,0600 | S_IFBLK,number) < 0)
die("mknod %s: %s",name,strerror(errno));
if (fstat(dev->fd,&dev->st) < 0)
die("fstat %s: %s",name,strerror(errno));
if (verbose > 1)
printf("Created temporary device %s (0x%4X)\n",name,number);
}
if ((dev->fd = open(name,flags)) < 0)
die("open %s: %s",name,strerror(errno));
dev->name = stralloc(name);
return dev->fd;
}
void dev_close(DEVICE *dev)
{
if (close(dev->fd) < 0) die("close %s: %s",dev->name,strerror(errno));
if (dev->delete) (void) remove(dev->name);
free(dev->name);
}
lilo/device.h 644 0 0 1226 5233077161 11430 0 ustar root root /* device.h - Device access */
/* Written 1992 by Werner Almesberger */
#ifndef _DEVICE_H_
#define _DEVICE_H_
#include
typedef struct {
int fd;
struct stat st;
char *name;
int delete;
} DEVICE;
int dev_open(DEVICE *dev,int number,int flags);
/* Searches /dev for a block device with the specified number. If no device
can be found, a temporary device is created. The device is opened with
the specified access mode and the file descriptor is returned. */
void dev_close(DEVICE *dev);
/* Closes a device that has previously been opened by dev_open. If the device
had to be created, it is removed now. */
#endif
lilo/first.S 644 0 0 3640 5310473442 11273 0 ustar root root /* first.S - LILO first stage boot loader */
/* Written 1992 by Werner Almesberger */
#include
#define LILO_ASM
#include "lilo.h"
.text
.globl _main
.org 0
_main: jmp start
.org 2
! Boot device parameters. They are set by the installer.
.ascii "LILO"
.word STAGE_FIRST
.word VERSION
delay: .word 0 ! boot delay
filler: .word 0 ! (unused)
d1_cx: .word 0 ! first descriptor sector address
d1_dx: .word 0
d1_al: .byte 0 ! (unused)
d2_cx: .word 0 ! second descriptor sector address
d2_dx: .word 0
d2_al: .byte 0 ! (unused)
d_addr: ! second stage sector addresses
.org CODE_START_1
ext_si: .word 0 ! external interface
ext_es: .word 0
ext_bx: .word 0
ext_dl: .byte 0
start: mov ax,#BOOTSEG ! set DS
mov ds,ax
mov ext_es,es ! copy possible external parameters
mov ext_si,si
mov ext_bx,bx
mov ext_dl,dl
mov ax,#FIRSTSEG ! beam us up ...
mov es,ax
mov cx,#256
sub si,si
sub di,di
cld
rep
movsw
jmpi go,FIRSTSEG
go: cli ! no interrupts
mov ds,ax ! AX is already set
mov es,ax ! (ES may be wrong when restarting)
mov sp,#STACK ! set the stack
mov ax,#STACKSEG
mov ss,ax
sti ! now it is safe
mov al,#0x0d ! gimme a CR ...
call display
mov al,#0x0a ! ... an LF ...
call display
mov al,#0x4c ! ... an 'L' ...
call display
lagain: mov si,#d_addr ! ready to load the second stage loader
mov bx,#SECOND
cld
sload: lodsw ! get CX
mov cx,ax
lodsw ! get DX
mov dx,ax
or ax,cx ! at EOF ?
jz done ! yes -> start it
inc si ! skip the length byte
mov al,#1 ! load the sector
call cread
jc error ! error -> start over again
add bx,#512 ! next sector
jmp sload
error: xor ax,ax ! reset the FDC
mov dl,al
int 0x13
jmp lagain ! redo from start
done: mov al,#0x49 ! display an 'I'
call display
jmpi 0,SECONDSEG ! start the second stage loader
#include "shared.S"
/* Here are at least 64 bytes of free space. This is reserved for the
partition table. */
lilo/geometry.c 644 0 0 14502 5310511251 12025 0 ustar root root /* geometry.c - Device and file geometry computation */
/* Written 1992 by Werner Almesberger */
#ifdef NEW_INCLUDES
#include
#define _LIMITS_H
#endif
#include
#include
#include
#include
#include
/* resolve current types.h conflict */
#ifdef _SYS_TYPES_H
#define _LINUX_TYPES_H
#endif
/* resolve possible future conflicts when implicitly including sched.h */
#ifdef _SIGNAL_H
#define _LINUX_SIGNAL_H
#endif
#ifdef _SYS_TIME_H
#define _LINUX_TIME_H
#endif
#ifdef _SYS_RESOURCE_H
#define _LINUX_RESOURCE_H
#endif
#include
#include
#include
#include "config.h"
#include "lilo.h"
#include "common.h"
#include "device.h"
#include "geometry.h"
typedef struct _dt_entry {
int device,bios;
int sectors,heads,cylinders,start;
struct _dt_entry *next;
} DT_ENTRY;
static DT_ENTRY *disktab = NULL;
void geo_init(char *name)
{
FILE *file;
char line[MAX_LINE+1];
char *here;
DT_ENTRY *entry;
if (name) {
if ((file = fopen(name,"r")) == NULL)
die("open %s: %s",name,strerror(errno));
}
else if ((file = fopen(DFL_DISKTAB,"r")) == NULL) return;
while (fgets(line,MAX_LINE,file)) {
if (here = strchr(line,'\n')) *here = 0;
if (here = strchr(line,'#')) *here = 0;
if (strspn(line," \t") != strlen(line)) {
entry = alloc(sizeof(DT_ENTRY));
if (sscanf(line,"0x%x 0x%x %d %d %d %d",&entry->device,&entry->bios,
&entry->sectors,&entry->heads,&entry->cylinders,&entry->start)
!= 6)
die("Invalid line in %s:\n\"%s\"",name ? name : DFL_DISKTAB,
line);
entry->next = disktab;
disktab = entry;
}
}
(void) fclose(file);
}
static int count_devs(char *prefix,char *letters)
{
char name[PATH_MAX+1];
int count,fd;
char buff;
count = 0;
while (*letters) {
sprintf(name,"%s%c",prefix,*letters++);
if ((fd = open(name,O_RDONLY)) < 0) break;
if (read(fd,&buff,1) == 0) {
(void) close(fd);
break;
}
(void) close(fd);
count++;
}
if (verbose > 2) printf("Found %d %s device(s)\n",count,prefix);
return count;
}
static void geo_query_dev(GEOMETRY *geo,int device)
{
DEVICE dev;
int fd;
struct floppy_struct fdprm;
struct hd_geometry hdprm;
fd = dev_open(&dev,device,O_NOACCESS);
switch (MAJOR(device)) {
case 2:
if (ioctl(fd,FDGETPRM,&fdprm) < 0)
pdie("geo_query_dev FDGETPRM");
geo->device = device & 3;
geo->heads = fdprm.head;
geo->cylinders = fdprm.track;
geo->sectors = fdprm.sect;
geo->start = 0;
break;
case 3:
if (ioctl(fd,HDIO_REQ,&hdprm) < 0)
pdie("geo_query_dev HDIO_REQ");
geo->device = 0x80 | ((device & 255) >> 6);
geo->heads = hdprm.heads;
geo->cylinders = hdprm.cylinders;
geo->sectors = hdprm.sectors;
geo->start = hdprm.start;
break;
case 8:
if (ioctl(fd,HDIO_REQ,&hdprm) < 0)
pdie("geo_query_dev HDIO_REQ");
geo->device = 0x80+count_devs("/dev/hd","ab");
geo->heads = hdprm.heads;
geo->cylinders = 1024; /* broken in 0.98pl6 */
geo->sectors = hdprm.sectors;
geo->start = hdprm.start;
break;
default:
die("Sorry, don't know how to handle device 0x%04x",device);
}
dev_close(&dev);
}
static void geo_get(GEOMETRY *geo,int device,int user_device)
{
DT_ENTRY *walk;
for (walk = disktab; walk; walk = walk->next)
if (walk->device == device) break;
if (walk == NULL) geo_query_dev(geo,device);
else {
geo->device = walk->bios;
geo->heads = walk->heads;
geo->cylinders = walk->cylinders;
geo->sectors = walk->sectors;
geo->start = walk->start;
}
if (user_device != -1) geo->device = user_device;
if (verbose > 2) {
printf("Device 0x%04x: BIOS drive 0x%02x, %d heads, %d cylinders,\n",
device,geo->device,geo->heads,geo->cylinders);
printf("%15s%d sectors. Partition offset: %d sectors.\n","",
geo->sectors,geo->start);
}
}
int geo_open(GEOMETRY *geo,char *name,int flags)
{
char *here;
int user_dev,block_size;
struct stat st;
if ((here = strrchr(name,':')) == NULL) user_dev = -1;
else {
fprintf(stderr,":BIOS syntax is no longer supported. Please use "
"/etc/lilo/disktab\n");
*here++ = 0;
user_dev = to_number(here);
}
if ((geo->fd = open(name,flags)) < 0)
die("open %s: %s",name,strerror(errno));
if (fstat(geo->fd,&st) < 0) die("fstat %s: %s",name,strerror(errno));
if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
die("%s: neither a reg. file nor a block dev.",name);
geo_get(geo,S_ISREG(st.st_mode) ? st.st_dev : st.st_rdev,user_dev);
geo->file = S_ISREG(st.st_mode);
#ifndef FIGETBSZ
geo->spb = 2;
#else
if (!geo->file) geo->spb = 2;
else {
if (ioctl(geo->fd,FIGETBSZ,&block_size) < 0) {
fprintf(stderr,"Warning: FIGETBSZ %s: %s\n",name,strerror(errno));
geo->spb = 2;
}
else {
if (!block_size || (block_size & (SECTOR_SIZE-1)))
die("Incompatible block size: %d\n",block_size);
geo->spb = block_size/SECTOR_SIZE;
}
}
#endif
return geo->fd;
}
void geo_close(GEOMETRY *geo)
{
(void) close(geo->fd);
}
#ifndef FIBMAP
#define FIBMAP BMAP_IOCTL
#endif
int geo_comp_addr(GEOMETRY *geo,int offset,SECTOR_ADDR *addr)
{
int block,sector;
block = offset/geo->spb/SECTOR_SIZE;
if (geo->file) {
if (ioctl(geo->fd,FIBMAP,&block) < 0) pdie("ioctl FIBMAP");
if (!block) return 0;
}
sector = block*geo->spb+((offset/SECTOR_SIZE) % geo->spb);
sector += geo->start;
if (linear) {
addr->device = geo->device | LINEAR_FLAG;
addr->sector = sector & 0xff;
addr->track = (sector >> 8) & 0xff;
addr->head = sector >> 16;
if (verbose > 4)
printf("fd %d: offset %d -> linear %d\n",geo->fd,offset,sector);
}
else {
addr->device = geo->device;
addr->sector = (sector % geo->sectors)+1;
sector /= geo->sectors;
addr->head = sector % geo->heads;
sector /= geo->heads;
if (sector > 1023)
die("geo_comp_addr: Cylinder number is too big (%d > 1023)",sector);
if (sector >= geo->cylinders)
die("geo_comp_addr: Cylinder %d beyond end of media (%d)",sector,
geo->cylinders);
if (verbose > 4)
printf("fd %d: offset %d -> dev %d, head %d, track %d, sector %d\n",
geo->fd,offset,addr->device,addr->head,sector,addr->sector);
addr->track = sector & 255;
addr->sector |= (sector >> 8) << 6;
}
addr->num_sect = 1;
return 1;
}
lilo/geometry.h 644 0 0 2127 5271053170 12021 0 ustar root root /* geometry.h - Device and file geometry computation */
/* Written 1992 by Werner Almesberger */
#ifndef _GEOMETRY_H_
#define _GEOMETRY_H_
#include "lilo.h"
typedef struct {
int device,heads,cylinders,sectors;
int start; /* partition offset */
int spb; /* sectors per block */
int fd,file;
} GEOMETRY;
void geo_init(char *name);
/* Loads the disk geometry table. */
int geo_open(GEOMETRY *geo,char *name,int flags);
/* Opens the specified file or block device, obtains the necessary geometry
information and returns the file descriptor. If the name contains a BIOS
device specification (xxx:yyy), it is removed and stored in the geometry
descriptor. Returns the file descriptor of the opened object. */
void geo_close(GEOMETRY *geo);
/* Closes a file or device that has previously been opened by geo_open. */
int geo_comp_addr(GEOMETRY *geo,int offset,SECTOR_ADDR *addr);
/* Determines the address of the disk sector that contains the offset'th
byte of the specified file or device. Returns a non-zero value if such
a sector exists, zero if it doesn't. */
#endif
lilo/lilo.c 644 0 0 13772 5310535546 11156 0 ustar root root /* lilo.c - LILO command-line parameter processing */
/* Written 1992 by Werner Almesberger */
#include
#include
#include
#include
#include
#include "config.h"
#include "common.h"
#include "lilo.h"
#include "geometry.h"
#include "bsect.h"
#include "cfg.h"
#define S2(x) #x
#define S(x) S2(x)
static void show_images(char *map_file)
{
DESCR_SECTORS descrs;
char *name;
int fd,image;
if ((fd = open(map_file,O_RDONLY)) < 0)
die("open %s: %s",map_file,strerror(errno));
if (read(fd,(char *) &descrs,SECTOR_SIZE*2) != SECTOR_SIZE*2)
die("read %s: %s",map_file,strerror(errno));
(void) close(fd);
for (image = 0; image < MAX_IMAGES; image++)
if (*(name = descrs.descr[image].name)) {
printf("%-" S(MAX_IMAGE_NAME) "s%s",name,image ? " " : " *");
if (verbose > 0) {
printf(" ",
descrs.descr[image].start.device,
descrs.descr[image].start.head,
descrs.descr[image].start.track,
descrs.descr[image].start.sector);
if (descrs.descr[image].present & OVR_ROOT)
printf(",root=0x%04x",descrs.descr[image].root_dev);
}
printf("\n");
}
exit(0);
}
static void usage(char *name)
{
char *here;
if (here = strrchr(name,'/')) name = here+1;
fprintf(stderr,"usage: %s [ -m map_file ] [ -v ]\n",name);
fprintf(stderr,"%7s%s [ -b boot_device ] [ -c ] [ -l ] [ -i boot_sector ]"
"\n","",name);
fprintf(stderr,"%12s[ -f disk_tab ] [ -m map_file ] [ -d delay ] "
"[ -v ] [ -t ]\n","");
fprintf(stderr,"%12s[ [ -s | -S ] save_file ] [ -r root_dir ] "
"[ boot_descr ... ]\n\n","");
fprintf(stderr,"Descriptor format:\n");
fprintf(stderr," [ label= ] image(s) [ ,root_dev ]\n\n");
fprintf(stderr,"Images:\n");
fprintf(stderr," Boot image: file_name\n");
fprintf(stderr," Device: device #start [ +num | -end ]\n");
fprintf(stderr," Unstripped: setup+kernel\n");
fprintf(stderr," Other OS: loader+boot_sect@ [ part_table ]\n");
exit(1);
}
int main(int argc,char **argv)
{
char *name,*config_file;
int image,test,query,more;
BOOT_SECTOR dummy;
config_file = NULL;
test = query = 0;
name = *argv++;
argc--;
cfg_init(cf_options);
while (argc && **argv == '-') {
argc--;
if (argv[0][2]) usage(name);
switch ((*argv++)[1]) {
case 'b':
if (!argc) usage(name);
cfg_set(cf_options,"boot",*argv++);
argc--;
break;
case 'c':
cfg_set(cf_options,"compact",NULL);
compact = 1;
break;
case 'd':
if (!argc) usage(name);
cfg_set(cf_options,"delay",*argv++);
argc--;
break;
case 'f':
if (!argc) usage(name);
cfg_set(cf_options,"disktab",*argv++);
argc--;
break;
case 'l':
cfg_set(cf_options,"linear",NULL);
linear = 1;
break;
case 'm':
if (!argc) usage(name);
cfg_set(cf_options,"map",*argv++);
argc--;
break;
case 'i':
if (!argc) usage(name);
cfg_set(cf_options,"install",*argv++);
argc--;
break;
case 'X':
printf("-DIMAGES=%d -DCODE_START_1=%d -DCODE_START_2=%d "
"-DDESCR_SIZE=%d -DDSC_OFF=%d -DDSC_OFF2=%d\n",MAX_IMAGES,
sizeof(BOOT_PARAMS_1),sizeof(BOOT_PARAMS_2),
sizeof(IMAGE_DESCR),(void *) &dummy.par_1.descr[0]-(void *)
&dummy,(void *) &dummy.par_1.descr[1]-(void *) &dummy);
exit(0);
case 'C':
if (!argc) usage(name);
config_file = *argv++;
argc--;
break;
case 'D':
dump = test = 1;
break;
case 'S':
if (!argc) usage(name);
cfg_set(cf_options,"force-backup",*argv++);
argc--;
break;
case 's':
if (!argc) usage(name);
cfg_set(cf_options,"backup",*argv++);
argc--;
break;
case 'q':
query = 1;
break;
case 'r':
if (!argc) usage(name);
if (chroot(*argv) < 0)
die("chroot %s: %s",*argv,strerror(errno));
if (chdir("/") < 0) die("chdir /: %s",strerror(errno));
argv++;
argc--;
break;
case 't':
test = 1;
break;
case 'v':
verbose++;
break;
default:
usage(name);
}
}
if (verbose > 0)
printf("LILO version 0.7\nWritten 1992 by Werner Almesberger\n\n");
#if 0
if (((install || test || boot_device || disktab_file || compact) && !argc)
|| (compact && linear && 0)) usage(name);
#endif
if (config_file) {
cfg_open(config_file);
more = cfg_parse(cf_options);
}
compact = cfg_get_flag(cf_options,"compact");
linear = cfg_get_flag(cf_options,"linear");
if (cfg_get_strg(cf_options,"verbose"))
verbose += to_number(cfg_get_strg(cf_options,"verbose"));
if (dump) {
#define DUMP_FLAG(x) \
if (cfg_get_flag(cf_options,x)) printf("%s\n",x);
#define DUMP_STRG(x) \
if (cfg_get_strg(cf_options,x)) \
printf("%s = %s\n",x,cfg_get_strg(cf_options,x));
DUMP_STRG("boot");
DUMP_STRG("delay");
DUMP_STRG("install");
DUMP_STRG("disktab");
DUMP_STRG("map");
if (verbose) printf("verbose = %d\n",verbose);
DUMP_STRG("backup");
DUMP_STRG("force-backup");
DUMP_FLAG("compact");
DUMP_FLAG("linear");
verbose = -1;
}
if ((!argc && !config_file) || query)
show_images(!cfg_get_strg(cf_options,"map") ? MAP_FILE :
cfg_get_strg(cf_options,"map"));
if (argc > MAX_IMAGES) {
fprintf(stderr,"Only %d images can be defined\n",MAX_IMAGES);
exit(1);
}
geo_init(cfg_get_strg(cf_options,"disktab"));
bsect_open(cfg_get_strg(cf_options,"boot"),cfg_get_strg(cf_options,"map") ?
cfg_get_strg(cf_options,"map") : MAP_FILE,cfg_get_strg(cf_options,
"install"),cfg_get_strg(cf_options,"delay") ? to_number(cfg_get_strg(
cf_options,"delay")) : 0);
if (!config_file)
for (image = 0; image < argc; image++) bsect_image(*argv++);
else {
if (argc) usage(name);
if (more) {
cfg_init(cf_top);
if (cfg_parse(cf_top)) cfg_error("Syntax error");
}
}
if (!test)
if (cfg_get_strg(cf_options,"force-backup"))
bsect_update(cfg_get_strg(cf_options,"force-backup"),1);
else bsect_update(cfg_get_strg(cf_options,"backup"),0);
else {
bsect_cancel();
fprintf(stderr,"The boot sector and the map file have *NOT* been "
"altered.\n");
}
return 0;
}
lilo/lilo.h 644 0 0 7203 5310553174 11130 0 ustar root root /* lilo.h - LILO constants */
/* Written 1992 by Werner Almesberger */
/* This file is also included by the boot loader assembler code. Put
everything that isn't legal C syntax or isn't swallowed by the
preprocessor into #ifdef LILO_ASM ... #endif */
#ifndef _LILO_H_
#define _LILO_H_
#define VERSION 7 /* boot sector and map file format revision */
#define MAX_IMAGES (SECTOR_SIZE*2/sizeof(IMAGE_DESCR))
/* maximum number of images */
#define MAX_IMAGE_NAME 15 /* maximum name length (w/o terminating NUL) */
#define MAX_PW 15 /* maximum password length */
#define MAX_SECONDARY 8 /* maximum number of sectors in the 2nd stage
loader */
#define SECTOR_SIZE 512 /* disk sector size */
#define BLOCK_SIZE 1024 /* disk block size */
#define ADDR_OFFS MAX_IMAGE_NAME+MAX_PW+2 /* map address offset */
#define PARTITION_ENTRY 16 /* size of one partition entry */
#define PARTITION_ENTRIES 4 /* number of partition entries */
#define PART_TABLE_SIZE (PARTITION_ENTRY*PARTITION_ENTRIES)
#define PART_TABLE_OFFSET 0x1be /* offset in the master boot sector */
#define PART_MASK 15 /* largest common partition bits mask */
#define PART_MAX 4 /* biggest primary partition number */
#define MAX_BOOT_SIZE PART_TABLE_OFFSET /* scream if the boot sector gets
any bigger */
#define BOOT_SIGNATURE 0xaa55 /* boot signature */
#define BOOT_SIG_OFFSET 510 /* boot signature offset */
#define PART_DOS12 1 /* DOS 12 bit FAT partition type */
#define PART_DOS16 4 /* DOS 16 bit FAT partition type */
#define PART_INVALID 98 /* invalid partition type */
#define STAGE_FIRST 1 /* first stage loader code */
#define STAGE_SECOND 2 /* second stage loader code */
#define STAGE_CHAIN 0x10 /* chain loader code */
#define SETUPSECS 4 /* nr of setup sectors */
#define MAX_KERNEL_SECS 1024 /* absolute maximum kernel size */
#define LINEAR_FLAG 0x40 /* mark linear address */
#define EX_OFF CODE_START_1+SSDIFF /* external parameter block */
#define EX_DL_MAG 0xfe /* magic number in DL */
#define EX_SI_MAG 0x494c /* magic number in SI, "LI" */
#define EX_ES_MAG 0x4f4c /* magic number in ES, "LO" */
#define OVR_RAMD 1 /* override RAM disk size */
#define OVR_VGA 2 /* override VGA mode */
#define OVR_ROOT 4 /* override root partition */
#ifdef LILO_ASM
BOOTSEG = 0x07C0 ! original address of boot-sector
PART_TABLE= 0x07BE ! partition table
FIRSTSEG = 0x9A00
INITSEG = DEF_INITSEG ! we move boot here - out of the way
SETUPSEG = DEF_SETUPSEG ! setup starts here
SYSSEG = DEF_SYSSEG ! system loaded at 0x10000 (65536).
STACKSEG = 0x9000
SSDIFF = 0xA000
STACK = 0xB000 ! top of stack
DESCR = 0x2200 ! descriptor load area offset
MAP = 0x2000 ! map load area offset
SECOND = 0x1000 ! second stage loader load address
SECOND_SS = 0xB000 ! second as seen from SS:0000
SECONDSEG = 0x9B00 ! second stage loader segment
! 0x007BE-0x007FD 64 B partition table
! 0x07C00-0x07DFF 0.5 kB boot load address
! 0x10000-0x8FFFF 512 kB kernel
! 0x90000-0x901FF 0.5 kB Linux floppy boot sector
! 0x90200-0x99FFF 39.5 kB setup
! 0x9A000-0x9A1FF 0.5 kB boot sector (first stage loader)
! 0x9A200-0x9AFFF 3.5 kB stack
! 0x9B000-0x9CFFF 8 kB second stage loader
! 0x9D000-0x9D1FF 0.5 kB file map load area
! 0x9D200-0x9D5FF 1 kB descriptor table load area
! 0x9D600-0x9FFFF 10.5 kB scratch space
CL_MAGIC_ADDR = 0x20 ! command line magic number
CL_MAGIC = 0xa33f ! very unusual command sequence
CL_OFFSET = 0x22 ! command line offset
CL_LENGTH = 0x4e ! maximum length
! 0x90020-0x90021 2 by command line magic number
! 0x90022-0x90023 2 by command line offset
#endif
#endif
lilo/map.c 644 0 0 13123 5310553352 10755 0 ustar root root /* map.c - Map file creation */
/* Written 1992 by Werner Almesberger */
#include
#include
#include
#include
#include
#include
#include "lilo.h"
#include "common.h"
#include "geometry.h"
#include "map.h"
typedef struct _map_entry {
SECTOR_ADDR addr;
struct _map_entry *next;
} MAP_ENTRY;
static MAP_ENTRY *map,*last;
static GEOMETRY map_geo;
static SECTOR_ADDR zero_addr;
static int map_file;
void map_create(char *name)
{
char buffer[SECTOR_SIZE*3];
int fd;
if ((fd = creat(name,0600)) < 0) die("creat %s: %s",name,strerror(errno));
(void) close(fd);
memset(buffer,0,SECTOR_SIZE*3);
map_file = geo_open(&map_geo,name,O_RDWR);
if (write(map_file,buffer,SECTOR_SIZE*3) != SECTOR_SIZE*3)
die("write %s: %s",name,strerror(errno));
if (!geo_comp_addr(&map_geo,SECTOR_SIZE*2,&zero_addr))
die("Hole found in map file (zero sector)");
}
void map_done(DESCR_SECTORS *descr,SECTOR_ADDR addr[2])
{
struct stat st;
if (lseek(map_file,0,0) < 0) pdie("lseek map file");
if (write(map_file,(char *) descr,SECTOR_SIZE*2) != SECTOR_SIZE*2)
pdie("write map file");
if (!geo_comp_addr(&map_geo,0,&addr[0]))
die("Hole found in map file (first descr. sector)");
if (!geo_comp_addr(&map_geo,SECTOR_SIZE,&addr[1]))
die("Hole found in map file (second descr. sector)");
if (verbose > 1) {
if (fstat(map_file,&st) < 0) pdie("fstat map file");
printf("Map file size: %d bytes.\n",st.st_size);
}
geo_close(&map_geo);
}
void map_register(SECTOR_ADDR *addr)
{
MAP_ENTRY *new;
new = alloc(sizeof(MAP_ENTRY));
memcpy(&new->addr,addr,sizeof(SECTOR_ADDR));
new->next = NULL;
if (last) last->next = new;
else map = new;
last = new;
}
void map_add_sector(void *sector)
{
int here;
SECTOR_ADDR addr;
if ((here = lseek(map_file,0L,1)) < 0) pdie("lseek map file");
if (write(map_file,sector,SECTOR_SIZE) != SECTOR_SIZE)
pdie("write map file");
if (!geo_comp_addr(&map_geo,here,&addr))
die("Hole found in map file (app. sector)");
map_register(&addr);
}
void map_begin_section(void)
{
map = last = NULL;
}
void map_add(GEOMETRY *geo,int from,int num_sect)
{
int count;
SECTOR_ADDR addr;
for (count = 0; count < num_sect; count++) {
if (geo_comp_addr(geo,SECTOR_SIZE*(count+from),&addr))
map_register(&addr);
else {
map_register(&zero_addr);
if (verbose > 3) printf("Covering hole at sector %d.\n",count);
}
}
}
void map_add_zero(void)
{
map_register(&zero_addr);
}
void map_compact(void)
{
MAP_ENTRY *walk,*next;
int count,removed,offset,adj;
removed = 0;
walk = map;
for (count = 0; walk && count <= SETUPSECS; count++) walk = walk->next;
offset = 0;
while (walk && walk->next) {
adj = walk->addr.device == walk->next->addr.device;
if (linear)
adj = adj && ((walk->addr.head << 16) | (walk->addr.track << 8) |
walk->addr.sector)+walk->addr.num_sect == ((walk->next->addr.head
<< 16) | (walk->next->addr.track << 8) | walk->next->addr.sector);
else adj = adj && walk->addr.track == walk->next->addr.track &&
walk->addr.head == walk->next->addr.head &&
walk->addr.sector+walk->addr.num_sect == walk->next->addr.sector;
if (!adj || offset >> 16 != (offset+SECTOR_SIZE*walk->addr.num_sect) >>
16) {
offset += SECTOR_SIZE*walk->addr.num_sect;
walk = walk->next;
}
else {
walk->addr.num_sect++;
next = walk->next->next;
free(walk->next);
removed++;
walk->next = next;
}
}
if (verbose > 1)
printf("Compaction removed %d BIOS call%s.\n",removed,removed == 1 ?
"" : "s");
}
static void map_alloc_page(int offset,SECTOR_ADDR *addr)
{
int here;
if ((here = lseek(map_file,offset,1)) < 0) pdie("lseek map file");
if (write(map_file,"",1) != 1) pdie("write map file");
if (!geo_comp_addr(&map_geo,here,addr))
die("Hole found in map file (alloc_page)");
if (lseek(map_file,-offset-1,1) < 0) pdie("lseek map file");
}
int map_end_section(SECTOR_ADDR *addr)
{
int first,offset,sectors;
char buffer[SECTOR_SIZE];
MAP_ENTRY *walk,*next;
first = 1;
memset(buffer,0,SECTOR_SIZE);
offset = sectors = 0;
if (compact) map_compact();
if (map == NULL) die("Empty map section");
for (walk = map; walk; walk = next) {
next = walk->next;
if (verbose > 3) {
printf(" Mapped AL=0x%02x CX=0x%04x DX=0x%04x",walk->addr.num_sect,
(walk->addr.track << 8) | walk->addr.sector,(walk->addr.head << 8)
| walk->addr.device);
if (linear)
printf(", linear=%d",(walk->addr.head << 16) | (walk->addr.track
<< 8) | walk->addr.sector);
printf("\n");
}
if (first) {
first = 0;
map_alloc_page(0,addr);
}
if (offset+sizeof(SECTOR_ADDR)*2 > SECTOR_SIZE) {
map_alloc_page(SECTOR_SIZE,(SECTOR_ADDR *) (buffer+offset));
if (write(map_file,buffer,SECTOR_SIZE) != SECTOR_SIZE)
pdie("write map file");
memset(buffer,0,SECTOR_SIZE);
offset = 0;
}
memcpy(buffer+offset,&walk->addr,sizeof(SECTOR_ADDR));
offset += sizeof(SECTOR_ADDR);
sectors += walk->addr.num_sect;
free(walk);
}
if (offset)
if (write(map_file,buffer,SECTOR_SIZE) != SECTOR_SIZE)
pdie("write map file");
return sectors;
}
int map_write(SECTOR_ADDR *list,int max_len)
{
MAP_ENTRY *walk,*next;
int sectors;
sectors = 0;
for (walk = map; walk; walk = next) {
next = walk->next;
if (--max_len <= 0) die("Map segment is too big.");
memcpy(list++,&walk->addr,sizeof(SECTOR_ADDR));
free(walk);
sectors++;
}
memset(list,0,sizeof(SECTOR_ADDR));
return sectors;
}
lilo/map.h 644 0 0 2341 5310272040 10732 0 ustar root root /* map.h - Map file creation */
/* Written 1992 by Werner Almesberger */
#ifndef _MAP_H_
#define _MAP_H_
#include "common.h"
#include "geometry.h"
void map_create(char *name);
/* Create and initialize the specified map file. */
void map_done(DESCR_SECTORS *descr,SECTOR_ADDR addr[2]);
/* Updates and closes the map file. */
void map_add_sector(void *sector);
/* Adds the specified sector to the map file and registers it in the map
section. */
void map_begin_section(void);
/* Begins a map section. Note: maps can also be written to memory with
map_write. Thus, the map routines can be used even without map_create. */
void map_add(GEOMETRY *geo,int from,int num_sect);
/* Adds pointers to sectors from the specified file to the map file. */
void map_add_zero(void);
void map_compact(void);
/* Compacts the current map section. */
int map_end_section(SECTOR_ADDR *addr);
/* Writes a map section to the map file and returns the address of the first
sector of that section. Returns the number of sectors that have been
mapped. */
int map_write(SECTOR_ADDR *list,int max_len);
/* Writes a map section to an array. If the section (including the terminating
zero entry) exceeds max_len, map_write dies. */
#endif
lilo/second.S 644 0 0 27357 5310526061 11446 0 ustar root root /* second.S - LILO second stage boot loader */
/* Written 1992 by Werner Almesberger */
#include
#define LILO_ASM
#include "lilo.h"
#ifdef DEBUG
#define DBG_LREAD 1
#endif
#define UI_MAGIC 0xff /* take input from keyboard */
.text
.globl _main
.org 0
_main: jmp start
.org 2
! Boot device parameters. They are set by the installer.
.ascii "LILO"
.word STAGE_SECOND
.word VERSION
.org CODE_START_2
start: mov al,#0x4c ! display an 'L'
call display
! Restart here after a boot error
restrt: mov ax,cs ! adjust segment registers
mov ds,ax
mov es,ax
cli ! reset SP (we might have restarted with some
mov sp,#STACK ! data on the stack)
sti
ldsc: mov al,#1 ! load the descriptor table
mov bx,#DESCR
seg ss
mov cx,DSC_OFF+SSDIFF
seg ss
mov dx,DSC_OFF+2+SSDIFF
call cread
jc fdnok ! error -> retry
mov al,#1 ! load the second sector
mov bx,#DESCR+512
seg ss
mov cx,DSC_OFF2+SSDIFF
seg ss
mov dx,DSC_OFF2+2+SSDIFF
call cread
jnc dokay ! okay -> go on
fdnok: xor ax,ax ! reset FDC
mov dl,al
int 0x13
jmp ldsc ! retry
! List all known boot images
list: mov bx,#crlf ! display a CRLF
call say
mov si,#DESCR ! list all images
mov cx,#IMAGES
lloop: testb (si),#0xff ! done ?
jz ldone ! yes
mov bx,si ! display the name
call say
add si,#MAX_IMAGE_NAME
fill: push bx ! fill with spaces
mov al,#0x20
call display
pop bx
inc bx
cmp bx,si
jbe fill
add si,#DESCR_SIZE-MAX_IMAGE_NAME
loop lloop ! next image
ldone: mov bx,#crlf ! display a CRLF
call say
jmp iloop ! done
! Ready to process user input
dokay: mov bx,#ospc ! display 'O '
call say
mov ospc,#0 ! disable the message
xor ah,ah ! get the current timer
int 0x1a
seg ss ! add the delay
add dx,DSC_OFF-4+SSDIFF
xor ax,ax
adc cx,ax
seg ss ! no delays when retrying to boot
mov DSC_OFF-4+SSDIFF,ax
mov to_low,dx ! save the timeout
mov to_high,cx
! Shift wait loop
actlp: mov ah,#2 ! get shift keys
int 0x16
and al,#0x5f ! anything set ? (except NumLock)
jnz iloop ! yes -> enter interactive mode
xor ah,ah ! get timer
int 0x1a
cmp cx,to_high ! compare MSW
ja extp ! -> timed out
jb actlp ! -> wait
cmp dx,to_low ! compare LSW
jae extp ! -> timed out
jmp actlp ! try again
! Check for external parameters
extp: seg ss ! external parameters ?
cmp byte ptr EX_OFF+6,#EX_DL_MAG
jne noex ! no -> go on
seg ss ! clear flag
mov byte ptr EX_OFF+6,#0
seg ss ! load the signature pointer
les bx,EX_OFF
seg es ! "LI" ?
cmp (bx),#EX_SI_MAG
jne noex ! no -> go on
seg es ! "LO" ?
cmp (bx+2),#EX_ES_MAG
jne noex ! no -> go on
seg ss
mov si,EX_OFF+4 ! pointer to the command line
seg es
cmp byte ptr (si),#0 ! empty ?
je iloop ! yes -> enter interactive mode
jmp niloop ! enter non-interactive mode
! No external parameters after timeout -> boot first image
noex: mov ax,cs ! restore ES
mov es,ax
br bfirst ! boot first image
tolist: br list ! ...
! Command input processor
iloop: mov si,#usrinpm ! interactive mode
niloop: mov bx,#msg_p ! display boot prompt
call say
push ds ! invalidate command line descriptor
mov ax,#INITSEG
mov ds,ax
mov bx,#cmdline
mov CL_MAGIC_ADDR,#0 ! clear magic number
pop ds ! restore DS
! Input loop
input: cmp byte ptr (si),#UI_MAGIC ! interactive mode ?
je kbinp ! yes -> get keyboard input
seg es ! get non-interactive input
mov al,(si)
inc si
jmp gotinp ! go on
kbinp: xor ah,ah ! read a key
int 0x16
gotinp: cmp al,#9 ! TAB ?
je tolist ! yes -> list images
cmp al,#63 ! "?" ?
je tolist ! yes -> list images
or al,al ! NUL ?
je cr ! yes -> go on
cmp al,#13 ! CR ?
je cr ! yes -> go on
cmp al,#8 ! BS ?
je todelch ! yes -> erase one character
cmp al,#127 ! DEL ?
je todelch ! yes -> erase one character
cmp al,#21 ! ^U ?
je todell ! yes -> erase the line
cmp al,#24 ! ^X ?
je todell ! yes -> erase the line
cmp al,#127 ! ignore non-printable characters except space
jae input
cmp al,#32
jb input
ja noblnk ! no space -> go on
cmp (bx-1),al ! second space in a row ?
je input ! yes -> ignore it
noblnk: mov (bx),al ! store in the buffer
inc bx ! increment pointer
push bx
call display ! echo
pop bx
cmp bx,#cmdline+CL_LENGTH ! at end of buffer ?
jb input ! no -> next input
! End of input, process the command line
cr: mov ax,cs ! set ES to CS
mov es,ax
xor al,al ! mark end
mov (bx),al
cmp bx,#cmdline ! empty line ?
je notrspc ! yes -> boot first image
cmp byte ptr (bx-1),#32 ! trailing space ?
jne notrspc ! no -> go on
dec bx ! remove the space
mov byte ptr (bx),al
notrspc:push bx ! display a CRLF
mov bx,#crlf
call say
pop bx
cmp bx,#cmdline ! empty line ?
emptyl: je bfirst ! yes -> boot first image
mov bx,#cmdline ! find first space
scnblnk:cmp byte ptr (bx),#32 ! first space ?
je spcfn ! yes -> set up command line
cmp byte ptr (bx),#0 ! at end ?
je scndne ! yes -> go on
inc bx ! next character
jmp scnblnk
toinput:br input ! ...
todelch:jmp delch ! ...
todell: jmp delline ! ...
! Find the boot image and start it
spcfn: mov byte ptr (bx),#0 ! zero out the first space
push ds ! create command line descriptor
mov ax,#INITSEG
mov ds,ax
mov CL_MAGIC_ADDR,#CL_MAGIC ! set magic number
add bx,#SECOND_SS+1 ! set command line offset
mov CL_OFFSET,bx
pop ds ! restore DS
scndne: mov cx,#IMAGES ! test all names
mov bx,#DESCR
nextn: mov si,bx ! compare the names
mov di,#cmdline
nextc: mov al,(si) ! character equal ?
cmp al,(di)
jne skipn ! no -> try next one
or al,al ! NUL ?
jz boot ! yes -> names match
inc si ! test next character
inc di
jmp nextc
skipn: add bx,#DESCR_SIZE ! test next name
loop nextn
mov bx,#msg_nf ! not found -> display a message
call say
br iloop ! get more input
! Delete one character
delch: cmp bx,#cmdline ! at the beginning ?
je toinput ! yes -> do nothing
push bx ! display BS,SPC,BS
mov bx,#bs
call say
pop bx
dec bx ! move the pointer
jmp toinput ! go on
! Delete the entire line
delline:cmp bx,#cmdline ! done ?
je toinput ! yes -> go on
push bx ! display BS,SPC,BS
mov bx,#bs
call say
pop bx
dec bx ! move the pointer
jmp delline ! next one
! Boot the first image
bfirst: mov bx,default ! boot the first image
! Boot the image BX points to
boot: mov default,bx ! make this the new default
push bx ! save image descr
mov bx,#msg_l ! say hi
call say
pop bx ! display the image name
push bx
call say
pop si
add si,#ADDR_OFFS
cld
lodsw ! address of the first map sector
mov cx,ax
lodsw
mov dx,ax
inc si ! skip number of sectors
inc si
push si ! save SI
#ifdef DEBUG
mov bx,#step1
call say
#endif
mov bx,#MAP ! load the first map sector
mov al,#1
call sread
#ifdef DEBUG
mov bx,#step2
call say
#endif
mov ax,#INITSEG ! load the original boot sector
mov es,ax
seg es ! save the command line stuff first
push CL_MAGIC_ADDR
seg es
push CL_OFFSET
xor bx,bx ! load now
call load
seg es ! restore the commands line
pop CL_OFFSET
seg es
pop CL_MAGIC_ADDR
pop si ! restore SI
lodsw ! get present bit map
mov bx,ax
lodsw ! copy parameters ... RAM disk size
test bx,#OVR_RAMD
jz noram
seg es
mov 504,ax
noram: lodsw ! ... VGA mode ...
test bx,#OVR_VGA
jz novga
seg es
mov 506,ax
novga: lodsw ! ... root partition
test bx,#OVR_ROOT
jz noroot
seg es
mov 508,ax
noroot: lodsw ! copy BSS parameters
mov bssseg,ax
lodsw
mov bsssgs,ax
lodsw
mov bsswrd,ax
cmp bssseg,#0 ! BSS range known ?
jne bssknwn ! yes -> go on
call clrbss ! clear BSS
bssknwn:
#ifdef DEBUG
mov bx,#step3
call say
#endif
mov ax,#SETUPSEG ! load the setup
mov es,ax
xor bx,bx
mov cx,#SETUPSECS
lsetup: push cx
call load
pop cx
loop lsetup
#ifdef DEBUG
mov bx,#step4
call say
#endif
mov ax,#SYSSEG ! load the system
mov es,ax
xor bx,bx
lsys: call load
jmp lsys
! Load one sector. Start the kernel at EOF.
load: push es ! save ES:BX
push bx
lfetch: mov si,moff ! get map offset
mov cx,MAP(si) ! get address
mov dx,MAP+2(si)
mov al,MAP+4(si)
or cx,cx ! at EOF ?
jnz noteof ! no -> go on
or dx,dx
jz launch ! yes -> start system
noteof: add si,#5 ! increment pointer
mov moff,si
cmp si,#508 ! page end ?
jb doload ! no -> load it
mov moff,#0 ! reset pointer
push cs ! adjust ES
pop es
mov bx,#MAP ! load map page
call sread
mov al,#0x2e ! print a dot
call display
jmp lfetch ! try again
! Start the kernel
launch: mov bx,#crlf ! display a CRLF
call say
mov dx,#0x3f2 ! stop the floppy motor
xor al,al
outb
xor ax,ax ! reset the FDC
mov dl,al
int 0x13
mov ax,bssseg ! clear BSS ?
or ax,ax
jz nobss ! no -> go on
mov es,ax
mov bx,bsssgs ! zero whole segments
zsegl: or bx,bx ! done with segments ?
jz segdn ! yes -> go on
xor ax,ax ! zero 32768 words
xor di,di
mov cx,#0x8000
rep
stosw
dec bx ! next segment
mov ax,es
add ax,#0x1000
mov es,ax
jmp zsegl
segdn: mov ax,bsswrd ! remaining words
or ax,ax ! any left ?
jz nobss ! no -> go on
mov cx,ax ! zero them
xor di,di
xor ax,ax
rep
stosw
nobss: mov ax,#INITSEG ! adjust segment registers
mov ds,ax
mov es,ax
jmpi 0,SETUPSEG ! start the setup
! Load one sector (called from load)
doload: pop bx ! restore ES:BX
pop es
! Load a sequence of sectors
sread: push bx ! save registers
push cx
push dx
mov tempal,al ! save AL
call cread
jc rerror ! error -> complain
pop dx ! restore registers
pop cx
rokay: pop bx
xor ax,ax ! compute offset
mov ah,tempal
add ah,ah
jc dowrap ! loaded an entire segment -> advance ES
add bx,ax ! move BX
jnc nowrap ! same segment -> go on
dowrap: mov ax,es ! move ES
add ax,#0x1000
mov es,ax
nowrap:
aret: ret ! done
! Read error - try a second time and give up if that fails too
rerror: xor ax,ax ! reset the disk
mov dl,al
int 0x13
pop dx ! try again
pop cx
pop bx
push bx
mov al,tempal
call cread
jnc rokay ! okay -> go on
push ax
mov bx,#msg_re ! say something
call say
pop ax ! display the error code
mov al,ah
call bout
mov bx,#crlf ! a CRLF
call say
mov moff,#0 ! restore initial state
jmpi restrt,SECONDSEG
! Clear area 0x10000-0x8FFFF
clrbss: push cx ! save CX, DX and ES
push dx
push es
mov ax,#DEF_SYSSEG ! start segment
mov es,ax
mov bx,#8 ! clear eight segments
cbslp: xor ax,ax ! clear one segment
xor di,di
mov cx,#0x8000 ! (0x8000 words)
rep
stosw
mov ax,es ! next segment
add ax,#0x1000
mov es,ax
dec bx ! done ?
jnz cbslp ! no -> go on
pop es ! restore CX, DX and ES
pop dx
pop cx
ret ! done
! Display a hexadecimal byte
#ifdef DEBUG
wout: push ax
mov al,ah
call bout
pop ax
#endif
bout: push ax ! save byte
shr al,#4 ! display upper nibble
call nout
pop ax
nout: and al,#15 ! lower nible only
add al,#48 ! display lower nibble
cmp al,#58 ! convert to ASCII
jb nokay
add al,#7
nokay: call display ! display it
ret ! done
! Display a NUL-terminated string on the console
say: mov al,(bx) ! get byte
or al,al ! NUL ?
jz aret ! yes -> done
push bx ! save pointer
call display ! display, tty-style
pop bx
inc bx ! next one
jmp say
! Sector read
#include "shared.S"
! Some messages
msg_p: .ascii "boot: "
.byte 0
msg_l: .ascii "Loading "
.byte 0
msg_re: .byte 13,10
.ascii "Error 0x"
.byte 0
msg_nf: .ascii "No such image. [Tab] shows a list."
.byte 13,10,0
ospc: .ascii "O"
.byte 32,0
crlf: .byte 13,10,0
bs: .byte 8,32,8,0
#ifdef DEBUG
step1: .ascii " map page,"
.byte 0
step2: .ascii " boot,"
.byte 0
step3: .ascii " setup,"
.byte 0
step4: .ascii " system,"
.byte 0
sax: .ascii "AX="
.byte 0
sbx: .ascii " BX="
.byte 0
scx: .ascii " CX="
.byte 0
sdx: .ascii " DX="
.byte 0
ses: .ascii " ES="
.byte 0
sdone: .byte 13,10
.byte 0
#endif
default:.word DESCR ! default descriptor
tempal: .byte 0
moff: .word 0 ! map offset
to_low: .word 0 ! timeout
to_high:.word 0
bssseg: .word 0 ! BSS parameters
bsssgs: .word 0
bsswrd: .word 0
usrinpm:.byte UI_MAGIC
.byte 32 ! guard double blank supression
cmdline:
lilo/shared.S 644 0 0 5343 5273331243 11414 0 ustar root root /* shared.S - Routines shared by the first and the second boot loader */
/* Written 1992 by Werner Almesberger */
display:xor bh,bh ! display on screen
mov ah,#14
int 0x10
ret
tord: br dord ! ...
tolner5:br linerr5 ! ...
cread: test dl,#LINEAR_FLAG ! linear address ?
jz tord ! no -> go on
and dl,#0xff-LINEAR_FLAG ! remove flag
mov t_secs,al ! save number of sectors
lnread: push cx ! keep linear address
push dx
push bx ! BX is used as scratch
push cx ! LSW
push dx ! MSW with drive
mov ah,#8 ! get drive geometry (do not clobber ES:DI)
push es
push di
int 0x13
pop di
pop es
jc tolner5 ! error -> quit
mov bl,dh ! BL <- #heads
pop dx ! get MSW
mov t_drive,dl ! save drive
mov dl,dh ! linear address into DX:AX
xor dh,dh
mov bh,dh ! (clear BH too)
pop ax
push cx ! compute #cyls-1
xchg ch,cl
rol ch,1
rol ch,1
and ch,#3
mov n_cyl,cx ! save #cyls-1
pop cx
and cx,#0x3f ! CX <- #secs
mov n_secs,cx
div cx ! AX <- track, DX <- sector
inc dl
mov t_sector,dl
xor dx,dx ! divide by #heads
inc bx
div bx ! AX <- cylinder, DX <- head
mov dh,dl ! set up DX (head:drive)
mov dl,t_drive
cmp ax,n_cyl ! valid cylinder number ?
ja linerr3 ! no -> error
xchg ah,al ! build cylinder number
ror al,1
ror al,1
or al,t_sector
mov cx,ax
pop bx ! restore BX
and ax,#0x3f ! read beyond end of track ?
add ax,t_secs
cmp ax,n_secs
jna intrk ! no -> go on
mov al,n_secs ! read to end of track
sub al,t_sector
inc al
jmp lrd ! read it
intrk: mov al,t_secs ! read all sectors
lrd: push ax ! save AX and BX
push bx
call dord ! read the sector(s)
pop bx ! restore AX and BX and the linear address
pop ax
pop dx
pop cx
jc linerr ! error -> quit
sub t_secs,al ! adjust sector count
jz lindone ! zero -> done
xor ah,ah ! increase linear address
add cx,ax
adc dh,#0
xchg ah,al ! move BX
add ah,ah
add bx,ax
jc interr ! crossing segment boundaries -> error
br lnread ! process remaining sectors
linerr5:pop dx ! discard stack contents
pop cx
pop bx
pop dx
pop cx
ret ! (carry is already set)
linerr3:pop bx ! pop BX and linear address
pop dx
pop cx
interr: xor ax,ax ! zero indicates internal error
linerr: stc ! error
ret
lindone:clc ! no error
ret ! done
dord: mov ah,#2 ! set command
#ifdef DBG_LREAD
push ax
push bx
push cx
push dx
push es
push dx
push cx
push bx
push ax
mov bx,#sax
call say
pop ax
call wout
mov bx,#sbx
call say
pop ax
call wout
mov bx,#scx
call say
pop ax
call wout
mov bx,#sdx
call say
pop ax
call wout
mov bx,#ses
call say
pop ax
call wout
mov bx,#sdone
call say
pop dx
pop cx
pop bx
pop ax
#endif
int 0x13 ! read
ret
n_cyl: .word 0 ! temporary space
n_secs: .word 0
t_drive:.byte 0
t_sector:.byte 0
t_secs: .word 0
lilo/dparam.s 644 0 0 3556 5241226247 11460 0 ustar root root /* dparam.s */
/* Written 1992 by Werner Almesberger */
.text
.globl _main
.org 0x100
_main: mov bl,0x80 ! NUL-terminate the command line
xor bh,bh
mov 0x81(bx),bh
mov bx,#0x81
aloop: mov al,(bx) ! get the next character
inc bx
cmp al,#32 ! space ?
je aloop ! yes -> skip it
cmp al,#48 ! '0' ?
jne error ! no -> invalid
cmpb (bx),#120 ! 'x' ?
je okay ! yes -> okay
cmpb (bx),#88 ! 'X' ?
jne error ! no -> invalid
okay: cmpb 1(bx),#56 ! '8' ?
jne error ! no -> invalid
cmpb 3(bx),#0 ! one more digit ?
jne error ! no -> invalid
mov dl,2(bx) ! get the digit
sub dl,#48 ! convert to a number
cmp dl,#1 ! valid ?
ja error ! no -> error
add dl,#0x80 ! adjust the number
mov ah,#8 ! get the drive parameters
int 0x13
or ah,ah ! error ?
jnz derror ! yes -> display a message
push cx ! save the parameters
push dx
mov al,cl ! number of sectors
and al,#0x3f
xor ah,ah
call decout
call space
pop dx ! number of heads
mov al,dh
inc al
xor ah,ah
call decout
call space
pop ax ! number of cylinders
xchg ah,al
mov cl,#6
shr ah,cl
inc ax
call decout
mov dx,#crlf ! crlf
mov ah,#9
int 0x21
ret ! done
error: mov dx,#errmsg ! display the error message
jmp dispit
derror: mov dx,#invdrv ! display the error message
jmp dispit
space: mov dx,#spc ! display two blanks
jmp dispit
decout: mov bx,#decend ! set the pointer to the end
declp: xor dx,dx ! divide by 10
mov cx,#10
div cx
add dl,#48 ! make a digit
dec bx ! store digit
mov (bx),dl
or ax,ax ! zero ?
jnz declp ! no -> go on
mov dx,bx ! display the string
dispit: mov ah,#9
int 0x21
ret ! done
errmsg: .ascii "usage: dparam 0x80"
.byte 13,10
.ascii " or dparam 0x81"
crlf: .byte 13,10
.ascii "$"
invdrv: .ascii "Invalid drive"
.byte 13,10
.ascii "$"
spc: .ascii " $"
decbuf: .byte 0,0,0,0,0
decend: .ascii "$"
lilo/disktab 644 0 0 516 5251030261 11333 0 ustar root root # /etc/lilo/disktab - LILO disk parameter table
#
# This table contains disk parameters for SCSI disks and non-
# standard parameters of IDE disks. Parameters in disktab
# _always_ override auto-detected disk parameters.
# Dev. BIOS Secs/ Heads/ Cylin- Part.
# num. code track cylin. ders offset
0x800 0x80 32 64 202 0 # /dev/sda
lilo/install.new 755 0 0 53 5310550411 12127 0 ustar root root $ROOT/etc/lilo/lilo -C /etc/lilo/config $*
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/