The GENDIST Toolkit


Tutorial

This tutorial shows you the basic usage of the GENDIST toolkit and explains the GENDIST concepts.

CONTENTS

  1. Introduction
  2. Generating the build-system
  3. The directory-layout
  4. Using built-in help
  5. Configuring the build-system
  6. Adding packages
  7. Creating media
  8. Changing the version number
  9. Creating source and binary distributions
  10. Where to go next

Introduction

The tutorial shows you how to build a very simplistic Linux distribution, named ShellLinux. This distribution consists only of a kernel, a root-filesystem, a number of device nodes and a shell. If you have read the book "Just for Fun" from Linus Torvalds, you know that the first Linux-kernel was developed around the bash, since the bash uses most of the important system-calls.

The distribution is so simplistic, that you could also call it UselessLinux, but it should get you going with some more sensible stuff.

This tutorial assumes that you have installed GENDIST in /usr/local/gendist-version. You should read version as the current version number of GENDIST.

This is a step by step tutorial. The impatient users can install the example (including all files created within the tutorial) by switching to /usr/local/gendist-version/examples/ShellLinux and running 'make install PREFIX=/tmp' there.

Top


Generating the build-system

Generating the basic build-system is straightforward:

# /usr/local/gendist-version/bin/gendist.sh -n ShellLinux -t all -p /tmp

The -n option gives the name of our distribution, with -t you can select the type of media and the -p option defines the prefix of the target directory. The target directory prefix/name is created automatically if it does not exist. If -p is ommitted, the current directory is used. Running gendist.sh with the switch -h will show all available options and types.

Since we want to experiment a bit with ShellLinux, we select all available types with -t all. The tradeoff is minimal: our build-system contains one additional makefile for every supported type.

Top


The directory-layout

The following screenshot shows the directories and files generated:

directory-layout

The toplevel directory contains some administrative files (e.g. README, NEWS, ChangeLog), the toplevel makefile and the file with the version information (version.inc).

The directories media and rules contain most of the logic of the build-system. Note that GENDIST is designed to be very flexible. One of the design-goals is that it is not necessary to change any of the generated makefiles, thus making it very easy to upgrade to a newer version of GENDIST.

The bin and doc-subdirectories are stubs for your own files. The src-directory contains the real-stuff.

The subdirectories of src contain the files which make up the distribution. All directories except the packages-directory contain some template files, the packages-directory itself is initially empty.

Top


Using built-in help

The build-system contains a number of help-targets. E.g.

# make help
Toplevel makefile for ShellLinux
 Use 'make help-targets' for a list of targets
     'make help-types'   to show available types
     'make help-params'  to describe config-parameters
     'make help-config'  to show the current configuration
     'make help-version' to show version information

Top


Configuring the build-system

The way the build-system works is controlled by a number of configuration variables. This is nothing special about GENDIST, it is a standard feature of make.

The current configuration is available with:

# make help-config
 Current configuration:
    TYPE:             classic2
    KERNEL:           missing
    IMG_SIZE:         1440
    RD_SIZE:          2600
    RD_FS:            minix
    RD_NODES:         auto
    root-fs_PACKAGES: 
 
 Type-specific configuration:
    no type specific configuration for type classic2                            

An explanation of these configuration variables is provided by 'make help-params' but they also should be self-explanatory (RD stands for ramdisk).

There are three possible ways to configure the build-system:

For our ShellLinux-project, we will use the latter two options. To begin, create a file config.inc with the following content:

# cat config.inc
root-fs_PACKAGES := dirs dev shell libs
RD_FS := ext2                                                                   

With this file, and additional command-line parameters, 'make help-config' will now yield:

# make help-config TYPE=el-torito IMG_SIZE=2880
 Current configuration:
    TYPE:             el-torito
    KERNEL:           missing
    IMG_SIZE:         2880
    RD_SIZE:          2600
    RD_FS:            ext2
    RD_NODES:         auto
    root-fs_PACKAGES: dirs dev shell libs
 
 Type-specific configuration:
    IMG_TYPE:       syslinux
    cd-fs_PACKAGES:
    MKISOFS_ARGS:   -A "Bootable Linux CD created with ShellLinux
0.0.1" -V "ShellLinux 0.0.1" -p "Bablokb@canopus" -R

As you can see, the parameters in config.inc overwrite the defaults. The same is true for parameters passed on the command-line. The latter have the highest priority. So you can put your own default parameters in config.inc, and temporarily overwrite them from the command-line.

A note on the parameters in config.inc: most stock kernels don't have built-in support for minix (they support it using modules, but this is not enough for us). Therefore this example uses RD_FS=ext2. The default value (minix) will create smaller initial ramdisks, and if space is a problem, you should create a special-purpose kernel anyhow.

The second parameter, root-fs_PACKAGES lists all GENDIST-packages to go into the root-filesystem. The next section gives you details.

Top


Adding packages

A GENDIST-package is not another package-format (there are enough of these around). Consider a GENDIST-package as a unit of work to do during the creation of the root-filesystem. The package can do anything, but it usually just copies or unpacks some files into the root-filesystem.

ShellLinux uses four packages:

Each package "lives" in it's own subdirectory underneath /tmp/ShellLinux/src/packages/root-fs. The dirs and dev packages are very simple: they only contain a makefile.

To create the packages, just create the directories and add the makefiles. The rules for creating package-level makefiles are simple:

You will find a template makefile in /tmp/ShellLinux/rules/Makefile.package. An example implementation for the dirs-package could look like this:

# cat /tmp/ShellLinux/src/packages/root-fs/dirs/Makefile

DEP-PACKAGES :=
 
include $(DIST_ROOT)/rules/package.inc
 
DIR_SET=bin boot cdrom dev etc floppy home lib mnt opt proc \
      root sbin tmp usr var/log
 
install:
        for d in $(DIR_SET); do \
          mkdir -p $(TARGET_DIR)/$$d; \
        done

The makefile for the dev-package is also simple:

# cat /tmp/ShellLinux/src/packages/root-fs/dev/Makefile

DEP-PACKAGES := ../dirs
 
include $(DIST_ROOT)/rules/package.inc
 
DEV_SET := tty0 tty1 console ram ram0 ramdisk null
 
install:
        tar -cpf - -C /dev $(DEV_SET) | tar -xpf - -C $(TARGET_DIR)/dev

As you can see, the dev-package depends on the dirs-package. The variable $(TARGET_DIR) always points to the directory, where the root-filesystem is built (the default value is /tmp/ShellLinux/build/root-fs).

Both makefiles show another useful technique. They define their own configuration variables. If for example you define "DEV_SET=." on the command-line, all devices in the current /dev-directory would be copied to the newly created root-fs.

The remaining two packages (shell and libs) are a bit more complicated. You can copy them from the /usr/local/gendist-version/examples/ShellLinux/files/src/packages/root-fs directory and have a look at them.

Top


Creating media

Now that you configured the build-system and added the packages, you can start creating disk-images of your target-media. At this point you also have to supply a kernel. Try the following:

# make KERNEL=path-to-your-kernel
# ... (a lot of output)
# ls -lAF build/media
-rw-r--r--    1 root     root      1474560 Jan 20 17:55 ShellLinux-bootdsk.img
-rw-r--r--    1 root     root      1474560 Jan 20 17:55 ShellLinux-rootdsk.img

You can copy these files to floppy-disks with:

# dd if=build/media/ShellLinux-bootdsk.img of=/dev/fd0
# dd if=build/media/ShellLinux-rootdsk.img of=/dev/fd0

If you have a CD-writer (and have installed the mkisofs-utility), you could also create an ISO9660-image with the command:

# make clean
# make KERNEL=path-to-your-kernel TYPE=el-torito IMG_SIZE=2880 IMG_TYPE=syslinux
# ... (a lot of output)
# ls -lAF build/media
-rw-r--r--    1 root     root      3006464 Jan 20 18:00 ShellLinux.iso

An El-Torito CD emulates a boot-disk. Since bash together with all it's dynamic libraries is so large that it does not fit together with a kernel on a single disk, we have increased the image size to 2.88MB.

Useful during development is an emulator, e.g. VmWare or Bochs (the latter is LGPLed but very, very slow). They work directly of the disk-images, so the turnaround time is much faster.

Top


Changing the version number

Now that everything is working, we want to change the version number of our distribution. Just calling 'make inc-dist-major' does the job (and sets the version to 1.0.0). Alternatives are 'make inc-dist-minor' to increase the minor version number or 'make inc-dist-pl' to increase the patch-level.

Top


Creating source and binary distributions

The last step is to create the distribution archives. At this point, you should also edit the administrative files in the toplevel directory (README, ChangeLog and NEWS). You should also add a LICENSE file, (the -g-option of gendist.sh adds the GPL as the license-file).

Creating distribution archives is simple. You have the choice between 'make src-dist', which creates a source-distribution including the build-system and all other files not removed by 'make distclean'. The alternative is 'make bin-dist', which only packages the administrative files and the generated disk-images (since 'make bin-dist' recreates the disk-images, you should pass all necessary parameters on the command-line).

# make bin-dist KERNEL=...
# make src-dist
# ls -lAF ShellLinux*
-rw-r--r--    1 root     root      1372542 Jan 20 18:12 ShellLinux-1.0.0-bin.tar.bz2
-rw-r--r--    1 root     root         7158 Jan 20 18:12 ShellLinux-1.0.0-src.tar.bz2

Top


Where to go next

Now that you know how to use the build-system, you should start with your own distribution. The main work will be to create appropriate packages. You can find additional examples in the various subdirectories of /usr/local/gendist-version/examples.

Reading documentation is not really fun (compared with programming), but if you are interessted in details (and want to use advanced features of GENDIST), you should take the time to read all sections of the documentation.

Top


My Homepage
Bernhard Bablok (mail @ bablokb.de)