|
Bt-Web 0.80 |
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.
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.
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:
NM2B”
NM2B”
NM2B”
NM2B”
NM2B”
The jflash-btweb program receives a single argument on the command line and writes it to flash starting at offset 0.
This chapter describes the steps needed to compile a RedBoot instance that works on the BtWeb supporting all the devices needed at boot time.
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.05.07.22.00.00 in my CVS/Entries file.
To checkout the ECOS repository, do the following:
cvs -d :pserver:anoncvs:anoncvs@sources.redhat.com:/cvs/ecos \
login
[type anoncvs as password]
cvs -d :pserver:anoncvs:anoncvs@sources.redhat.com:/cvs/ecos \
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.
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/')
done
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.
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: 192.168.16.40/255.255.255.0, Gateway: 192.168.16.14
Default server: 192.168.16.14, DNS server IP: 0.0.0.0
The kernel I used in the BtWeb device is version
linux-2.4.18-rmk7. The original source code is available as:
ftp://ftp.it.kernel.org/pub/linux/kernel/v2.4/linux-2.4.18.tar.bz2
ftp://ftp.arm.linux.org.uk/pub/linux/arm/kernel/v2.4/patch-2.4.18-rmk7.gz
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.
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.
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.
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/config.in
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*
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/config.in 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.
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.
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.
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).
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:
CONFIG_I2C
CONFIG_I2C_ALGOBIT
CONFIG_I2C_BIT_SA1100_GPIO
CONFIG_I2C_CHARDEV
CONFIG_I2C_PROC
CONFIG_L3
CONFIG_BIT_SA1100_GPIO
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:
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:
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SA1100_WATCHDOG=y
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
}
}
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.
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
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
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.
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.
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
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/config.in
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/config.in
patch -p1 < $BTWEB/patches/memsize.patch
patching file arch/arm/mach-sa1100/btweb.c
patching file arch/arm/config.in
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.
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.
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”.
The patch file patches/v2.6/linux-2.6.0-test2-rmk1-btweb.patch applies the following modification:
BTWEB platform
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.
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.
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 :pserver:cvs@ar.linux.it:/data/cvs login
cvs -d :pserver:cvs@ar.linux.it:/data/cvs \
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.
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.
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.
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/ld.so.cache 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
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.
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.
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.
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 255.255.255.255 .
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.
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:
init=/sbin/init0.
It mounts a tmpfs and
copies over the whole ramdisk image to that filesystem. It
then decompresses the compressed tar file found in another
MTD partition. The name of the tar file to be used in
filling tmpfs can be passed to first init0 as an
environment variable, by placing it on the kernel command-line
as “TARFILE=/dev/mtd5” or equivalent.
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.
Now that we've compiled all the relevant parts of the system, let's set it up in its production configuration.
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"
The 4MB-flash has been partitioned in the following way, with an erase block of 0x20000 (128kB):
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
The 8MB-flash has been partitioned in the following way:
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
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.
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.
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
autoconf
export CC=sa110_le-gcc
./configure --without-pear --without-pcre-regex --disable-posix \
--with-gnu-ld --without-mysql --disable-experimental-zts \
--disable-xml
make
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
libdl.so.2 => /lib/libdl.so.2 (0x4001e000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x40029000)
libresolv.so.2 => /lib/libresolv.so.2 (0x4005d000)
libm.so.6 => /lib/libm.so.6 (0x40074000)
libnsl.so.1 => /lib/libnsl.so.1 (0x400b1000)
libc.so.6 => /lib/libc.so.6 (0x400d0000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Since libnsl is not normally installed, you'll need to add it to your target tree and recreate /etc/ld.so.cache by running ldconfig. A static binary for ldconfig is included in the tools directory of this package, so you can recreate your ld.so.cache according to your chosen final setup.