The Debian installer is highly modular, and modules are key to its design.
Details about modules (udebs) are explained in modules.txt. The installer
initrds are themselves built up out of udebs which are unpacked during the
build process by the Makefile in installer/build/. And once the installer
is booted, it typically loads more udebs from available media or the
network. This use of modules makes it easy to change and extend the
installer, and lets different parts of the installer be maintained by
different people, just as different Debian packages are maintained. One way
to think of the installer is as a miniature Linux distribution.

Another important design choice was to use debconf for all user interaction
within the installer. This ensures that the entire installer has a
consistent, easily translated look. It also allows the user interface to
be changed by providing a new debconf frontend. One downside to this design
choice is that Debconf is a relatively simplistic user interface and this
can make it hard to reach the level of user interface polish available with
a full-fledged GUI toolkit.

Other key benefits of using debconf for the installer's interface include
the use of debconf priorities, which can be used to hide most unimportant
questions, or provide an expert mode install by asking them all. Debconf
preseeding can even be used to automate installs. Since debconf is also the
standard for interaction in Debian itself, the UI remains consistent after
the base system install.

The installer boots from an initrd (loaded from CD, network, USB keychain,
floppies, etc). To allow loading modules on the fly and storing state, it
requires a writable filesystem, and so it typically runs in a RAM disk. One
downside to this is that the entire installer's filesystem is present in
RAM, which makes it hard to support very low memory installs (in the 16 MB
range).

The installer boots more or less directly into the debconf environment,
and the entire rest of the installation is driven by the main-menu program.
This creates a menu of all modules that register as menu items, ordered
mostly by dependency (but see menu-item-numbers.txt). The installation
process is then a simple matter of stepping down this list, running each
menu item in turn. This may be done by the user manually (who can choose to
run items out of turn too), or at higher priority levels, is done behind
the scenes without interaction by main-menu. 

Running a menu item really means configuring (or reconfiguring) the udeb
that provides it, and so all of a menu item's dependencies must be
configured before it. Thus, the installer doesn't allow downloading things
from the network until the network is configured, or setting up the target
filesystem until disks are partitioned.

The early stages of the install process are concerned with getting minimal
information about the user to let them use the installer (things like
language, location, and keyboard layout), and then loading udebs from
available media or the network. Most initrds are built from only the
minimum set of modules needed to perform these tasks.

Loading udebs is taken care of by the anna program (Anna's Not Nearly Apt).
It in turn relies on retriever modules, which take care of scanning media
or the network for available udebs and retrieving them (see retriever.txt).
Anna chooses which of the available udebs to load, based on dependencies
and priority information, gets them retrieved, and unpacks them. This
process may be repeated using multiple retrievers, for example modules
might first be retrieved from a driver floppy, and those drivers be used to
load the rest of the installer from CD. After anna's final run, the
complete installer environment has been bootstrapped, and the Debian
installer can begin.

Of course to load modules from CD or the network, some hardware detection
needs to be done. The installer leaves hardware detection to just another
installer module; currently we use discover for most hardware detection.
Hardware detecton is run multiple times, first to detect hardware that can
be accessed by the kernel modules on the initrd, and later to detect all
hardware accessible by the full d-i environment as bootstrapped by anna.

The Debian installation process has three major steps: partitioning disks,
installing packages, and installing the boot loader. Disk partitioning (and
formatting and mounting to /target) is handled by an installer module or
modules, currently the partman suite on most architectures (see the
partman/ directory for docs). Package installation is done by
base-installer, which calls debootstrap to do most of the work of
installing a minimal base system and then installs a kernel; and also by
pkgsel, which installs a more extensive set of packages, mostly by calling
tasksel. Boot loader installation is handled by a number of
architecture-specific modules, such as grub-installer, lilo-installer, and
yaboot-installer.

The installation finishes up in finish-install, which reboots into the
installed system.
