Next Previous Contents

4. Setting up the client's resources

This section explains how the client's resources are set up on your server. First of all, an install-client is supposed to boot from its network card, thus the DHCP, NFS, and TFTP services should be installed and properly set up on your server(s), refer to section Setting up the server for details. Although the installation is based on the Debian GNU/Linux "potato" release, it can be employed on a server running different linux distributions as well; we have set up a fully functional server system on SuSE 6.3 as well as on Debian GNU/Linux 2.1 using the same scripts.

To give you a brief overview of the installation process:

  1. The client boots via the network (see section How the client boots for details). Then, the net-boot loader loads the kernel bzImage and the initial RAM disk image initrd.gz. (By changing this initrd.gz additional modules can be loaded as well e.g. to enable PCMCIA support.)
  2. The ash-script /linuxrc is executed (in fact, this can be any valid executable; it is run with uid 0 and can do basically everything init can do):
  3. As linuxrc terminates, the "real" root file system (e.g. /dev/hda1/) is mounted and the 2nd part of the installation begins: The left packages are installed and configured.
  4. kiss is stopped.
  5. Installation is completed!

4.1 How to create a reasonable client kernel

The kernel compilation procedure is documented extensively by various documents; in case of trouble you might want to refer to Kernel-HOWTO or the kernel's Documentation/-directory for example.

For building a linux kernel suitable for installing and running a client choose appropriate options and drivers that match your client's hardware configuration (e.g. hard disks, cdrom etc.). Note: if you can avoid using modules to support your clients hardware devices, do so - that will simplify your further tasks; you will need them for PCMCIA though.

Furthermore, the kernel needs following features built-in:

If you think you missed something take a look at the kernel-config files that come with NAIS. Also, when compiling the modules remember to set the environment variable ${INSTALL_MOD_PATH}:

vermeer[/usr/src/linux]# setenv INSTALL_MOD_PATH /tmp
vermeer[/usr/src/linux]# make modules modules_install 
Installing modules under /tmp/lib/modules/2.2.16/block
Installing modules under /tmp/lib/modules/2.2.16/fs
Installing modules under /tmp/lib/modules/2.2.16/misc

4.2 How to create install-root filesystem

The install-root filesystem is based on Debian's base2_2.tgz. Propably, it will have to be made only once. It will be mounted read only by the clients during the installation, thus being the basis of their respective filesystems. It is quite easy to create the root filesystem with Debian.

Customizing util.conf and mk_root

Edit the two files util.conf and mk_root in this directory. Both contain numerous comments which should explain in detail the options you are asked to set. You should look through util.conf and mk_root and check the variable settings.


This file contains basic informations about your server and various (remote and local) file locations. Review the PACKAGES variable carefully - it enumerates the packages to be installed in the installroot. Make sure you specify the INSTALL_ROOT - that is where your installroot will be created


This script specifies how your installroot will be built and what it will contain.

Making the installroot filesystem

Make sure you don't run the script from your root directory ("/"). In case this happens by accident, the script will exit immediately. The script retrieves the files base2_2.tgz and drivers.tgz from the internet, if needed, and extracts the debian "base" root-filesystem as well as the modconf package from drivers.tgz :

case $BASE_TGZ in
    info "Retrieving baseX_Y.tgz ..."
    wget -nv -P$INSTALL_ROOT/ $BASE_TGZ
    info "Unpacking baseX_Y.tgz ..."
    tar -C $INSTALL_ROOT -zxpf $file
    rm -f $file
    info "Unpacking baseX_Y.tgz ..."
    tar -C $INSTALL_ROOT -zxpf $BASE_TGZ
tar zxOf $DRIVERS_TGZ ./modconf.tgz | tar -C $INSTALL_ROOT -xpz
Some scripts needed later on (like chroot_script), busybox sources, an apt-get configuration file (URL's of available debian ftp-servers) and the resolv.conf are copied into the install-root. In order to avoid needless modules probing, the switch_off file, containing the neccessary 'off' lines for the disk-modules, is copied to the etc/modutils directory. The modules.conf will be updated in the script. As a last step, we link etc/mtab and etc/fstab to proc/mounts. This is neccessary, since these files are required for unmounting. Note: proc/mounts is not being mounted in the chroot environment, but it will be during the installation (linuxrc script).

Installing additional packages

Now that the preliminaries have been dealt with, we can change the root directory to the install_root. This step, made incorrectly, can damage your system. Thus, we decided to let the script perform this operation :

chroot $INSTALL_ROOT /bin/bash ${__chroot//*\//}
Once inside the install-root, the is executed. Note: you are in a debian system now - all operations made herein are independent of your local linux distribution. For the next step you will need internet access. As an alternative, a local (NFS) debian mirror can be mounted at "/debian".You can set this option in the util.conf file.
[ x$APT_METHOD = xfile ] &&
  mount -n -t nfs -o ro $NFS_SERVER /debian
Apt-get will download and install the newest versions of some needed packages. In detail, we need : Note: apt-get will show you all dependencies of these packages and ask for approval, so you can consider a change in the PACKAGES variable. After the successful upgrade/installation of these packages, busybox will be compiled. In order to avoid needless modules probing, we update the modules.conf file and create an empty modules.dep file.

If everything went well, your install-root should be complete.

4.3 How to create the Initial RAM disk

Note: The initrd is independent of your linux distribution, since all needed files, in particular libraries, are copied from the Installroot. If you have not created it by now, you'd better return to the section How to create install-root filesystem.

... and why do we need it ?

The initial RAM disk contains a minimal root filesystem. It is used to mount the neccessary ressources from the server. Furthermore, once the client is installed, it does not have to be rebooted - the root simply changes from the initrd to the created one. Apart from the installation, it can be used conveniently as a boot- or rescue-disk. Originally, the initrd has been designed to load additional modules during system startup, thus making pcmcia-usage possible. Look out for this feature in a future release.

Customizing util.conf and mk_initrd

Edit the two files util.conf and mk_initrd in this directory. Both contain numerous comments which should explain in detail the options you are asked to set. You should look through util.conf and mk_initrd and check the variable settings.


This file contains basic informations about your server and various file locations.


This script specifies how your initial RAM disk will be built and what it will contain. In case you want to use your initrd for other purposes than this installation, you should review the selections of /bin files.

Making the initrd (minimal root file system)

When you are done customizing these to files, su to root and run :

This script creates the initial root file system that will be mounted in a RAM disk. It works in four phases. First it processes the util.conf and files setting up variables and defining common functions. Next, it creates a ramdisk, 10 MB in size, so you will propably have to set your ramdisk_size variable in lilo's 'append' string (like append="ramdisk_size=10240").

vermeer[~]# dd if=/dev/zero of=/dev/ram bs=1k count=10240
10240+0 records in
10240+0 records out

We have finally decided to use ext2 as its filesystem, since minix and romfs has too many restrictions. The RAM disk is formatted with mke2fs, using a 1024 inode ratio. In order to maintain maximum caompatibility, all device files are copied from the debian filesystem to /dev, hence this inode ratio.

vermeer[~]# mke2fs -i 1024 -vm1 /dev/ram 10240
mke2fs 1.17, 26-Oct-1999 for EXT2 FS 0.5b, 95/08/09
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
1024 inodes, 1024 blocks
10 blocks (0.98%) reserved for the super user
First data block=1
1 block group
8192 blocks per group, 8192 fragments per group
1024 inodes per group

Writing inode tables: done

Writing superblocks and filesystem accounting information: done

As a next step, the formatted RAM disk is mounted and the directory and link structure is made:

vermeer[~]# mkdir -p $__mnt
vermeer[~]# mount -t ext2 /dev/ram $__mnt

Among the directories are /init_bin, /init_lib and /installroot. Note that the initrd is only a temporary means. The links /bin, /lib are pointing to /init_bin, /init_lib; after the installroot is mounted, they will be relinked to the new location (bin -> /installroot/bin, lib -> /installroot/lib). Note: the re-linking will take place in the linuxrc script. Other links, like /etc, /sbin, /usr, point inside the installroot directory right from the start (respectively installroot/etc, ..). As the client boots, it needs the files /etc/mtab and /etc/fstab, so we simply create them :

touch $__mnt/installroot/etc/{passwd,group,fstab}
After the installroot is mounted, all files and directories previously located in /installroot will become invisible as long as this file system remains attached, thus all created links will point at valid (albeit readonly) directories.

Next, the script copies binaries specified in $__binaries to /init_bin. It looks for required libraries as well as the adequate loaders and copies them to /init_lib. Note: the ldd command (checks the shared library dependencies of a binary) is executed in a chroot (debian) environment of the installroot, so it is independent of your local linux distribution:

chroot $INSTALL_ROOT ldd $bin | while read ...
Notes on BusyBox usage: When you create a link to BusyBox for the utility you wish to use, when BusyBox is called using that link it will behave as if the command itself has been invoked. For example, entering
ln -s ./BusyBox ls
will cause BusyBox to behave as 'ls' (if the 'ls' command has been compiled into BusyBox).

The BusyBox multicall-library has been compiled during the installroot setup. One of the resulting files - busybox.links - contains all links corresponding to the functions compiled into BusyBox.

The script copies the busybox executable to /init_bin and creates all required links :

sed 's~.*/~~' $INSTALL_ROOT/$__busy_links |
while read link
        ln -s busybox $link

where $__busy_links contains the location of busybox.links.

Finally, the neccessary scripts, in particular linuxrc, and dhclient configuration files are copied from the installroot.

Now that the initrd has been created, we unmount the ramdisk, 'dd' it to a file and finally, compress it :

umount $__mnt
dd if=/dev/ram bs=1k count=10240 | gzip -v9 > $__target
mk_initrd will produce occasional messages showing what it is doing. Any errors should be prominent.

When you are satisfied with the output from mk_initrd, create an appropriate bootdisk. Refer to section Booting from floppy for further details.


You are done. Try to boot your client using your favourite method (lilo, syslinux, pxelinux, netboot etc.). If all has gone well, the linuxrc script starts.

...and what does the linuxrc script do anyway?

You should see :

starting NAIS (initrd.gz) ...

Linuxrc performs only a few tasks:

Finally, when linuxrc and all subsequently launched (forked) scripts terminate, the client's newly made root file system is mounted and the initrd is moved to /initrd.

Next Previous Contents