1016 lines
40 KiB
TeX
1016 lines
40 KiB
TeX
\documentclass[12pt,a4paper]{article}
|
|
\usepackage{times}
|
|
\usepackage{html}
|
|
\title{Getting Linux into Small Machines}
|
|
\author{L.C. Benschop}
|
|
\begin{document}
|
|
\maketitle
|
|
|
|
Copyright \copyright{}2002, L.C. Benschop, Eindhoven, The
|
|
Netherlands. Permission is granted to make verbatim copies of this
|
|
document.
|
|
|
|
\tableofcontents
|
|
|
|
\section{Introduction}
|
|
|
|
This document serves as an instruction to build a minimal Linux system
|
|
for use on rescue diskettes, installation diskettes and embedded
|
|
projects.
|
|
|
|
The Bootdisk Howto from the Linux Documentation Project also describes
|
|
how to build a bootable diskette, but a diskette created in this way
|
|
has a few shortcomings:
|
|
\begin{itemize}
|
|
\item It carries a lot of ballast such as {\tt inittab}, {\tt getty} and
|
|
{\tt login}. For a simple to use rescue disk, these programs and their
|
|
associated configuration files are not necessary.
|
|
\item It contains full featured GNU shell utilities that occupy a lot
|
|
of space.
|
|
\item It contains the real GNU C libraries, which are very large indeed.
|
|
\end{itemize}
|
|
Therefore a boot disk created in this way contains not many useful
|
|
programs and it needs a comparatively large RAM disk to load. If you
|
|
have 8MB of RAM, this works, but you can forget this on a 4MB or even
|
|
2MB machine.
|
|
|
|
There are two excellent software packages that are specially designed
|
|
for saving precious memory and disk space when you are on a tight budget:
|
|
\begin{itemize}
|
|
\item \htmladdnormallinkfoot{Busybox}{http://www.busybox.net} is a
|
|
combination of a Unix shell and many common Unix utility programs in
|
|
a single executable. The size of Busybox is about half that of the
|
|
typical {\tt bash} shell and at that it already contains a few dozen
|
|
Unix commands, ranging from {\tt ls} to {\tt gzip}. These are
|
|
trimmed down versions of course, but adequate in most cases.
|
|
\item \htmladdnormallinkfoot{uClibc}{http://www.uclibc.org} is a
|
|
scaled down Unix library. The GNU C library is huge, has every
|
|
feature on the planet and adheres to every conceivable standard on
|
|
every conceivable platform. uClibc is adequate for many applications
|
|
and uses much less space.
|
|
\end{itemize}
|
|
While the use of Busybox on rescue disks is common, uClibc is rarely
|
|
used. There are toolkits to create Busybox based diskettes, but IMHO
|
|
there is no good instructional document that describes how to create a
|
|
bootable Linux diskette with both Busybox and uClibc. The
|
|
\htmladdnormallinkfoot{{\tt BootE} diskette}{http://www.everywhere.dk}
|
|
is a bootable Linux diskette with {\tt Busybox} and {\tt
|
|
uClibc}. There are no instructions on the site how to
|
|
customize that disk to your needs.
|
|
|
|
In order to achieve huge space savings, we need to recompile
|
|
everything from source.
|
|
|
|
\subsection{The Mission}
|
|
|
|
Suppose we have an old 386 machine in the basement that comes with
|
|
only 4MB of RAM. We want to show our friends that this old beast can
|
|
still run Linux.
|
|
|
|
We must be able to perform the following tasks:
|
|
\begin{itemize}
|
|
\item Partition a hard disk.
|
|
\item Make a swap partition on the hard disk an use it.
|
|
\item Create an ext2 file system on the hard disk and make it usable as the
|
|
root file system.
|
|
\item Mount diskettes and a hard disk.
|
|
\item Edit files.
|
|
\end{itemize}
|
|
|
|
So basically we have everything to install a Linux root file system on
|
|
the hard disk.
|
|
|
|
\subsection{What needs to be on the diskette?}
|
|
|
|
In order to get a Linux system up and running we need the following items:
|
|
\begin{itemize}
|
|
\item A boot loader. This program is loaded by the PC BIOS and this
|
|
makes it possible to load another program, such as the Linux kernel/
|
|
\item the Linux kernel. This is the heart of the operating system.
|
|
\item a root file system. This is the file system that is mounted when
|
|
the kernel is started. The first program that runs (typically {\tt
|
|
/sbin/init} has to be in the root file system. The root file system
|
|
can exist on a diskette, it can be loaded in RAM at boot time or it
|
|
can exist on the hard disk.
|
|
\end{itemize}
|
|
|
|
The root file system has to contain the following items:
|
|
\begin{itemize}
|
|
\item Binaries that we want to run.
|
|
\item Startup scripts and other configuration files.
|
|
\item Shared libraries.
|
|
\item Device files.
|
|
\item Mount points.
|
|
\end{itemize}
|
|
|
|
|
|
\subsection{The Host and Target System}
|
|
|
|
The host system is the computer on which we build the bootable
|
|
diskette. It is assumed to be a fairly modern PC with a modern
|
|
installation of Linux. We will assume that it is a Pentium with at
|
|
least 32MB of RAM.
|
|
|
|
Also we assume that it contains a modern Linux system that contains
|
|
the following software:
|
|
\begin{itemize}
|
|
\item Linux kernel 2.4
|
|
\item recent gcc (2.95 or later)
|
|
\item Loop devices (a kernel feature that allows you to mount a file
|
|
system on a file instead of a block device).
|
|
\item Bzip2
|
|
\item a recent LILO
|
|
\end{itemize}
|
|
|
|
You will need lots of hard disk space. Around 300MB would be
|
|
enough. The unpacked Linux kernel source tree alone takes around 150MB
|
|
these days. Paradoxically enough the end result will fit on a single
|
|
1.44MB diskette.
|
|
|
|
The target system is an old 386 PC with 4MB of RAM or more and zero,
|
|
one or two hard disks.
|
|
|
|
\section{First Preparation}
|
|
|
|
First create a directory where we will build the whole project. I
|
|
chose the name {\tt myboot}. I will use this name throughout the
|
|
document. Type the following command in your home directory:
|
|
\begin{verbatim}
|
|
mkdir myboot
|
|
\end{verbatim}
|
|
|
|
Obtain the following source packages and collect them into the
|
|
directory {\tt myboot}:
|
|
\begin{itemize}
|
|
\item The Linux kernel. In our example we take version 2.4.18, which
|
|
was the latest version at the time of writing. It may be desirable
|
|
to use a kernel from the 2.2 series instead as it requires less
|
|
memory. Even a kernel from the 2.0 series may do the job, it's still
|
|
maintained, but don't ask me for how long. Download it from the
|
|
\htmladdnormallinkfoot{ main kernel site}{http://www.kernel.org}
|
|
\item The small C library
|
|
\htmladdnormallinkfoot{{\tt uClibc}}{http://www.uclibc.org}.
|
|
\item The shell and utilities
|
|
\htmladdnormallinkfoot{{\tt Busybox}}{http://www.busybox.net}.
|
|
\item The utility programs in {\tt util-linux}. These can be found at
|
|
the main kernel site in the kernel archive, the {\tt utils}
|
|
subdirectory.
|
|
\item The package \htmladdnormallinkfoot{{\tt
|
|
e2fsprogs}}{http://e2fsprogs.sourceforge.net} with programs to create
|
|
and repair file systems. .
|
|
\end{itemize}
|
|
|
|
Some of these packages may already be present in your Linux
|
|
distribution. For all packages except {\tt uClibc} and {\tt Busybox}
|
|
this is very likely. But of course there may exist more recent
|
|
versions.
|
|
|
|
After you have downloaded all the sources, your {\tt myboot} directory
|
|
may look like this. Of course you may have different (more recent)
|
|
versions of all programs:
|
|
{\scriptsize
|
|
\begin{verbatim}
|
|
total 27776
|
|
-rw-rw-r-- 1 lennartb lennartb 613464 Jun 9 11:44 busybox-0.60.3.tar.bz2
|
|
-rw-rw-r-- 1 lennartb lennartb 1376698 Jun 12 19:56 e2fsprogs-1.27.tar.gz
|
|
-rw-rw-r-- 1 lennartb lennartb 24161675 Jun 8 19:28 linux-2.4.18.tar.bz2
|
|
-rw-rw-r-- 1 lennartb lennartb 1170790 Jun 8 19:00 uClibc-snapshot.tar.bz2
|
|
-rw-rw-r-- 1 lennartb lennartb 1065574 Jun 9 16:01 util-linux-2.11r.tar.bz2
|
|
\end{verbatim}
|
|
}
|
|
|
|
So let's unpack what we've got. Type the following commands when
|
|
inside the {\tt myboot} directory:
|
|
\begin{verbatim}
|
|
bunzip2 -c busybox-0.60.3.tar.bz2 | tar xvf -
|
|
gunzip -c e2fsprogs-1.27.tar.gz | tar xvf -
|
|
bunzip2 -c linux-2.4.18.tar.bz2 | tar xvf -
|
|
bunzip2 -c uClibc-snapshot.tar.bz2 | tar xvf -
|
|
bunzip2 -c util-linux-2.11r.tar.bz2 | tar xvf -
|
|
\end{verbatim}
|
|
After this you should have the sources of the five packages,
|
|
each in its own subdirectory.
|
|
|
|
Note: the {\tt myboot} directory is assumed to be created under a
|
|
user's home directory. In several places in this text we will use an
|
|
absolute path to this directory and on my system this is
|
|
{\tt /home/lennartb/myboot}. Other users should replace this with their
|
|
own home directory.
|
|
|
|
Note: in this document you see many sequences of shell commands. Of
|
|
course you can put them into shell scripts, so you need not retype
|
|
them when you try to build a modified boot disk.
|
|
|
|
\section{Building uClibc}
|
|
|
|
The trickiest part to get right is probably the C library, especially
|
|
because we want to use shared libraries. The space savings are
|
|
tremendous and once this is done right, you can fit many more
|
|
utilities on a diskette. The directory where the shared libraries exist
|
|
on the target system (where they will be used) is different from the
|
|
directory where they exist on the host system. Without special tricks,
|
|
the binaries that are compiled with {\tt uClibc} won't run on the host
|
|
system.
|
|
|
|
First create the following subdirectories under the {\tt myboot}
|
|
directory.
|
|
\begin{itemize}
|
|
\item {\tt uclibc-dev} is the directory that contains everything you
|
|
need to compile programs with {\tt uClibc}. Int contains the include
|
|
files for the {\tt uClibc} library and special versions of {\tt gcc}
|
|
and similar programs. In fact it is a kind of cross-compiler, albeit
|
|
for the same processor architecture.
|
|
\item {\tt rootfs} is the directory where everything goes that will be
|
|
on your bootable diskette.
|
|
\end{itemize}
|
|
|
|
Next {\tt cd} into the {\tt myboot/uClibc} directory. There run the following
|
|
command:
|
|
\begin{verbatim}
|
|
ln -s extra/Configs/Config.i386 Config
|
|
\end{verbatim}
|
|
|
|
Next edit the {\tt Config} file as follows:
|
|
\begin{itemize}
|
|
\item Your native compiler will probably compile for a 386. If not,
|
|
you can edit the line with CROSS=
|
|
\item Change the line with KERNEL\_SOURCE to
|
|
\begin{verbatim}
|
|
KERNEL_SOURCE=/home/lennartb/myboot/linux
|
|
\end{verbatim}
|
|
It is important that this directory matches the kernel that will
|
|
eventually be used on the boot diskette.
|
|
\item Check the configuration options. They look reasonable at the
|
|
moment, except that you have to set {\tt LFS = true}. Even though
|
|
large file system support seems unnecessary on old 386 machines with
|
|
hard disks well under 2GB, some programs will complain if it is not there.
|
|
\item Below the BIG FAT WARNING: change the line to
|
|
\begin{verbatim}
|
|
SHARED_LIB_LOADER_PATH=/lib.
|
|
\end{verbatim}
|
|
\item Change the line with DEVEL\_PREFIX to
|
|
\begin{verbatim}
|
|
DEVEL_PREFIX=/home/lennartb/myboot/uclibc-dev
|
|
\end{verbatim}
|
|
\end{itemize}
|
|
|
|
Run the following commands to make and install the library. Note that
|
|
we do {\em not} install the library as root as we do not install it in
|
|
a system-wide directory.
|
|
\begin{verbatim}
|
|
make
|
|
make install
|
|
make PREFIX=/home/lennartb/myboot/rootfs install_target
|
|
\end{verbatim}
|
|
|
|
The first command compiles the libraries, the second command installs
|
|
the development code into the uclibc-dev directory and the last
|
|
command installs the shared libraries into the rootfs directory. These
|
|
will end up on the root file system of the bootable diskette.
|
|
|
|
Compiling with uClibc can be as simple as putting the {\tt uclibc-dev}
|
|
directory first in your path and just running {\tt make}. Note that
|
|
you cannot run the programs you have just made on the host system.
|
|
|
|
\section{Building Busybox}
|
|
|
|
First {\tt cd} into the {\tt myboot/busybox-0.60.3} subdirectory.
|
|
|
|
|
|
Edit the file {\tt Conf.h} as follows:
|
|
\begin{itemize}
|
|
\item Add or remove support for programs you do or do not want. For
|
|
each program there is a {\tt \#define BB\_XXX} line that can be
|
|
commented out or not. Uncomment the BB\_VI line, as you would
|
|
probably need an editor. Leave the network related programs
|
|
commented out if you do not enable network support, otherwise
|
|
uncomment them. In our example we will not use network support. It's
|
|
basically your choice what to put in or not. Though it may be
|
|
possible to start Linux with an interactive shell instead of init,
|
|
we will leave the init program in.
|
|
\item Uncomment the {\tt BB\_FEATURE\_USE\_TERMIOS} line.
|
|
\end{itemize}
|
|
|
|
Edit the {\tt Makefile} as follows:
|
|
\begin{itemize}
|
|
\item Append {\tt -m386} to the {\tt CFLAGS\_EXTRA} line.
|
|
\item Uncomment the {\tt CC=} line below the comment about uClibc and
|
|
change it to {\tt CC=/home/lennartb/myboot/uclibc-dev/bin/gcc}.
|
|
\item You could enable LFS support, as you already have selected it in
|
|
the {\tt uClibc} library as well.
|
|
\end{itemize}
|
|
|
|
Now build the program.
|
|
\begin{verbatim}
|
|
make
|
|
make PREFIX=/home/lennartb/myboot/rootfs install
|
|
\end{verbatim}
|
|
|
|
Because you have linked with the dynamic {\tt uClibc} library and
|
|
these are not installed in the host system's {\tt /lib} directory,
|
|
the program cannot run. There is a trick to work around it: by using
|
|
the chroot command, you can run a program whose root directory is the
|
|
specified directory. Become root and type the following command:
|
|
\begin{verbatim}
|
|
/usr/sbin/chroot /home/lennartb/myboot/rootfs /bin/sh
|
|
\end{verbatim}
|
|
The shell that you are now in is the shell inside the\\
|
|
{\tt /home/lennartb/myboot/rootfs} directory. This shell thinks that
|
|
this {\tt rootfs} directory is in fact the root directory: even the
|
|
shared libraries of {\tt uClibc} in the {\tt /lib} directory will be
|
|
found. Type the command {\tt ls /} and it will be clear. Exit the {\tt
|
|
chroot} subshell with Control-D and everything will be back to normal.
|
|
|
|
Now you have most common Unix utilities including an editor and a
|
|
shell and you've spent only 576kB of disk space!
|
|
|
|
\section{Other Essential Binaries}
|
|
|
|
While Busybox offers us many essential Unix utilities, we still miss a
|
|
few essential programs for our mission. We cannot partition a hard
|
|
disk and we cannot create or repair ext2 file systems. Busybox can be
|
|
made to include {\tt mkfs} and {\tt fsck} for Minix file systems, but
|
|
not for the much more common Ext2 file system. Both util-linx and
|
|
e2fsprogs complain if you had not built {\tt uClibc} with large file
|
|
support.
|
|
|
|
First start another shell and type the following command:
|
|
\begin{verbatim}
|
|
export PATH=/home/lennartb/myboot/uclibc-dev/bin:$PATH
|
|
\end{verbatim}
|
|
From now on, the {\tt uClibc} version of {\tt gcc} will be used
|
|
instead of the normal version.
|
|
|
|
For now we need util-linux only for the {\tt fdisk} utility. The build
|
|
procedure is as follows:
|
|
\begin{itemize}
|
|
\item {\tt cd} into the util-linux source directory.
|
|
\item Edit the {\tt MCONFIG} file as follows:
|
|
\begin{itemize}
|
|
\item Change the CPU line near the top of the file to {\tt
|
|
CPU=i386}.
|
|
\item Add another line to the large CFLAGS statement near the
|
|
bottom of the file:
|
|
\begin{verbatim}
|
|
-D__NO_CTYPE \
|
|
\end{verbatim}
|
|
This line must look like the other lines in the same statement,
|
|
including the backslash with a space before it and nothing after
|
|
it. \footnote{This option causes real functions to be used for {\tt
|
|
tolower()} and friends, instead of macros. The macros
|
|
evaluate their arguments twice, where {\tt fdisk} uses a call to an
|
|
input function as argument to {\tt tolower()}.}
|
|
\end{itemize}
|
|
\item Run make.
|
|
\item Make stops with an error while trying to build {\tt mount}. We
|
|
already have a mount in {\tt busybox}, so we leave it that way.
|
|
\item {\tt cd} into the fdisk directory.
|
|
\item Run make.
|
|
\item Move the file {\tt fdisk} to the directory\\
|
|
{\tt /home/lennartb/myboot/roofts/sbin}.
|
|
\end{itemize}
|
|
|
|
Now we will build e2fsprogs as follows:
|
|
\begin{itemize}
|
|
\item Create a directory named {\tt build} under the e2fsprogs source
|
|
directory and {\tt cd} to it.
|
|
\item Configure and build the programs:
|
|
\footnote{The BUILD\_CC option specifies that we want to use the normal
|
|
{\tt gcc} for building a certain program that must be run on the
|
|
host system. Otherwise it would be linked with {\tt uClibc} and
|
|
would not run.}
|
|
\begin{verbatim}
|
|
./configure
|
|
make BUILD_CC=/usr/bin/gcc
|
|
\end{verbatim}
|
|
\item Strip and move e2fsck and mke2fs to the {\tt rootfs} directory.
|
|
\begin{verbatim}
|
|
strip e2fsck/e2fsck.shared
|
|
mv e2fsck/e2fsck.shared \
|
|
/home/lennartb/myboot/rootfs/sbin/e2fsck
|
|
strip mke2fs
|
|
mv misc/mke2fs /home/lennartb/myboot/rootfs/sbin
|
|
\end{verbatim}
|
|
|
|
\end{itemize}
|
|
|
|
This is the time to build any other programs you will need. Link them
|
|
with {\tt uClibc} and move them to the one of the binary
|
|
subdirectories in the {\tt myboot/rootfs} directory. If linking with
|
|
{\tt uClibc} does not work, try to link statically using the ordinary
|
|
{\tt gcc}.
|
|
|
|
|
|
\section{Populating the Root File System}
|
|
|
|
|
|
The binaries and libraries are already installed in the {\tt rootfs}
|
|
directory. Now we will complete the root file system.
|
|
First create the remaining directories in rootfs.
|
|
\begin{verbatim}
|
|
cd /home/lennartb/myboot/rootfs
|
|
mkdir dev tmp etc proc mnt etc/init.d
|
|
\end{verbatim}
|
|
|
|
Add the device nodes. We will only add the necessary device nodes: two
|
|
floppy disks, two hard disks with 8 partitions each and four
|
|
terminals. Further we need some memory related devices and a ram
|
|
disk. Become root and cd to the {\tt dev} subdirectory in the {\tt
|
|
myboot/rootfs} file system.
|
|
\begin{verbatim}
|
|
mknod fd0 b 2 0
|
|
mknod fd1 b 2 1
|
|
mknod hda b 3 0
|
|
mknod hda1 b 3 1
|
|
mknod hda2 b 3 2
|
|
mknod hda3 b 3 3
|
|
mknod hda4 b 3 4
|
|
mknod hda5 b 3 5
|
|
mknod hda6 b 3 6
|
|
mknod hda7 b 3 7
|
|
mknod hda8 b 3 8
|
|
mknod hdb b 3 64
|
|
mknod hdb1 b 3 65
|
|
mknod hdb2 b 3 66
|
|
mknod hdb3 b 3 67
|
|
mknod hdb4 b 3 68
|
|
mknod hdb5 b 3 69
|
|
mknod hdb6 b 3 70
|
|
mknod hdb7 b 3 71
|
|
mknod hdb8 b 3 72
|
|
mknod tty c 5 0
|
|
mknod console c 5 1
|
|
mknod tty1 c 4 1
|
|
mknod tty2 c 4 1
|
|
mknod tty3 c 4 1
|
|
mknod tty4 c 4 1
|
|
mknod ram b 1 1
|
|
mknod mem c 1 1
|
|
mknod kmem c 1 2
|
|
mknod null c 1 3
|
|
mknod zero c 1 5
|
|
\end{verbatim}
|
|
|
|
Add files in the {\tt /etc} subdirectory. The {\tt init} program from
|
|
{\tt busybox} works without a login procedure, so the {\tt passwd} and
|
|
{\tt group} files are not really needed. You could of course create
|
|
single line versions for the root user and group. Even the {\tt
|
|
inittab} file is not essential and {\tt busybox} provides a
|
|
reasonable default. You are free to copy the {\tt scripts/busybox}
|
|
file from the source directory and customize it.
|
|
The only file I added in {\tt /etc} was {\tt init.d/rcS}.
|
|
\begin{verbatim}
|
|
#!/binsh
|
|
mount -t proc none /proc
|
|
\end{verbatim}
|
|
|
|
Make all files in the root file system owned by root:
|
|
\begin{verbatim}
|
|
chown -R 0:0 /home/lennartb/myboot/rootfs
|
|
\end{verbatim}
|
|
|
|
Now we have a complete root file system in a directory. We still need
|
|
a kernel and a way to boot. Further we need to transfer the file
|
|
system to a floppy disk.
|
|
|
|
\section{Building a Kernel}
|
|
|
|
Now it is time to build a kernel. For the target system we will build
|
|
a kernel that is different from the host system kernel. W build it
|
|
under the {\tt myboot} directory. First {\tt cd} to the {\tt
|
|
myboot/linux} subdirectory.
|
|
|
|
The most important job is configuring the kernel. Run the following
|
|
command:
|
|
\begin{verbatim}
|
|
make menuconfig
|
|
\end{verbatim}
|
|
Instead of {\tt menuconfig} you can use {\tt config} (not
|
|
recommended!) or {\tt xconfig}. This will give a usable kernel for the
|
|
target system.
|
|
\begin{itemize}
|
|
\item Processor type menu: processor family must be 386, enable math
|
|
emulation, switch off everything else. Most 386 systems have no 387
|
|
coprocessor, so they do need math emulation.
|
|
\item General setup menu: switch off networking support, PCI support,
|
|
system V IPC
|
|
and sysctl support. Support ELF binaries, other formats can be
|
|
disabled.
|
|
\item Code maturity, Module support, Memory Technology, Parallel port,
|
|
Plug and play, Multi-device, Telephony, SCSI, I2O, Amateur radio,
|
|
ISDN, Old CDROM, Input core, Multimedia, Sound, USB and kernel hacking
|
|
submenus: disable everything.
|
|
\item Block device submenu: support floppy, RAM disk and initial RAM
|
|
disk.
|
|
\item ATA/IDE/MFM/RLL submenu: support, keep everything under the
|
|
ATA/IDE\ldots{} block devices submenu the default.
|
|
\item Character devices submenu: Support virtual terminal, console on
|
|
virtual terminal, Unix 98 PTY, disable everything else.
|
|
\item File systems. Keep second extended, proc and dev PTS enabled. If
|
|
you want to mount DOS diskettes, enable fat, msdos and maybe
|
|
vfat. If you want to mount a CDROM, enable ISO9660.
|
|
\item Console drivers. Keep VGA text console enabled.
|
|
\item Exit an say Yes to save changes.
|
|
\end{itemize}
|
|
Of course you must adapt the configuration to the target system you
|
|
are using. If your target system has PCI, it would be better to
|
|
enable it. In that case, you probably have a 486DX or a Pentium, so
|
|
the math emulation may go. If you have SCSI on your target system, you
|
|
should of course enable support for it and for the host adapted you
|
|
are using. If you have SCSI and no IDE devices installed, you can
|
|
disable ATA/IDE/MFM/RLL support.
|
|
|
|
Now we only need to build the kernel:
|
|
\begin{verbatim}
|
|
make clean
|
|
make dep
|
|
make zImage
|
|
\end{verbatim}
|
|
The kernel described here should be around 400kB and it should work
|
|
with {\tt make zImage}. Use {\tt make bzImage} instead if you build a
|
|
kernel with more features, e.g. networking support.
|
|
|
|
\section{Making a Bootable Diskette}
|
|
|
|
We will describe three methods to boot Linux from a diskette.
|
|
\begin{itemize}
|
|
\item Booting the kernel directly from a diskette and mount a root
|
|
file system on a different diskette.
|
|
\item Booting the kernel with LILO and mount a root file system on a
|
|
diskette (possibly the same diskette).
|
|
\item Booting the kernel with LILO and add a RAM disk for the root
|
|
file system.
|
|
\end{itemize}
|
|
Instead of LILO we could use another boot loader, such as SYSLINUX or
|
|
GRUB. This is considered to be outside the scope of this text.
|
|
|
|
For the boot diskettes we have to
|
|
format 1.44MB floppy disks or take formatted disks that may be
|
|
erased. In Linux there are two programs to format a diskette. One program is
|
|
{\tt fdformat}. A diskette is formatted as follows:
|
|
\begin{verbatim}
|
|
fdformat /dev/fd0H1440
|
|
\end{verbatim}
|
|
Some distributions have {\tt superformat} instead. This is used as follows:
|
|
\begin{verbatim}
|
|
superformat --hd /dev/fd0
|
|
\end{verbatim}
|
|
We assume 3.5'' HD diskettes and we only format them in the standard
|
|
way (1440kB), so we do not try to get a few more sectors per track or
|
|
a few more tracks.
|
|
|
|
All commands in this section should be done as root.
|
|
|
|
\subsection{Booting Linux directly from a diskette}
|
|
|
|
We do not have to use a complicated boot loader such a LILO in order
|
|
to boot a Linux system. The Linux kernel has its own primitive boot
|
|
loader. When the kernel is transferred directly to a diskette with the
|
|
{\tt dd} command, the kernel can boot itself. This way we cannot
|
|
supply a command line and it works only with diskettes. We also cannot
|
|
use the {\tt initrd} feature, but there is a different way of loading
|
|
a RAM disk, which we will not discuss (it is discussed in the Bootdisk
|
|
HOWTO).
|
|
|
|
First we have to create a file system on the root diskette and
|
|
transfer the files to it. Type the following commands:
|
|
\begin{verbatim}
|
|
mke2fs /dev/fd0
|
|
mkdir /home/lennartb/myboot/rootfs/mnt
|
|
mount /dev/fd0 /home/lennartb/myboot/mnt
|
|
cp -a /home/lennartb/myboot/rootfs/* \
|
|
/home/lennartb/myboot/mnt
|
|
umouunt /dev/fd0
|
|
\end{verbatim}
|
|
The root file system will be mounted read-only. If this is not
|
|
desired, add the following line to the file {\tt etc/init.d/rcS} while
|
|
the floppy is mounted:
|
|
\begin{verbatim}
|
|
mount -o remount /dev/fd0 /
|
|
\end{verbatim}
|
|
|
|
Next we create the boot disk. With a different diskette in the drive
|
|
type the following command:
|
|
\begin{verbatim}
|
|
dd if=/home/lennartb/myboot/linux/arch/boot/zImage \
|
|
of=/dev/fd0
|
|
rdev /dev/fd0 /dev/fd0
|
|
\end{verbatim}
|
|
The {\tt rdev} command selects the device on which the root file
|
|
system should be mounted by the kernel after booting. We could use the
|
|
following command to make the diskette mount the root file system on
|
|
the first hard disk partition.
|
|
\begin{verbatim}
|
|
rdev /dev/fd0 /dev/hda1
|
|
\end{verbatim}
|
|
|
|
\subsection{LILO bootable disk}
|
|
|
|
First make the root diskette as described in the previous
|
|
section. There are two ways to proceed:
|
|
\begin{itemize}
|
|
\item Mount the root diskette and install the kernel and LILO on
|
|
it. This way we have a self-contained diskette that boots and has
|
|
the root file system. It works for the kernel and the utilities as
|
|
described in this article, but you would quickly run out of disk
|
|
space when adding more features to the kernel or more utilities to
|
|
the root file system.
|
|
\item {\tt mke2fs} a different diskette for the kernel and LILO. This
|
|
way we still have two diskettes and more space on each.
|
|
\end{itemize}
|
|
The LILO diskette is either the root diskette to which we will add
|
|
LILO or the separate diskette on which we will install LILO.
|
|
|
|
Mount the LILO diskette and add the kernel and boot loader to it:
|
|
\begin{verbatim}
|
|
mount /dev/fd0 /home/lennartb/myboot/mnt/
|
|
mkdir /home/lennartb/myboot/mnt/boot
|
|
cp /home/lennartb/myboot/linux/arch/i386/boot/zImage \
|
|
/home/lennartb/myboot/mnt/boot
|
|
cp /boot/lilo/boot.b /home/lennartb/myboot/mnt/boot
|
|
\end{verbatim}
|
|
|
|
Create the file {\tt /home/lennartb/myboot/lilo.conf} as follows:
|
|
\begin{verbatim}
|
|
boot=/dev/fd0
|
|
install=/home/lennartb/myboot/mnt/boot/boot.b
|
|
map=/home/lennartb/myboot/mnt/boot/map
|
|
delay=100
|
|
compact
|
|
image=/home/lennartb/myboot/mnt/boot/zImage
|
|
label=linux
|
|
root=/dev/fd0
|
|
\end{verbatim}
|
|
All relevant files mentioned in {\tt lilo.conf} are on the mounted diskette.
|
|
The {\tt delay} option will wait 10 seconds, so we have the
|
|
opportunity to type a command line in LILO. The {\tt compact} option
|
|
makes loading much faster. Try it without and compare.
|
|
|
|
Run LILO. This will add a {\tt map} file to the {\tt /boot} directory
|
|
on the diskette and it will add a boot sector to the diskette. The
|
|
boot sector will load the loader in boot.b, this will load the map
|
|
file and the map file contains a list of sectors of the kernel, so
|
|
this can be loaded.
|
|
\begin{verbatim}
|
|
lilo -C /home/lennartb/myboot/lilo.conf
|
|
\end{verbatim}
|
|
|
|
Finally unmount the LILO diskette.
|
|
\begin{verbatim}
|
|
unount /dev/fd0
|
|
\end{verbatim}
|
|
|
|
\subsection{RAM disk}
|
|
|
|
A RAM disk has the following advantages.
|
|
\begin{itemize}
|
|
\item Once the system is booted, programs will load faster.
|
|
\item Once the system is booted, the diskette can be removed from the
|
|
drive. Therefore the floppy drive can be used to load other programs
|
|
or to restore a hard disk partition from backup diskettes.
|
|
\item The RAM disk image can be stored compressed on the diskette. A
|
|
full 1.44MB or even 2MB file system can be stored compressed on a
|
|
diskette together with a kernel. A compressed 4MB or 8MB file system
|
|
is also possible as long as it is not completely filled. After
|
|
booting the system, you can copy programs from other diskettes into
|
|
the RAM disk.
|
|
\end{itemize}
|
|
|
|
The RAM disk has the following disadvantages:
|
|
\begin{itemize}
|
|
\item It requires more RAM to run. The RAM disk configuration
|
|
described in this system will boot on a system with 4MB of RAM, but
|
|
this is pretty much the limit. More kernel features or more
|
|
utilities would make this RAM disk unusable on a 4MB system.
|
|
\item It requires more steps to create or to adapt the root file system.
|
|
\item Changes made to the root file system are not permanent. This is
|
|
either an advantage (security) or a disadvantage (configuration
|
|
changes are not possible).
|
|
\end{itemize}
|
|
|
|
First we have to create an image file for the RAM disk. We limit its
|
|
size to 1000K, so it still runs on a 4MB machine. Create a file system
|
|
on the image file. The {\tt -N 200} option is necessary to create
|
|
enough inodes on the file system, as there are a lot of symbolic links.
|
|
\begin{verbatim}
|
|
dd if=/dev/zero of=/home/lennartb/myboot/root.img \
|
|
bs=1k count=1000
|
|
mke2fs -F -N 200 /home/lennartb/myboot/root.img
|
|
\end{verbatim}
|
|
|
|
Next mount the image file using a loop device and copy all files of
|
|
the root file system to it. The loop option to mount makes it possible
|
|
to mount a regular file as if it were a block device.
|
|
\begin{verbatim}
|
|
mount -o loop /home/lennartb/myboot/root.img \
|
|
/home/lennartb/myboot/mnt
|
|
cp -a /home/lennartb/myboot/rootfs/* \
|
|
/home/lennartb/myboot/mnt
|
|
umount /home/lennartb/myboot/mnt
|
|
\end{verbatim}
|
|
|
|
Compress the root file system image. This image file will be copied to
|
|
a diskette.
|
|
\begin{verbatim}
|
|
gzip -9 /home/lennartb/myboot/root.img
|
|
\end{verbatim}
|
|
|
|
Create a new LILO diskette, mount it and add the kernel, root file
|
|
system image and boot loader to it:
|
|
\begin{verbatim}
|
|
mke2fs /dev/fd0
|
|
mount /dev/fd0 /home/lennartb/myboot/mnt/
|
|
mkdir /home/lennartb/myboot/mnt/boot
|
|
cp /home/lennartb/myboot/linux/arch/i386/boot/zImage \
|
|
/home/lennartb/myboot/mnt/boot
|
|
cp /home/lennartb/myboot/root.img.gz \
|
|
/home/lennartb/myboot/mnt/boot
|
|
cp /boot/lilo/boot.b /home/lennartb/myboot/mnt/boot
|
|
\end{verbatim}
|
|
|
|
Create the file {\tt /home/lennartb/myboot/lilo-initrd.conf} as follows:
|
|
\begin{verbatim}
|
|
boot=/dev/fd0
|
|
install=/home/lennartb/myboot/mnt/boot/boot.b
|
|
map=/home/lennartb/myboot/mnt/boot/map
|
|
delay=100
|
|
compact
|
|
image=/home/lennartb/myboot/mnt/boot/zImage
|
|
label=linux
|
|
root=/dev/ram
|
|
initrd=/home/lennartb/myboot/mnt/boot/root.img.gz
|
|
image=/home/lennartb/myboot/mnt/boot/zImage
|
|
label=noram
|
|
root=/dev/fd0
|
|
\end{verbatim}
|
|
The configuration file is almost the same, except for the {\tt initrd}
|
|
option. This causes the boot loader to load a RAM disk image into
|
|
memory. The Linux kernel will decompress it to a RAM disk device and
|
|
mount this as the root file system \footnote{The {\tt initrd} feature
|
|
makes it possible to mount the root file system twice, once on the
|
|
RAM disk loaded by the boot loader and once on another device (most
|
|
likely a disk partition). The RAM disk can contain an initialization
|
|
routine to load the required modules to mount the root disk. This
|
|
two stage root file system feature is not used here.}.
|
|
Further we added a {\tt noram} option, so it is also possible to use this
|
|
LILO diskette without a RAM disk.
|
|
|
|
Run LILO:
|
|
\begin{verbatim}
|
|
lilo -C /home/lennartb/myboot/lilo-initrd.conf
|
|
\end{verbatim}
|
|
|
|
Finally unmount the LILO diskette:
|
|
\begin{verbatim}
|
|
unount /dev/fd0
|
|
\end{verbatim}
|
|
|
|
\section{Using the Boot Disks}
|
|
|
|
First boot Linux by putting the appropriate Linux diskette into the
|
|
floppy drive.
|
|
\begin{itemize}
|
|
\item If you boot from a diskette without LILO, you should see a
|
|
``Loading'' message right away. After some disk activity you should
|
|
see the message ``Uncompressing Linux'' and a little later you
|
|
should see the kernel messages. Next it prompts for the root
|
|
diskette. Remove the boot disk and insert the root diskette and press
|
|
enter.
|
|
\item If you boot from a diskette with LILO, you should see the LILO
|
|
message. If you press the space bar, you should see the boot prompt
|
|
from LILO, if you don't you should see the message ``Loading linux''
|
|
after 10 seconds. After some disk activity you should see the
|
|
``Uncompressing Linux'' message, some kernel messages and next the
|
|
kernel will prompt for a root diskette. If the LILO diskette
|
|
contains the root file system, you just press enter, otherwise you
|
|
have to swap disks first.
|
|
\item If you boot from a diskette with LILO and a RAM disk, everything
|
|
starts the same as in the previous case. Instead of prompting you
|
|
for a boot disk, the kernel should display a message that a
|
|
compressed RAM disk image was found. It automatically proceeds after
|
|
decompressing.
|
|
\end{itemize}
|
|
As soon as the root file system is mounted, you should see a message
|
|
from Busybox. A few seconds later you are invited to press
|
|
enter. After you press enter, you get a root shell prompt, which
|
|
should be very familiar. With the function keys ALT-F1, ALT-F2, ALT-F3
|
|
and ALT-F4 you can switch to four virtual terminals and you should be
|
|
able to get a shell prompt on all four of them.
|
|
|
|
WARNING: If your root file system is on a floppy disk (you are not using a RAM
|
|
disk), do not remove this diskette from the drive when Linux is
|
|
running. If you use a RAM disk or if you moved all of your root file
|
|
system to the hard disk and booted with the option {\tt
|
|
root=/dev/hd??}, then it is OK to remove the diskette as soon as
|
|
Linux has started.
|
|
|
|
Type the {\tt reboot} command in order to shut the system
|
|
down. If you are using a root file system on a diskette,
|
|
you should wait until the PC has rebooted before removing the
|
|
diskette.
|
|
|
|
What we can do is installing the linux root file system on the hard
|
|
disk. First we have to (re)partition the hard disk. Type the following
|
|
command:
|
|
\begin{verbatim}
|
|
fdisk /dev/hda
|
|
\end{verbatim}
|
|
While inside {\tt fdisk} use the {\tt p} command to show the current
|
|
partition table. Maybe you find an old DOS partition that you still
|
|
want to backup. If so, quit {\tt fdisk} now using the {\tt q}
|
|
command. If you can part with that old DOS partition, you can delete
|
|
partitions with the {\tt d} command and create new partitions with the
|
|
{\tt n} command. Finally you can write the modified partition table
|
|
with the {\tt w} command. Using {\tt fdisk} you should be able to
|
|
create the following partitions:
|
|
\begin{itemize}
|
|
\item A swap partition (set type to 0x82 with the {\tt t} command) of
|
|
around 16MB. Suppose this is partition 2 ({\tt /dev/hda2}).
|
|
\item A Linux partition occupying the rest of the disk. Suppose this
|
|
is partition 1 ({\tt /dev/hda1}).
|
|
\end{itemize}
|
|
|
|
After partitioning the hard disk, create a swap partition with the
|
|
{\tt mkswap} command, create an ext2 file system and copy all data to
|
|
it. Type the following commands. Of course we assume that the Linux
|
|
partition is {\tt /dev/hda1} and the swap partition is {\tt
|
|
/dev/hda2}. Otherwise you must supply appropriate device names.
|
|
\begin{verbatim}
|
|
mkswap /dev/hda2
|
|
swapon /dev/hda2
|
|
mke2fs /dev/hda1
|
|
mount /dev/hda1 /mnt
|
|
mkdir /mnt/proc /mnt/mnt
|
|
cp -a /bin /sbin /usr /etc /lib /dev /tmp /mnt
|
|
\end{verbatim}
|
|
|
|
Edit the file {\tt /mnt/etc/init.d/rcS}. If you haven't learned {\tt
|
|
vi} by now, tough luck.
|
|
\begin{verbatim}
|
|
#!/bin/sh
|
|
mount -a
|
|
swapon -a
|
|
\end{verbatim}
|
|
|
|
Edit the file {\tt /mnt/etc/fstab} as follows:
|
|
\begin{verbatim}
|
|
/dev/hda1 / ext2 defaults 0 0
|
|
none /proc proc defaults 0 0
|
|
/dev/hda2 swap swap defaults 0 0
|
|
\end{verbatim}
|
|
|
|
Now we can shut the system down.
|
|
\begin{verbatim}
|
|
umouunt /dev/hda1
|
|
reboot
|
|
\end{verbatim}
|
|
|
|
Reboot the system with the boot diskette in the drive.
|
|
|
|
As soon as you see the word LILO, press the SHIFT key. Now you see a
|
|
boot prompt. If you use a boot diskette without a RAM disk, type:
|
|
\begin{verbatim}
|
|
linux root=/dev/hda1
|
|
\end{verbatim}
|
|
|
|
If you use a boot diskette with a RAM disk, type this at the boot prompt:
|
|
\begin{verbatim}
|
|
noram root=/dev/hda1
|
|
\end{verbatim}
|
|
|
|
If you have a boot diskette without LILO, you have to go to the host
|
|
system and change the root device using the {\tt rdev} command:
|
|
\begin{verbatim}
|
|
rdev /dev/fd0 /dev/hda1
|
|
\end{verbatim}
|
|
After this, reboot the target system with the modified diskette.
|
|
|
|
In any case, your system should now mount the root file system on your
|
|
hard disk and your floppy drive will be free to mount other diskettes,
|
|
so you can copy more files to the hard disk.
|
|
|
|
\section{And Further}
|
|
|
|
We showed you how to create a boot diskette with one set of
|
|
features. Now you know how to do this, you should be able to customize
|
|
it to your needs. You can turn it into a full featured rescue disk, an
|
|
installation disk for your brand new Linux distribution, a
|
|
demonstration disk or an embedded project, such as a router or print
|
|
server.
|
|
|
|
First try to add kernel module support. Modules come in very handy for
|
|
devices that are seldom used or are only available on some target
|
|
systems. Serial ports, network adapters and SCSI features may be
|
|
candidates for compiling as modules, as well as additional file
|
|
systems. In order to use modules you have to
|
|
do the following:
|
|
\begin{itemize}
|
|
\item Reconfigure the kernel with module support enabled. Configure
|
|
certain features to be compiled as modules.
|
|
\item Rebuild the kernel.
|
|
\item Run the additional make step {\tt make modules}.
|
|
\item Copy the kernel to the boot disk (and run LILO if necessary).
|
|
\item Copy the modules to the root file system or a different
|
|
diskette.
|
|
\item Rebuild busybox with the {\tt insmod} and {\tt rmmod} commands
|
|
enabled. Move this to the root file system as well.
|
|
\item If you use a RAM disk, you should recreate a RAM disk image,
|
|
compress it and rerun LILO on your boot disk . If you hadn't made a
|
|
shell script to perform all these tasks, you should do by now.
|
|
\end{itemize}
|
|
One additional feature that you might try (it only exists in 2.4
|
|
kernels) is the {\tt devfs} file system. Instead of a {\tt /dev}
|
|
directory with hundreds of useless device node you mount a pseudo file
|
|
system on the {\tt /dev} directory, not unlike the {\tt /proc} file
|
|
system. There the device nodes appear for only the devices that exist.
|
|
|
|
After module support you may want to add network support. Once you
|
|
have added an Ethernet adapter to your old 386, you can connect it to
|
|
your LAN and you do not need diskettes so often. With a little bit of
|
|
luck, this still runs on a 4MB machine, but forget about using a RAM
|
|
disk.
|
|
\begin{itemize}
|
|
\item Rebuild the kernel with networking enabled. Of course you have
|
|
to rebuild the modules as well.
|
|
\item Rebuild Busybox with network commands enabled (ifconfig, telnet,
|
|
ping etc.)
|
|
\item Copy all relevant files to their respective places.
|
|
\item Recreate the RAM disk image and rerun LILO if appropriate.
|
|
\end{itemize}
|
|
|
|
You can add additional programs and libraries to the target system.
|
|
\begin{itemize}
|
|
\item Many programs need {\tt curses}. The {\tt ncurses} library is reported
|
|
to be usable with {\tt uClibc}. You must recompile it in order to
|
|
achieve this. You will probably need a stripped down {\tt termcap} file on
|
|
your target system as well.
|
|
\item With {\tt ncurses} and the standard libraries of {\tt uClibc},
|
|
you should really be able to compile a lot of programs that do not
|
|
require X.
|
|
\item Some make files try to run the programs you have just
|
|
built. This can be a problem. It should be possible to copy the {\tt
|
|
uClibc} shared libraries to the {\tt /lib} directory of the host
|
|
system, as their names are different from the {\tt glibc}
|
|
libraries. The programs linked against {\tt glibc} will still work
|
|
and the {\tt uClibc} programs will work too. I just haven't tried
|
|
this, so don't do it on a life-critical system or if you haven't
|
|
made a backup.
|
|
\item Even {\tt gcc} and {\tt X} are reported to work with {\tt
|
|
uClibc}, so give them a try! A target system with {\tt uClibc} as
|
|
the only C library should therefore be able to run a C development
|
|
environment and X. Building this is certainly not for beginners.
|
|
\end{itemize}
|
|
|
|
The RAM disk version of the boot disk runs on a 4MB machine, the
|
|
version without RAM disk should run with 3MB or RAM, but nothing so
|
|
far has run on a machine with just 2MB of RAM. In the good old days,
|
|
people ran Linux routinely on such machines and it should still be
|
|
possible with modern (if not the newest) software. Some hints:
|
|
\begin{itemize}
|
|
\item Do not use a RAM disk.
|
|
\item Remove more features from the kernel. RAM disk support can be
|
|
removed, use the disk-only driver instead of the more functional IDE
|
|
driver, remove file systems such as FAT and ISO9660. If you do have
|
|
a 387 in that 2MB box, get rid of math emulation.
|
|
\item Use an older kernel, 2.2 or even 2.0. Note: if you use 2.0,
|
|
remember to use the {\tt -O none} option on mke2fs if you make a
|
|
file system for the target system. Kernel 2.0 does not understand
|
|
some features added by later kernels.
|
|
\item Remove more functions from busybox. This should not help much as
|
|
busybox will be demand loaded. Parts that are not demanded, will not
|
|
be loaded. It may help to a certain degree. Features line color {\tt
|
|
ls} and command line editing can be removed and a more primitive
|
|
shell can be utilized.
|
|
\item Remove init and start {\tt /bin/sh} directly at startup.
|
|
\item If this lets you do do {\tt fdisk}, {\tt mkswap} and {\tt
|
|
swapon}, you can get swapping enabled on the target system. From
|
|
there you should be fine.
|
|
\end{itemize}
|
|
|
|
\section{Other Useful Resources}
|
|
|
|
This article should have shown you how to create useful bootable
|
|
diskettes and minimal Linux systems with just the programs you
|
|
need. You cannot be without the following resources:
|
|
\begin{itemize}
|
|
\item \htmladdnormallinkfoot{Linux from
|
|
scratch}{http://www.linuxfromscratch.org}.
|
|
If you
|
|
got the taste of creating your own Linux system, one program at a
|
|
time, one file at a time, compiling everything from source, then this
|
|
is the next big thing. This site contains a detailed instruction how
|
|
to compile a complete Linux system completely from source, including
|
|
the libraries, C compiler and utilities. The target system is created on
|
|
the hard disk and not on a diskette.
|
|
\item \htmladdnormallinkfoot{Freshmeat}{
|
|
http://www.freshmeat.net}. This site
|
|
contains an index of almost all programs available for Linux. Most
|
|
open source programs can be found there.
|
|
\item \htmladdnormallinkfoot{Linuxdoc}{http://www.linuxdoc.org}.
|
|
This site contains all Linux related documentation you ever wanted.
|
|
\item \htmladdnormallinkfoot{My
|
|
homepage}{http://www.xs4all.nl/\~{}lennartb} contains the online
|
|
version of this document.
|
|
\end{itemize}
|
|
|
|
\end{document} |