Bt-Web 0.80

Next: , Previous: (dir), Up: (dir)

This file is a working document about how to install a kernel and filesystem (specifically, the EtLinux distribution) on the web server device distributed by Bticino S.p.A.

It's been a pleasure to work on this stuff, and I want to thank Roberto Cerati, Enrico Valtolina, Simone Agresta and Raffaele Recalcati for their work with the device and their help.

Next: , Previous: Top, Up: Top

1 Introduction

This document is meant to be a hands-on tutorial when rebulding a kernel and a filesystem. Most of the basic information is available in the companion Assabet document, as the initial work and system setup has been accomplished on the Assabet development platform, distributed by Intel.

Next: , Previous: Introduction, Up: Top

2 Customizing Jflash

In order to boot your system at all, you first need to program some code into the flash memory. To this aim, the Jflash program comes to rescue, but it needs to be modified to act on the specific flash device used in the BtWeb device (the M29W160DB device by ST).

The directory jflash includes a version of the tool ported by Bticino staff, called jflash-btweb.

To connect the JTAG port of the BtWeb to the parallel port of a personal computer, you'll need a cable with at least 5 wires (4 data plus GND), but the best choice is using a TP network cable to pair one ground line to each data line. The wires must be soldered to the “NM2B” 8-pin connector near the Ethernet connector. Pin 1 is marked, pins 1 to 4 are near the border of the PCB and pins 5 in the second row is near pin 1.

The following pins of the parallel port must be connected for jflash-btweb to work:

PIN2 (data 0)
To pin 7 of “NM2B
PIN3 (data 1)
To pin 3 of “NM2B
PIN4 (data 2)
To pin 8 of “NM2B
PIN11 (status 7)
To pin 4 of “NM2B
PINS 18-25 (GND)
To pin 6 of “NM2B

The jflash-btweb program receives a single argument on the command line and writes it to flash starting at offset 0.

Next: , Previous: Customizing Jflash, Up: Top

3 Customizing RedBoot

This chapter describes the steps needed to compile a RedBoot instance that works on the BtWeb supporting all the devices needed at boot time.

Next: , Previous: Customizing RedBoot, Up: Customizing RedBoot

3.1 Downloading ECOS

Since there are not timely official releases of the ECOS code base, the best approach to a repeatable port is staring from a CVS checkout tagged at a specific date.

In this port I used a checkout stamped 2003-05-08, but due to timezone differences between my site and the ECOS repository, the files are tagged 2003. in my CVS/Entries file.

To checkout the ECOS repository, do the following:

        cvs -d \
        [type anoncvs as password]
        cvs -d \
                    co -D 2003-0508 ecos

After the checkout is over, you'll have a directory called ecos within your current working directory. It's contents are more or less 120 MB in size.

Next: , Previous: Downloading ECOS, Up: Customizing RedBoot

3.2 Creating an ECOS platform

The first step to port RedBoot the to the BtWeb engine is creating a new platform for BtWeb. This is best accomplished by issuing the following command:

         for n in $(find . -type d -name assabet); do
              cp -a $n $(echo $n | sed 's/assabet$/btweb/')

You are expected to perform this step before applying the patch that's distributed with this package. I chose to limit the patch to actual differences so it remains small and meaningful for those who read it.

Previous: Creating an ECOS platform, Up: Customizing RedBoot

3.3 Specific Customizations

Note: all of these changes, excluding Ethernet support, have been implemented by Raffaele Recalcati.

.... FIXME ...

With the changes described earlier, you'll get boot messages similar to the following ones after flashing RedBoot and turning on the BtWeb:

        +FLASH PCMCIA mode
        LAN91CXX - supposed BankReg  18000c38 = 0033
        LAN91CXX - type: 4, rev: 9
        LAN91CXX - status: 0000
        LAN91CXX - eeprom ESA: 0e:00:00:50:03:00
        Ethernet eth0: MAC address 0e:00:00:50:03:00
        IP:, Gateway:
        Default server:, DNS server IP:

Next: , Previous: Customizing RedBoot, Up: Top

4 Compiling the 2.4 Kernel

The kernel I used in the BtWeb device is version linux-2.4.18-rmk7. The original source code is available as:

The patch file, like every patch included with this package, is applied by feeding it to the standard input of “patch -p1”, from within the toplevel source directory for the kernel.

You can begin by configuring and compiling the kernel with the default configuration for the Assabet device:

        make assabet_config ARCH=arm
        yes "" | make oldconfig ARCH=arm
        make dep ARCH=arm CROSS_COMPILE=sa110_le-
        make zImage ARCH=arm CROSS_COMPILE=sa110_le-

Here, I assume you are working on an x86 host with the cross-compiler that is distributed within the Assabet package. If not, please adapt the previous and following commands to your own development environment.

After a few minutes (or more, according to your setup), you'll find a compiled kernel in arch/arm/boot/zImage. Loading and running is described in the companion Assabet document.

Next: , Previous: Compiling the 2.4 Kernel, Up: Top

5 Customizing the 2.4 Kernel

The kernel for the BtWeb device must be tailored. This chapter describes all the changes that ought to be applied starting from the default Assabet configuration used in Compiling the 2.4 Kernel. We thus refer to version 2.4.18-rmk7 throughout this chapter.

For the impatient, all modifications for BtWeb have been collected in the patch file patches/btweb-all.patch. You can apply that one instead of the individual changes described in this chapter.

Next: , Previous: Customizing the 2.4 Kernel, Up: Customizing the 2.4 Kernel

5.1 Changing the Kernel Name

Before applying any actual change to the source tree, it's a good policy to mark the tree with a different release name. In this case we'll change the EXTRAVERSION variable in the Makefile to get an overall version name “linux-2.4.18-rmk7-btweb”. The change is in the patch file patches/kernelname.patch.

Next: , Previous: Changing the Kernel Name, Up: Customizing the 2.4 Kernel

5.2 Creating a Machine Type

The first step to set up a new machine is creating your own configuration variable, so you can ifdef places where your computer is unique and possibly create specific source files, automatically selected during the build process

The new machine type for btweb, will be selected by CONFIG_SA1110_BTWEB. By applying the patch found in patches/mach-btweb.patch you'll create such a configuration option and an associated file, arch/arm/mach-sa1100/btweb.c. It also changes include/asm/arch/assabet.h in a trivial way. The new btweb.c is mostly a copy of assabet.c, but it renames all local symbols from assabet_* to btweb_*; it also removes all references to the neponset device. Other changes are delayed to further patches to ease understanding them.

        ostro% patch -p1 < ~/btweb/patches/mach-btweb.patch
        patching file arch/arm/mach-sa1100/Makefile
        patching file arch/arm/mach-sa1100/btweb.c
        patching file arch/arm/
        patching file include/asm-arm/arch-sa1100/assabet.h

As usual, run “make oldconfig” to select the new platform, and to generate other input files from .config, but remember to remove the selection for the assabet platform. As an alternative, run the following script to do the right steps without interaction.

        make assabet_config ARCH=arm
        yes "" | make oldconfig ARCH=arm
        perl -p -i -e 's/^(CONFIG.*ASSABET[^=]*)=y$/# \1 is not set/' .config
        perl -p -i -e 's/^# (CONFIG.*BTWEB).*$/\1=y/' .config
        yes "" | make oldconfig ARCH=arm

Then, recompile the kernel as usual:

        make zImage ARCH=arm CROSS_COMPILE=sa110_le-

FIXME – up to here

The resulting zImage file, in arch/arm/boot, will be 700kB, matching an uncompressed vmlinux more than 1.6MB worth of code and data:

         ostro% size vmlinux
            text    data     bss     dec     hex filename
         1448167   82079  183560 1713806  1a268e vmlinux
         ostro% ls -l arch/arm/boot/zImage
         -rwxrwxr-x  1 rubini  staff  707240 Aug 4 15:43 arch/arm/boot/zImage*

Next: , Previous: Creating a Machine Type, Up: Customizing the 2.4 Kernel

5.3 Memory Size

The kernel receives information about memory size from the boot loader; the right thing to do here, then, is fixing redboot to properly detect the memory size.

Since some versions of the loader currently being used on btweb report an incorrect RAM size (set at compilation time, not probed), you'll need to apply patches/memsize.patch and recompile.

The patch changes arch/arm/ adding a question about whether the device is a prototype with 32MB or a production device with 16 MB of memory; it changes arch/arm/mach-sa1100/btweb.c to enforce 32M or 16M accordingly. It also sets the system up for 4MB of flash memory instead of 32MB.

Given the relatively small amount of total memory on the system, you may also want to apply the patches/memorymon.patch. This patch adds a command-line option for the kernel. If the kernel is booted with “mmon=0”, it will print to the console a snapshot of memory usage just before spawning the init process (therefore showing how much RAM has been eaten by dynamic allocation performed by the kernel subsystems). If you boot with “mmon=n”, with n greater than zero, the kernel will also print memory information every that many seconds. The feature is disabled by default and can be turned off by using a negative command-line parameter.

Next: , Previous: Memory Size, Up: Customizing the 2.4 Kernel

5.4 The Configuration File

Since the default configuration for the Assabet is pretty full-featured, on first step in customizing the kernel; is changing its configuration. The suggested initial configuration, available in patches/config.0, removes several subsystems that are not used (or that will be enabled later on, with specific setups). After make oldconfig and make zImage you'll get an executable ELF file of almost 1.2MB, for a compressed image well under 500 kilobytes.

         ostro% size vmlinux
            text    data     bss     dec     hex filename
          999551   47480  144340 1191371  122dcb vmlinux
         ostro% ls -l arch/arm/boot/zImage
         -rwxrwxr-x  1 rubini staff 474184 Aug  4 16:03 arch/arm/boot/zImage*

The configuration file enables NFS version 3 (though not NFS-root operation), although the Ethernet device isn't supported at this time. Also, the chosen RAM size is 16MB.

Next: , Previous: The Configuration File, Up: Customizing the 2.4 Kernel

5.5 The Serial Port

Serial ports in the btweb are laid out differently than in the Assabet, so we must move the console to a different serial port. This is simply achieved by applying the patch patches/move-console.patch. It simply switches the serial ports at initialization time, so the console is moved to the other one even if no command-line arguments are passed to the kernel.

Next: , Previous: The Serial Port, Up: Customizing the 2.4 Kernel

5.6 The Ethernet Device

To add ethernet support, you need to patch the file drivers/net/smc9194.c to include the btweb setup. This is accomplished by applying the patch patches/netdevice.patch. Its main role is adding a block of code for initialization, most of which is copied from the assabet section in the same file.

You'll also need to enable compilation of the 9194 driver by editing the .config file. Please note that you may avoid changing the configuration file if you won't compile the kernel now and choose to go on reading instead.

The following commands perform reconfiguration and recompilation; you can reconfigure interactively, instead, if you prefer it.

        perl -p -i -e 's/^# (CONFIG.*9194).*$/\1=y/' .config
        yes "" | make oldconfig ARCH=arm
        make zImage ARCH=arm CROSS_COMPILE=sa110_le-

The kernel will be 6kB bigger than the one shown earlier (20kB if you also enable DHCP and NFS-Root).

Next: , Previous: The Ethernet Device, Up: Customizing the 2.4 Kernel

5.7 The I2C Bus

Adding support for the i2c bus is trivial; it's simply a matter of declaring the GPIO bits being used. What is slightly less trivial is the configuration.

The patch to apply is patches/i2c.patch. It declares the GPIO bits and disables L3 initialization, since there is no L3 bus on btweb, and no third gpio bit to drive.

To run i2c the configuration options to activate are:


according to your specific applications, you can skip some of these options. Note, however, that you need CONFIG_L3 to be enabled regardless what your needs are, since the i2c controller code for SA1110 lives in the drivers/l3 directory.

Access to the i2c bus from user space is described in Documentation/i2c/, especially dev-interface.

The complete kernel configuration file I used at this point is available as patches/config.1, and it enables NFS-root and bootp/dhcp. You can simply overwrite your .config and make oldconfig as usual:

        patch -p1 < ~/btweb/patches/i2c.patch
        cp ~/btweb/patches/config.1 .config
        yes "" | make oldconfig ARCH=arm
        make zImage ARCH=arm CROSS_COMPILE=sa110_le-

Please note that this configuration file selects 16MB as memory size.

The kernel created is 1.25MB, and the compressed image is under 490kB; this can actually be used for booting over the network, without a local ram disk.

To access the i2c bus from user space you'll need to create a device special file, for example by issuing:

        mknod /dev/i2c c 89 0

You can then access i2c devices using the simple program found in tools/4i2c.c. The program can only read and write device registers: the 7-bit device address is passed on the command line, and commands are then read from standard input. The following devices are connected to the i2c bus of the btweb platform:

Next: , Previous: The I2C Bus, Up: Customizing the 2.4 Kernel

5.8 The Watchdog

There's nothing special to do about the watchdog. The only needed step is enabling it in the configuration file. I enabled the following options:


The nowaytout is designed so that the watchdog is not disabled when the associated file descriptor is closed. In any case, however, the watchdog mechanism is not activated unless the associated device file is opened by a process. You can copy the new configuration file from patches/config.2. Again, this configuration file selects 16MB as memory size.

Unfortunately, the timeout by default can't be specified by a kernel command-line but only at insmod time. The patch patches/wd.patch fixes the problem, allowing the same assignment (sa1100_margin=) to work both as insmod parameter and kernel command-line argument.

With the patch applied, therefore, the timeout can be specified on the kernel command line; for example for a 10-seconds timeout use “sa1100_margin=10". If no margin is specified, the default of 60 seconds applies; note however that the watchdog machinery is only activated when the device special file is opened by a process.

The device file to use is /dev/wd, and it can be created using “mknod /dev/wd c 10 130”. To keep the system up from an EtLinux process, then, you can use the following program:

        set F [open /dev/wd w]
        fconfigure $F -buffering none
        while 1 {
            puts $F ""
            after 1000

To place this code into /etc/init.d/scripts, you'll want to do that in a child process, and let the father return. For example:

        if ![sys_fork] {
            newcmdname "wd-pinger"
            set F [open /dev/wd w]
            fconfigure $F -buffering none
            while 1 {
                puts $F ""
                after 1000

Next: , Previous: The Watchdog, Up: Customizing the 2.4 Kernel

5.9 The Real-Time Clock

The real-time clock in the btweb device is a Philips PCF8564 connected to the I2C bus, and it is used to supplement the internal SA1100 runtime one. It is read at boot time and updated when system time is updated by the user. This last step is typically performed by the hwclock command, opening /dev/rtc.

If /dev/rtc is missing from your target filesystem, you can create it by invoking the mknod command:

        mknod /dev/rtc c 10 135

To enable use of the btweb-specific device, you need to apply the patches/rtc.patch patch, that changes drivers/char/sa1100-rtc.c and adds a new function to drivers/i2c/i2c-core.c (changing include/linux/i2c.h to declare it). The new I2C function is used to access the I2C controller from files not directly related to I2C.

The RTC is read at boot time. Later, you can read it and set it to the current system date using the tools/rtc-rw program. The program takes a “r” or “w” argument and an optional format argument (to be used to display the date read from the RTC – possibly after changing it).

You can also use the hwclock program, as rtc.patch instruments the standard ioctl calls to read and set the RTC. Note however that rtc-rw is 3kB and hwclock is ten time as big. Whatever the mechanism, kernel code as implemented assumes the date being written is in the 21st century.

Next: , Previous: The Real-Time Clock, Up: Customizing the 2.4 Kernel

5.10 The Thermometer

The btweb device includes a TC74 thermometer chip connected on the I2C bus. To avoid requiring a user application to read the temperature, I chose to make the current temperature available as a /dev special file, specifically /dev/temperature. The file returns the current temperature as ASCII representation of a signed byte. If read operations on the I2C bus return an error, the empty string is returned (for example, if no thermometer is mounted on your specific device). The value returned represents the current temperature as returned by the TC74 device (i.e., in signed Celsius degrees).

To enable temperature measurement, apply the patch temp.patch. It only affects the btweb.c file, but it depends on the previous rtc.patch, that exports a new symbol from the I2C subsystem.

To create /dev/temperature in your filesystem, you can issue the following command:

        mknod /dev/temperature c 10 131

Next: , Previous: The Thermometer, Up: Customizing the 2.4 Kernel

5.11 The I2C Memory Controller

The btweb device includes 32kB of static memory on the I2C bus (using a 24LC256). Similarly to the choice taken for the thermometer, the i2c memory can be accessed using a misc device, and the code is part of btweb.c. The support, thus, has been folded in the temp.patch we applied in the previous section.

The memory area can be accessed using read, write and lseek. To create the device special file, use the following command:

        mknod /dev/nvram c 10 144

Next: , Previous: The I2C Memory Controller, Up: Customizing the 2.4 Kernel

5.12 The DSP Device

The "video" version of the BtWeb device includes an extra PCB, hosting a Texas Instruments DSP device. The patch file patches/dsp.patch adds another misc device to btweb.c, with minor number 127.

You should create your device special file by running:

        mknod /dev/dsp c 10 127

The driver implements the read(), write() and ioctl() system calls, in addition to boot-time initialization of the relevant signals. The first time open() is called, it checks whether the DSP is installed on the system or not. If not, ENODEV is returned and any further open() returns ENODEV without checking again.

Since ioctl() is only used to resets the DSP, the implementation issues a reset independent of what the ioctl command and argument are. Applications should use a command number of 0 to be forward-compatible with possible future enhancements. Currently, though you can use any application that calls ioctl() to reset the DSP, without the need for a specific command; for example, “stty < /dev/dsp” is an easy way to reset the device.

Next: , Previous: The DSP Device, Up: Customizing the 2.4 Kernel

5.13 MTD Support

The suggested kernel configuration for a BtWeb device with MTD support is available as patches/config.mtd. As usual, the RAM size is pre-set to 16MB.

In order to access static partitioning in your flash area, you'll need to instruct the kernel about your partitioning scheme at compile time. To this aim, you can apply patches/mtd-map.patch, that modifies drivers/mtd/maps/sa1100-flash.c to add BtWeb partitioning information, automatically selecting between 4MB and 8MB devices. The patch also modifies drivers/mtd/chips/jedec_probe.c to add support for the ST M29W320DB chip, the one used in 8MB btweb devices.

To access your three flash partitions, then, you'll need the proper entry points in your /dev tree. The following instances of mknod are all that's neeeded, run from the root directory of your target tree:

        mknod dev/mtd0  c 90 0
        mknod dev/mtdr0 c 90 1
        mknod dev/mtd1  c 90 2
        mknod dev/mtdr1 c 90 3
        mknod dev/mtd2  c 90 4
        mknod dev/mtdr2 c 90 5
        mknod dev/mtd3  c 90 6
        mknod dev/mtdr3 c 90 7
        mknod dev/mtd4  c 90 8
        mknod dev/mtdr4 c 90 9
        mknod dev/mtd5  c 90 10
        mknod dev/mtdr5 c 90 11
        mknod dev/mtd6  c 90 12
        mknod dev/mtdr6 c 90 13

With the chosen configuration, your boot messages will look like this if booting a 4MB device:

         SA1100 flash: probing 32-bit flash bus
         Search for id:(20 2249) interleave(2) type(2)
         Found: ST M29W160DB
         SA1100 flash: Found 2 x16 devices at 0x0 in 32-bit mode
         number of JEDEC chips: 1
         BTWEB: using static partition list for 4MB
         Using static partition definition
         Creating 7 MTD partitions on "SA1100 flash":
         0x00000000-0x00020000 : "boot firmware"
         0x00020000-0x00040000 : "cfg0"
         0x00040000-0x00060000 : "cfg1"
         0x00060000-0x000e0000 : "kernel"
         0x000e0000-0x002e0000 : "etlinux"
         0x002e0000-0x00360000 : "applications0"
         0x00360000-0x003e0000 : "applications1"

and like this if you boot an 8MB device:

         SA1100 flash: probing 32-bit flash bus
         Search for id:(20 22cb) interleave(2) type(2)
         Found: ST M29W320DB
         SA1100 flash: Found 2 x16 devices at 0x0 in 32-bit mode
         number of JEDEC chips: 1
         mtd size: 00800000
         BTWEB: using static partition list for 8MB
         Using static partition definition
         Creating 7 MTD partitions on "SA1100 flash":
         0x00000000-0x00040000 : "boot firmware"
         0x00040000-0x000a0000 : "cfg0"
         0x000a0000-0x00100000 : "cfg1"
         0x00100000-0x00220000 : "kernel"
         0x00220000-0x00520000 : "etlinux"
         0x00520000-0x00660000 : "applications0"
         0x00660000-0x007a0000 : "applications1"

At this point, /dev/mtd0 can be opened read-write and /dev/mtdr0 can be opened read-only (and the same applies for other devices).

If you want to use the MTD subsystem as an integral part of the kernel instead of using modules, you can use the configuration file available as patches/config.mtd. As usual, the RAM size is pre-set to 16MB.

To erase flash blocks you'll need to issue the proper ioctl commands to a file descriptor associated to /dev/mtd0. As a quick way to test things out, you might just download the mtd-tools package and cross-compile the util subdirectory. You can compile with the comand:

        make erase CC=sa110_le-gcc

The erase executable can then be copied to the target tree. Note that most of the other programs need a more complete cross-compilation environment, and compilation will likely fail if you to compile all tools.

Next: , Previous: MTD Support, Up: Customizing the 2.4 Kernel

5.14 The LED

To turn on and off the green led found on the btweb device, you can write '1' or '0' (ascii), to /dev/led. The device must be created with mknod, as usual:

        mknod /dev/led c 10 69

The device accepts two-byte writes, so you can use the echo command or equivalent, and the trailing newline is discarded. On read, it returns two bytes, '0' or '1' followed by newline. If you read one byte only, it returns the ASCII digit.

Code associated to this device is in patches/led.patch

Previous: The LED, Up: Customizing the 2.4 Kernel

5.15 Executive Summary

In this summary I'll assume the toplevel directory of this package as stored in your system is recorded in the environment variable BTWEB. This means you are expected to have issued

        export BTWEB=~/btweb

or a similar command.

With BTWEB properly in place, all the changes described in this chapter can be applied to a fresh linux-2.4.18-rmk7 tree by applying the single patch patches/btweb-all.patch, with your current directory in the toplevel kernel source directory:

     patch -p1 < $BTWEB/patches/btweb-all.patch
         patching file arch/arm/mach-sa1100/Makefile
         patching file arch/arm/mach-sa1100/btweb.c
         patching file arch/arm/
         patching file drivers/net/smc9194.c
         patching file drivers/char/sa1100_wdt.c
         patching file drivers/char/sa1100-rtc.c
         patching file drivers/i2c/i2c-core.c
         patching file drivers/mtd/maps/sa1100-flash.c
         patching file drivers/l3/l3-bit-sa1100.c
         patching file include/linux/i2c.h
         patching file include/asm-arm/arch-sa1100/assabet.h
         patching file init/main.c
         patching file Makefile

Alternatively, you can apply each part individually, like this:

     patch -p1 < $BTWEB/patches/kernelname.patch
         patching file Makefile
     patch -p1 < $BTWEB/patches/mach-btweb.patch
         patching file include/asm-arm/arch-sa1100/assabet.h
         patching file arch/arm/mach-sa1100/Makefile
         patching file arch/arm/mach-sa1100/btweb.c
         patching file arch/arm/
     patch -p1 < $BTWEB/patches/memsize.patch
         patching file arch/arm/mach-sa1100/btweb.c
         patching file arch/arm/
     patch -p1 < $BTWEB/patches/move-console.patch
         patching file arch/arm/mach-sa1100/btweb.c
     patch -p1 < $BTWEB/patches/memorymon.patch
         patching file init/main.c
     patch -p1 < $BTWEB/patches/netdevice.patch
         patching file drivers/net/smc9194.c
     patch -p1 < $BTWEB/patches/i2c.patch
         patching file drivers/l3/l3-bit-sa1100.c
     patch -p1 < $BTWEB/patches/wd.patch
         patching file drivers/char/sa1100_wdt.c
     patch -p1 < $BTWEB/patches/rtc.patch
         patching file include/linux/i2c.h
         patching file drivers/char/sa1100-rtc.c
         patching file drivers/i2c/i2c-core.c
     patch -p1 < $BTWEB/patches/temp.patch
         patching file arch/arm/mach-sa1100/btweb.c
     patch -p1 < $BTWEB/patches/mtd-map.patch
         patching file drivers/mtd/maps/sa1100-flash.c
     patch -p1 < $BTWEB/patches/dsp.patch
         patching file arch/arm/mach-sa1100/btweb.c
     patch -p1 < $BTWEB/patches/led.patch
         patching file arch/arm/mach-sa1100/btweb.c

The compressed kernel image, with config.mtd as configuration file, weights 501kB, thus fitting in the allocated 512kB flash partition. Still, if the need arises, a few kilobytes more can be squeezed from the code, for example by removing CONFIG_I2C_PROC or the code to create core files.

Next: , Previous: Customizing the 2.4 Kernel, Up: Top

6 Compiling and Customizing the 2.6 Kernel

This chapter quickly deals with 2.6 issues. It doesn't go in depth as the chapters about 2.4 since the production computers will run 2.4.

This chapter is written based on experience made with version 2.6.0-test2-rmk1. Code and configuration files is distributed in the patches/v2.6 subdirectory of this package.

Next: , Previous: Compiling and Customizing the 2.6 Kernel, Up: Compiling and Customizing the 2.6 Kernel

6.1 Compiling Linux-2.6

Cross-compiling version 2.6 of the kernel is similar to what we did for version 2.4, but somewhat easier. You can set both ARCH and CROSS_COMPILE in the environment, so the command lines we'll need to issue are simply:

         make oldconfig
         make zImage

The cross-compiler of the hardhat kit won't work, though, as the build process uses an assembler directive that is not supported by the hardhat version of as. So you'll get to roll your own, or get a different tool-chain somewhere out there on the Net.

You'll notice that make messages are much terse than the 2.4 default is, this because of tricks in the makefiles. If you need to get the complete command lines as you are used to, issue “make zImage V=1”, or set V in the environment. For a quick overview, “make help”.

The configuration file I've been using is not very well thought, but you can use that as a working starting point: patches/v2.6/config.0. As usual, copy that file to .config, then make both oldconfig and zImage. Unlike what happened with 2.4, no questions will be asked by “make oldconfig”.

Previous: Compiling Linux-2.6, Up: Compiling and Customizing the 2.6 Kernel

6.2 Patching Linux-2.6

The patch file patches/v2.6/linux-2.6.0-test2-rmk1-btweb.patch applies the following modification:

It does not add, as of this release, add device drivers for board-specific hardware nor anything else. With that configuration and code I can happily boot a diskless BtWeb device with 16MB-RAM.

Next: , Previous: Compiling and Customizing the 2.6 Kernel, Up: Top

7 Building an EtLinux Filesystem

This chapters describes the steps that have been performed to build the filesystem for the target, by customizing EtLinux for the specific target and configuration.

Next: , Previous: Building an EtLinux Filesystem, Up: Building an EtLinux Filesystem

7.1 Getting EtLinux

First of all, I suggest you get EtLinux-1,1 in some recent incantation. Since some of the material discussed here has been included in the CVS tree for EtLinux-1.1 during this work, I suggest you use the following command to retrieve the code as of June 11th 2003. The password for anonymous CVS login is “cvs”.

         cvs -d login
         cvs -d \
                       co -D 2003-06-11 etlinux-1.1

The previous step will create a directory called “etlinux-1.1” under your current working directory. In this chapter I'll assume you downloaded EtLinux inside /opt/btweb (thus, you'll have a directory called /opt/btweb/etlinux-1.1). Please ensure to do the CVS checkout outside of the directory of this package.

Later on we'll compile EtLinux packages from source and will add configuration files and packages to the etlinux-1.1 tree. To prevent accidental modification of the downloaded files, I suggest you write-protect all of them after the checkout, or change their ownership.

Next: , Previous: Getting EtLinux, Up: Building an EtLinux Filesystem

7.2 Creating a Local Copy of the Source Tree

The EtLinux distribution is built from source code, so it's wouldn't be wise to include it all in this btweb package. Therefore, I chose to distribute only files you'll need to add to EtLinux, and the tools to make and remote symbolic links to the EtLinux source distribution.

This brings in another advantage: the original source tree is not modified at all and you keep complete control of what you have modified even without live access to the EtLinux CVS tree.

To create the tree of symbolic links to the source, you should enter the etlinux-1.1 directory of this package (where you find custom configuration files and directories) and run ../tools/makelinks, after pointing the ETLINUX environment variable to your EtLinux source tree.

With bash or another sh-compatible shell, you can for example use:

        $ export ETLINUX=/opt/btweb/etlinux-1.1
        $ cd etlinux-1.1
        $ ../tools/makelinks

or, better:

        $ (cd etlinux-1.1 && ETLINUX=/opt/btweb/etlinux-1.1 ../tools/makelinks)

If you ever need to remove the tree of symbolic links, keeping only the customization files, you can use tools/rmlinks:

       $ (cd etlinux-1.1 && ../tools/rmlinks)

Caution: please note that you ought to remove the links before updating this package from CVS, because a newer version of btweb might replace a file that is part of EtLinux (since it needs a different one, for example). CVS will complain if it finds a symbolic link where it wants to create a file.

Next: , Previous: Creating a Local Copy of the Source Tree, Up: Building an EtLinux Filesystem

7.3 Building a Tree

To build a target tree, you should refer to the EtLinux manual (included in its distribution tree). This is just a quick summary on how to build a tree in a different directory than the source one.

Let's assume you are building your target tree in the directory build within this directory (the btweb main directory). The sequence of actions will look like the following:

        $ mkdir build
        $ cd build
        $ export SOURCEDIR=../etlinux-1.1
        $ ln -s $SOURCEDIR/Makefile .
        $ sudo make all PLATFORM=arm-cross-hhl CONFIG=btweb

As an alternative, you might prefer to set PLATFORM and CONFIG in your environment, to avoid retyping them over and over if you need to change the configuration and rebuild the system:

        $ mkdir build
        $ cd build
        $ export SOURCEDIR=../etlinux-1.1
        $ ln -s $SOURCEDIR/Makefile .
        $ export PLATFORM=arm-cross-hhl CONFIG=btweb
        $ sudo make all

At the end of the compilation (which takes more or less 300 kilo-bogoMIPS-second) you'll find a complete target tree in the Trees subdirectory, named after your configuration of choice: Trees/btweb. You can point your NFS-Root system directly to this directory, or move it over to a proper place.

Please note that this tree is not yet complete nor optimized. We'll achieve these aims in the next sections.

Next: , Previous: Building a Tree, Up: Building an EtLinux Filesystem

7.4 Fixing the Tree

The default configuration for EtLinux needs some tailoring to the target device it will be hosted in. For example, you most likely miss a few device special files. You can proceed in two ways: either by creating a different _base file, after the name of your configuration file, or by creating an application-specific customization rule-set.

Creating a different _base is pretty straightforward, as it amounts to just creating _base-btweb.tar.gz if you configuration is called btweb, and is documented in the EtLinux manual.

Creating a customization, on the other hand, means specifying what to remove from, what to add to and what to run on the target tree just installed. Here, we'll go with this option, the customization.

So, let's create a directory Customizations/btweb in the source directory of EtLinux (there's already is one in the etlinux-1.1 directory distributed with this package). In the directory you can create a file called RUN, one called DEL and a tree of files called ADD/. When the customization is run, the build process first copies over the ADD/ tree, then removes unwanted files and finally executes RUN. Again, this is documented in more detail in the EtLinux manual.

Since our main concern at this point is creating device files, the RUN command will be used to run mknod. This has been preferred over creating the special files into ADD/ because CVS isn't designed to bring over special files and this package is hosted in a CVS tree.

The RUN file must be given execute permission and is run in the root directory of the target tree. Please refer to the EtLinux manual for more details.

Another thing you might want to customize is the /etc/init.d/options file. To this aim, the copy that gets into the target tree is copied over from Customizations/btweb/ADD. The released copy is very similar to the default one: it removes the explicit configuration of the network address for eth0 (since we are using DHCP) and removes the "%Z" field in dates for log files, which doesn't work on our target. Having the configuration file in ADD/ eases possible future changes without the need to edit a patch file each time while fine-tuning the production system. The provided ADD tree also includes an /etc/ suitable to run the system without LD_LIBRARY_PATH, the new telnetd from the ettcl CVS tree, a version of httpd with PHP3 support.

In the DEL file, /etc/network.options is removed, from the target system, for the same reason. To save inodes, all the /dev/hd* entries are removed as well and other unneeded file (like /etc/applications/README).

To specify a list of customizations to the build command, you must pass them in the CUSTOM variable of make. Therefore the suggested compilation command line is now:

        $ sudo make all PLATFORM=arm-cross-hhl CONFIG=btweb CUSTOM=btweb

Next: , Previous: Fixing the Tree, Up: Building an EtLinux Filesystem

7.5 Adding the Application

To add your custom application, the easiest way is creating a customization called, for example, application. You then just need to create a directory ADD where you can copy all the files you need to add to the target system. In order to fire specific processes at boot time, you can add them to either /etc/init.d/respawn or /etc/init.d/applications.

Using respawn/ to host the application may be safer if the application may die and must be silently restarted. If it's never expected to die, on the other hand, you might want to use applications/ instead.

This package includes a trivial example, called sample-application, that places a file in /etc/init.d/respawn that prints an alive message once every minute seconds. To include it in the target tree, you can for example use:

        $ export PLATFORM=arm-cross-hhl CONFIG=btweb
        $ sudo make all CUSTOM="btweb sample-application"

If the application is an executable and not a script, you might want to issue a single sys_exec TCL command in the script file.

Next: , Previous: Adding the Application, Up: Building an EtLinux Filesystem

7.6 Customizing Busybox

The busybox package distributed with the EtLinux version used has a predefined Config.h file (customized by a patch, part of the EtLinux distribution. However, you might want to change the Config.h file by yourself, without generating a patch and re-extracting from source each time you try a different setup.

To this aim, the btweb package includes an EtLinux package called busybox-custom. The package relies on the source tarball for busybox, but copies Config.h from busybox-custom-0.60.2.cfg, found in the toplevel EtLinux directory.

The version in this distribution matches what Bticino staff chose as best for their application. If you need to change it, you can then recompile the EtLinux system to use the different choice of busybox tools. To recompile after changing the configuration file, use the following commands:

         rm -rf Trees/btweb
         rm tmp/busybox*.built
         make all CONFIG=btweb

In the example above, removing the tree is mandatory to prevent old files to remain in the target filesystem; removing the .built file is needed in order to force actual recompilation of the package, since the Makefile has no special dependency rule for the busybox-custom package.

Next: , Previous: Customizing Busybox, Up: Building an EtLinux Filesystem

7.7 Adding a /dev/printk device

tools/dpk.c contains the source code of a kernel module implementing a device named /dev/printk. Such device has a write() method only, which just passes its input buffer on to printk() with a KERN_INFO log level. As a result, whatever is written into /dev/printk gets queued to the kernel messages.

/dev/printk is registered as a misc device with major and minor numbers respectively equal to 10 and 68. A pre-compiled module (dpk.o) is part of the btweb customization, and is added to the target tree as /lib/dpk.o.

The same customization installs a script (S50logger) under /etc/init.d/scripts and creates the /dev/printk entry with proper major and minor numbers on the target tree. The role of S50logger is just to load /lib/dpk.o via /sbin/insmod at target startup.

Note that you can send all the logs to the kernel log buffer by symlinking /var/log/ettcl.log to /dev/printk or directly changing options(logfile) to /dev/printk in /etc/init.d/options.

Next: , Previous: Adding a /dev/printk device, Up: Building an EtLinux Filesystem

7.8 The udplogs application

udplogs is an ettcl application which reads kernel messages from /proc/kmsg and sends them to a configurable destination (broadcast messages allowed) using the UDP protocol.

As soon as it is started, udplogs reads the configuration file /etc/udplogs (if existing) and then whatever file is specified by options(udplogs:cfg).

At the moment just the option options(udplogs:dest) is considered. If options(udplogs:dest) contains a string of the form "IP:PORT", then the first part of the string, before the ':', is interpreted as an IP address (which must be specified in decimal dotted notation), while the second part, after the ':', is interpreted as a UDP port number. On the other hand, if options(udplogs:dest) does not contain any ':', then it is interpreted as a UDP port number and messages are sent to the broadcast IP address . If options(udplogs:dest) is not specified, it is assigned a default value equal to "26913". So udplogs messages are sent by default to port 26913 udp, using the broadcast IP address.

udplogs is part of the btweb customization and is installed under /etc/applications on the target tree. Note that such customization doesn't add any /etc/udplogs file, nor does it provide any value for options(udplogs:dest). So the default destination will be used unless you modify the btweb customization.

Previous: The udplogs application, Up: Building an EtLinux Filesystem

7.9 Creating the Temporary Filesystem

To avoid any delay in application execution during filesystem access, and to avoid data duplication in memory when executing your programs, the best option is using the tmpfs engine, if you have enough RAM to host the whole of the filesystem. However, tmpfs cannot be used as a root filesystem, because it must be filled by creating all the files one at a time before you can access its contents. In other words, you can't hand a tmpfs-image to the kernel to be mounted at boot time.

The suggested solution, therefore, is the following:

The /sbin/init0 script checks whether its own environment includes TARFILE as a variable, and whether its value identifies a readable file (or device). If the conditions are not met, then it prints a complaint message and runs the EtLinux system without adding the custom applications.

Next: , Previous: Building an EtLinux Filesystem, Up: Top

8 Overall System Setup

Now that we've compiled all the relevant parts of the system, let's set it up in its production configuration.

Next: , Previous: Overall System Setup, Up: Overall System Setup

8.1 Flash Partitions

Since the BtWeb device comes in two favors, with 4MB or 8MB of flash memory, there are two different partitioning configurations.

The kernel knows about the partitions configurations, since they are compiled-in inside drivers/mtd/maps/sa1100-flash.c. The kernel chooses which set of partitions to use according to the probed size of the flash memory.

Still, you should make RedBoot aware of at least the kernel and initrd images; telling him about all partitions is best, though.

A kernel compiled with the suggested configuration will use the static partition definition, but if you activate the CONFIG_MTD_REDBOOT_PARTS option, it will read RedBoot partitioning information and override the static definition.

To boot the kernel in the production setup with the partitioning configurations described below, the following boot script may be used (the third line has been split to fit in the page, but must be typed without newlines):

     fis load -c "kernel"
     fis load -c "etlinux"
     exec -b 0x100000 -l 0x80000 -r 0x400000
                 -c "root=/dev/ram init=/sbin/init0 TARFILE=/dev/mtd5"

Next: , Previous: Flash Partitions, Up: Flash Partitions

8.1.1 Partitions for 4MB

The 4MB-flash has been partitioned in the following way, with an erase block of 0x20000 (128kB):

mtd0: 0x000000-0x020000
This partitions hosts redboot code.
mtd1: 0x020000-0x040000
mtd2: 0x040000-0x060000
Application-specific configuration data. Two copies.
mtd3: 0x060000-0x0e0000
The kernel image (it must fit in 512 kB).
mtd4: 0x0e0000-0x2e0000
The initrd image (an ext2 filesystem hosting the whole of etlinux)
mtd5: 0x2e0000-0x360000
mtd6: 0x360000-0x3e0000
The application files, as a compressed tar file. Two copies.

To create the partitions from RedBoot while filling them with 1's, you can use the following commands:

       fis init -f
       mfill -b 0x100000 -l 0x200000 -p 0xff -1
       fis create -b 0x100000 -l 0x020000 -f 0x50020000 "cfg0"
       fis create -b 0x100000 -l 0x020000 -f 0x50040000 "cfg1"
       fis create -b 0x100000 -l 0x080000 -f 0x50060000 "kernel" -e 0x100000
       fis create -b 0x100000 -l 0x200000 -f 0x500E0000 "etlinux" -e 0x400000
       fis create -b 0x100000 -l 0x080000 -f 0x502E0000 "applications0"
       fis create -b 0x100000 -l 0x080000 -f 0x50360000 "applications1"

If you want to fill the partitions with the relevant data, you must fill the RAM with the data first. For example by reading it from the TFTP server. The following example shows how to write to flash a kernel and the base filesystem:

         load zImage.btweb -r -b 0x100000
         fis create -b 0x100000 -l 0x080000 -f 0x50060000 "kernel"
         load etlinux.btweb.gz -r -b 0x400000
         fis create -b 0x400000 -l 0x200000 -f 0x500e0000 "etlinux"

The result, as displayed by RedBoot, will look like this:

         RedBoot> fis list
         Name              FLASH addr  Mem addr    Length      Entry point
         RedBoot           0x50000000  0x50000000  0x00020000  0x00000000
         RedBoot config    0x503FF000  0x503FF000  0x00001000  0x00000000
         FIS directory     0x503E0000  0x503E0000  0x0001F000  0x00000000
         cfg0              0x50020000  0x50020000  0x00020000  0x00000000
         cfg1              0x50040000  0x50040000  0x00020000  0x00000000
         kernel            0x50060000  0x50060000  0x00080000  0x00100000
         etlinux           0x500e0000  0x500e0000  0x00200000  0x00400000
         applications0     0x502e0000  0x502e0000  0x00080000  0x00000000
         applications1     0x50360000  0x50360000  0x00080000  0x00000000

Previous: Partitions for 4MB, Up: Flash Partitions

8.1.2 Partitions for 8MB

The 8MB-flash has been partitioned in the following way:

mtd0: 0x000000-0x040000
This partitions hosts redboot code.
mtd1: 0x040000-0x0a0000
mtd2: 0x0a0000-0x100000
Application-specific configuration data. Two copies.
mtd3: 0x100000-0x220000
The kernel image (it must fit in 512 kB).
mtd4: 0x220000-0x520000
The initrd image (an ext2 filesystem hosting the whole of etlinux)
mtd5: 0x520000-0x660000
mtd6: 0x660000-0x7a0000
The application files, as a compressed tar file. Two copies.

To create the partitions from RedBoot while filling them with 1's, you can use the following commands:

       fis init -f
       mfill -b 0x100000 -l 0x300000 -p 0xff -1
       fis create -b 0x100000 -l 0x060000 -f 0x50040000 "cfg0"
       fis create -b 0x100000 -l 0x060000 -f 0x500a0000 "cfg1"
       fis create -b 0x100000 -l 0x120000 -f 0x50100000 "kernel" -e 0x100000
       fis create -b 0x100000 -l 0x300000 -f 0x50220000 "etlinux" -e 0x400000
       fis create -b 0x100000 -l 0x140000 -f 0x50520000 "applications0"
       fis create -b 0x100000 -l 0x140000 -f 0x50660000 "applications1"

If you want to fill the partitions with the relevant data, you must fill the RAM with the data first. For example by reading it from the TFTP server. The following example shows how to write to flash a kernel and the base filesystem:

         load zImage.btweb -r -b 0x100000
         fis create -b 0x100000 -l 0x120000 -f 0x50100000 "kernel"
         load etlinux.btweb.gz -r -b 0x400000
         fis create -b 0x400000 -l 0x300000 -f 0x50220000 "etlinux"

The result, as displayed by RedBoot, will look like this:

         RedBoot> fis list
         Name              FLASH addr  Mem addr    Length      Entry point
         RedBoot           0x50000000  0x50000000  0x00040000  0x00000000
         RedBoot config    0x507FF000  0x507FF000  0x00001000  0x00000000
         FIS directory     0x507E0000  0x507E0000  0x0001F000  0x00000000
         cfg0              0x50040000  0x50040000  0x00060000  0x00000000
         cfg1              0x500A0000  0x500A0000  0x00060000  0x00000000
         kernel            0x50100000  0x50100000  0x00120000  0x00100000
         etlinux           0x50220000  0x50220000  0x00300000  0x00400000
         applications0     0x50520000  0x50520000  0x00140000  0x00000000
         applications1     0x50660000  0x50660000  0x00140000  0x00000000

Previous: Flash Partitions, Up: Overall System Setup

8.2 Initrd Filesystem

The EtLinux filesystem is loaded as a ramdisk, using ext2 as storage medium. Smaller filesystems can be considered, but so far have not been, since dropping ext2 from the current configuration won't help gaining another 128kB block.

To create the ext2 image, you can use the script found in tools/btweb.ext2, calling it from within the toplevel btweb directory (i.e, Trees/btweb in your EtLinux build directory. The compressed filesystem image will be left in the parent directory.

        ostro% cd Trees/btweb
        ostro% sudo ../../../tools/btweb.ext2
        Creating host file
        4096+0 records in
        4096+0 records out
        Making a filesystem
        mke2fs 1.27 (8-Mar-2002)
        Creating the mount point and mounting
        Filling and unmunting
        Compressing file system
        -rw-r--r--  1 root   root  1112501 Sep 23 12:42 ../etlinux.btweb.gz

This filesystem can then be copied where TFTP can load it and programmed into flash as shown above in Flash Partitions. As an alternative, you can write the file to /dev/mtd4 after booting via NFS-Root:

        ostro% telnetc btweb 230
        % bash
        bash# erase /dev/mtd4  0 16
        Erase Total 8 Units
        Performing Flash Erase of length 131072 at offset [...] done
        bash# cat etlinux.btweb.gz > /dev/mtd4

A similar procedure can be used to write the compressed tar of application files to /dev/mtd5.

Previous: Overall System Setup, Up: Top

9 Additional Packages

Next: , Previous: Additional Packages, Up: Additional Packages

9.1 PHP-3

To compile PHP version 3, I downloaded the source tar file php3-3.0.18.orig.tar.gz and the patch php3_3.0.18-23.1woody1.diff.gz from a Debian mirror, and issued the following commands:

        tar xvzf php3-3.0.18.orig.tar.gz
        cd php3-3.0.18
        zcat ../php3_3.0.18-23.1woody1.diff.gz | patch -p1
        export CC=sa110_le-gcc
        ./configure --without-pcre-regex --without-posix --disable-displ

The whole process takes approximately 120 kilo-bogoMIPS-second, and you'll end up with a binary called php of 1.2MB, 420kB when stripped.

Previous: PHP-3, Up: Additional Packages

9.2 PHP-4

Similarly, to compile PHP version 4, I downloaded the source tar file php4_4.1.2.orig.tar.gz and the patch php4_4.1.2-6.diff.gz from a Debian mirror.

Still, a few autoconf tests don't provide a default for cross-compiling, so another patch must be applied; such patch is available in the btweb package as patches/php4.patch; after applying the patch you must reissue autoconf in order to generate the configure script with the new m4 macros.

Summarizing, I ran the following commands:

        tar xvzf php4_4.1.2.orig.tar.gz
        cd php-4.1.2
        zcat ../php4_4.1.2-6.diff.gz | patch -p1
        cat $BTWEB/patches/php4.patch | patch -p1
        export CC=sa110_le-gcc
        ./configure --without-pear --without-pcre-regex --disable-posix \
                    --with-gnu-ld --without-mysql --disable-experimental-zts \

The whole process takes approximately 250 kilo-bogoMIPS-second, and you'll end up with a binary called php of 2.3MB, 920kB when stripped. The binary is linked with the following shared libraries:

        bash# LD_TRACE_LOADED_OBJECTS=1 /tmp/php
       => /lib/ (0x4001e000)
       => /lib/ (0x40029000)
       => /lib/ (0x4005d000)
       => /lib/ (0x40074000)
       => /lib/ (0x400b1000)
       => /lib/ (0x400d0000)
                /lib/ => /lib/ (0x40000000)

Since libnsl is not normally installed, you'll need to add it to your target tree and recreate /etc/ by running ldconfig. A static binary for ldconfig is included in the tools directory of this package, so you can recreate your according to your chosen final setup.

Table of Contents