Version: 1.3
Author: Miguel A. Diaz
NOTES TAKEN REGARDING THE GIGASET M740AV FIRMWARE DEVELOPMENT
--------------------------------------------------------------------------------------------------------------------
The notes published in this document were taken during my work trying to build a
new firmware IPv6 capable for the GIGASET M740AV by Siemmens. This document
doesn't try to be a complete "HOWTO" guide in order to provide all the insight
needed to address all the stages in the firmware development. It only collects
the difficulties and the actions I've carried out to overcome such difficulties
so that it becomes a good guide to me or others trying to emulate my work.
It is absolutely necessary understand all the steps pointed in this document and
how to carried out them when no instructions are provided because, as I said
above, I don't give any instruction that could be considered as basic.
Below the content of this document is shown.
[1] NOTES TO BUILT MY OWN GIGASET M740V FIRMWARE
[2] NOTES TO BUILD THE BUILDROOT TOOLCHAIN
[3] NOTES TO BUILD MY OWN TOOLCHAIN
[4] NOTES TO CROSS-COMPILING SOFTWARE
[5] NOTES ABOUT LINUX-2.4-XFS
[6] NOTES ABOUT COMPILING THE LINUX-2.4-XFS KERNEL
[7] MISCELLANEOUS
[8] ACKNOWLEDGMENTS
[1] NOTES TO BUILT MY OWN GIGASET M740V
FIRMWARE
The information that I have followed has been collected from
- the Lemmi's WSW HowTo
-
http://www.m740.com/phpBB2/viewtopic.php?t=133
1) I've downloaded the official 1_44_cf firmware from the
Gigaset Firmware Portal
2) I've extracted the root-filesystem from the 1.44.4_cf.wsw file
dd if=siemens-wsw-file
of=cramfs_cf ibs=1 obs=1M count=6M skip=1416
3) I've swapped the cramfs_cf file because the Intel architecture in endian-opposite
to the one used in the MIPS-based gigaset architecture.
3.1) For that it is needed to use the cramfsswap tool, but I
first have to download and compile it.
3.1.1) I've downloaded it from
http://kju.de/projekte/cramfsswap/cramfsswap-1.1.tar.gz
3.1.2) I've just compiled as usual by
making 'make'
3.2) Then I've swapped the file cramfs_cf cramfsswap
cramfs_cf cramfs_cf_intel
4) I've mounted the cramfs filesystem
mkdir /mnt2
mount -o loop -t cramfs cramfs_cf_intel /mnt2
5) I've made a tarball with the gigaset root-filesystem that I've just mounted
tar cvjf
cf_1_44_4_original.tar.bz2 -C /mnt2 . (the final dot is important)
unmount /mnt2
6) I've installed the gigaset root-filesystem
tar xvjf
cf_1_44_4_original.tar.gz2 -C cramfs_fs
7) Modify the root-filesystem (cramfs_fs) as required
8) Create the new cramfs file
./mkcramfs -bb
root-filesystem private.cramfs (mkcramfs is provided by Lemmi in his
toolkit)
9) The new cramfs filesystem has to be copied into the wsw file, (the right
position), then the checksum has to be added to the whole wsw file (the right
position) and finally the file has to be signed with the private key
cp -p
1.37.4.wsw private.wsw
dd if=private.cramfs of=private.wsw obs=8 seek=177 conv=notrunc
(Optionally the version name in the header can be modified. To do so, it is
necessary to put before the 1100 position the new label. It can be edited
directly with vi because it is big-endian, so it should be done in the target)
dd if=private.wsw
ibs=1K skip=1 obs=1M | md5sum > md5sum
./rsaencode private.rsa < md5sum | dd of=private.wsw obs=8
seek=1 conv=notrunc
the rsaencode and the private.rsa files are provided by Lemmi in his toolkit
[2] NOTES TO BUILD THE BUILDROOT
TOOLCHAIN
The uClibc site provides a tool called
buildroot to build a
toolchain for several architectures, which includes the MIPS one. Such a
tool includes all the components needed to build the toolchain and it uses the
uclibc library rather than the legacy glibc. Initially the uclibc was developed
to support CPU without memory processor, but later its scope was extended and
today it supports many types of CPUs, with or without memory processor. The
uclibc has nearly the same functionality that the glibc one. However the former
has a lower size that makes it better choice to be included in embedded systems.
According to the firmware sources provided by Siemens, the GIGASET M740AV has
been built with uClibc library. At the /lib
directory within the root file system, all the libraries used by the system can
be found. The version of such libraries is uClibc-0.9.19. The version is very
important because there are important incompatibility issues among different
versions.
IMPORTANT: The toolchain built by using the latest buildroot tool is based on
the uclibc-0.9.27 version, which is no compatible with the one used by the
M740AV firmware (uclibc-0.9.19). This means that all
the libraries provided by the toolchain has to be included in the M740AV
firmware in order to support all the binaries compiled wich such a toolchain.
1) I've followed the instructions at
http://www.uclibc.org/toolchains.html to build a toolchain based on uClibc
library
1.1) I've downloaded a copy of the buildroot tool
1.2) I've configured such a buildroot with minimal support
- Busybox support
- Enable cramfs filesystem rather the
default one
- gcc version: 3.4.2
- binutils version: 2.16.1
- kernel headers: 2.4.25
- the c++ compiler is not set
All the above options are configured
by means the make menuconfig command
1.3) I've modified the
Makefile file to change the line
include .config
rather than
include .config.cmd
1.4) I've modified the package/busybox/busybox.config file by enabling two oprtions regarding IPv6
1.5) I've run make
- MIPS-I type
- Big endian
2) The process is compiled and installed without problems
3) I've compiled the typical hello-world program with such a toolchain with no
problems. Also I've compiled the busybox-1.0 program (a program that implements
most of the system tools like cp, ls, strings, mkdir,
etc. and it's lower in size) with no problems. The compilations for both
programs were not only dynamic but also static.
The static binaries works perfectly in the M740AV (once they were uploaded)
but the dynamic binary versions caused a Segmentation Fault, which is
logical because they required the uclibc-0.9.27 version which is not compatible
with the uclibc-0.9.19 version installed at the M740AV, as I said above.
[3] NOTES TO BUILD MY OWN TOOLCHAIN
Given the fact that it was not possible by using the buildroot tool (see the
item [2] above) to build a toolchain based on the same
components that the ones used to build the M740AV firmware (egcs-1.1.2, uclibc
0.9.19, linux kernel 2.4.21, etc.) I decided to build my own toolchain based on
such components.
This isn't a trivial work at all because there are a lot of things that can fail
(file-dependencies, version incompatibilities, etc.). I've studied a lot of
stuff in this matter and I've done a lot of tries before I succeeded. Some good
general information are the following:
-
http://geek.vtnet.ca/embedded/KuroBox/cross-procedure.html
- Building Embedded Linux Systems (Book), by Karim Yaghmour.
Publisher: O'Reilly
ISBN : 0-596-00222-X
I've basically followed the instructions pointed at
http://www.void.at/andi/papers/claxan_compile.txt (*) to build my
cross-compiler. Such instructions are specific for other system (NAS113), but
its philosophy is adequate for my needs.
I've downloaded the following software:
ftp://ftp.gnu.org/gnu/binutils/binutils-2.15.tar.bz2
ftp://ftp.gnu.org/gnu/gcc/gcc-3.3.4/gcc-core-3.3.4.tar.gz
ftp://ftp.fu-berlin.de/unix/languages/gcc/old-releases/egcs/egcs-1.1.2.tar.bz2
ftp://ftp.linux-mips.org/pub/linux/mips/gcc/egcs/egcs-1.1.2.diff.gz
ftp://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.5.tar.gz
ftp://ftp.gnu.org/gnu/glibc/glibc-2.2.5.tar.gz
http://www.void.at/andi/patches/glibc-2.2.5-mipsel-linux.diff
linux kernel: linux-2.4.21-xfs provided by Siemens in the M740AV sources.
uClibc-0.9.19 source directory provided by Siemens
Also I've to upgrade my gcc compiler to the
gcc-3.3.5 version
Basically, the toolchain building involves five steps:
1) Building binutils. These are several tools used by the cross-compiler
and they are architecture-dependent. Some of them are for example
ld, ranlib, etc. I've installed the binutils-2.15
version. I've followed the steps pointed at (*)
2) Building a minimal cross-compiler (bootstrap compiler). Building the
whole cross-compiler to the specific architecture (MIPS for the M740AV) makes
that the compiler lies on the glibc library for those things that are
architecture-specific. However to build the glibc library with support for the
new architecture requires a compiler with the new-architecture support which is
what we want to do. This is similar to the "chiken and egg" problem and it is
known as the bootstrap-compiler issue which is solved by building first a
minimal cross-compiler.
To do so, I've again followed the steps
pointed at (*).
I've read somewhere that it is essential for making a MIPS-target cross-compiler
to use the comands 'with-gnu-as and with-gnu-ld' when compiling the gcc
compiler. This is related to certain lack of support for such architecture.
After that, it is necessary to make the kernel headers setup. For that, I've
copied the whole linux-2.4.21-xfs directory provided by Siemens in other
location. Important:
- there are two files that has to be copied by hand (one is
semaphore.c and the other one I don't remember);
- it is necessary to redirect the symbolic link located at
./linux-2.4-xfs/linux/include/asm-generic/asm
and point it to ./linux-2.4-xfs/linux/include/asm
- it is necessary to create the file
./linux-2.4-xfs/linux/include/asm-mips/setup.h
It is no necessary that it has content, just it exists. (0 byes is OK).
- after doing make menuconfig,
I've copied not only the
./linux/include/linux
and
./linux/include/asm-mips
directories, but also the
./linux/include/asm-generic
one to the TARGET/include
3) Building the simple glibc library. It has
the target-architecture support to the bootstrap cross-compiler built at the
previous step. Again, I've followed the instructions pointed at (*).
4) Building the full and complete cross-compiler. By using the
information provided by the simple-glibc target-dependant library we build the
complete cross-compiler. To do that we don't use again the gcc-3.3.4 but the
egcs-1.1.2. I don't know why the egcs-1.1.2 compiler is used at (*)
but I've decided to use due to two reasons:
- I've read somewhere that the egcs compiler is needed for
compilers for MIPS architectures
- The /proc/version information
provided by the M740AV informs that the system was built with the egcs-1.1.2
compiler, so it seems to me that it is a very good reason to choose it.
To make this step I've found some issues that I had to fix:
- replace line 37 at
egcs-1.1.2/gcc/frame.h "size_t count" by
"SIZE_TYPE__ count;" (quotes are not needed in the
file)
- the makeinfo binary (or a
symbolic link) has to be located at the /build-egcs/texinfo/makeinfo
directory. The makeinfo binary doesn't belong to the
egcs package and it will likely be installed in /usr/bin/
5) Building the full library set target-architecture-specific. This
provides all the required libraries needed by the cross-compiler to be included
into the binaries that will run at the target host (M740AV in our case). The
libraries will be located likely under the /lib
directory at the target. This step should be done in a normal case with the
previous glibc package, however we will work with the uclibc-0.9.19 library
which is the one used in the M740V. For this reason the full library set will be
created by using the uclibc-0.9.19 library provided by Siemens.
On the other hand, we can't use the uclibc library to make the step
3 above because it uses some information provided
by the glibc library once it has been built in a simple way for a specific
architecture. Hence, to build the libraries based on uclibc we need both
packages (the glibc compiled according to step 3 above
and the uclibc-0.9.19 package).
In this step I've also found several issues that I've fixed as follows:
5.1) I had problems with the
./uclibc-0.9.19/extra/locales files. The information provided at the
./uclibc-0.9.19/extra/locale/README file is a bit
tricky, so I've decided don't include 'locale'
support for uclibc. To do so it is necessary disable the option
LOCALE in the "String and Stdio
Support" menu.
5.2) I had to modified the
./uclibc-0.9.19/ldso/ldso/mips/boot1_arch.h
file as follows, from line 6 on:
asm("" \
" .text\n"
\
" .globl _dl_boot\n"
\
"_dl_boot:\n"
\
" .set
noreorder\n"
\
" bltzal $0,
0f\n"
\
" nop\n"
\
"0: .cpload $31\n"
\
" .set
reorder\n"
\
" la $4,
_DYNAMIC\n" \
" sw $4,
-0x7ff0($28)\n" \
" move $4,
$29\n"
\
" la $8, coff\n"
\
" .set
noreorder\n"
\
" bltzal $0,
coff\n"
\
" nop\n"
\
"coff: subu $8, $31, $8\n"
\
" .set
reorder\n"
\
" la $25,
_dl_boot2\n" \
" addu $25,
$8\n"
\
" jalr $25\n"
\
" lw $4,
0($29)\n"
\
" la $5,
4($29)\n"
\
" sll $6, $4,
2\n"
\
" addu $6, $6,
$5\n" \
" addu $6, $6,
4\n"
\
" la $7, _dl_elf_main\n"
\
" lw $25,
0($7)\n"
\
" jr $25\n"
\
);
the syntax in the original file caused problems with the compiler because
the lack of the quotes.
5.3) I've modified the
./uclibc-0.9.19/libc/sysdeps/linux/common/initfini.S
file because the linker showed a problem with two '.end'
directives in such a file. The file is generate after starting the compilation.
I've deleted the original lines with the '.end _init'
and '.end _fini' commands and I've put them in lines
68 and 119 respectively, just bejore the #APP
command each.
After the previous steps I've my own mips-target cross-compiler based in:
- egcs-1.1.2
- uclibc-0.9.19
I've checked it by compiling two applications (not only statically but also
dynamically) with the cross-compile just built: the typical hello-world and the
busybox application. Both of them have been successfully ran at the M740AV with
the firmware installed by Siemens
[4] NOTES TO CROSS-COMPILING SOFTWARE
1) It is necessary to built the toolchain (binutils, gcc compiler and glibc
library -uClibc instead is also OK-). See notes above.
2) After that, the configure,
make and make install typical process can be
followed, but some particular actions are required. The following is an example
of the compilation of the tar-1.13.25 packet I've cross-compiled.
2.1) Untar the source
2.2) Run configure with the following instructions:
./configure --host=mips-linux
--prefix=/home/mad/gigaset_m740v/my_target/tools/test/ \
CC=/home/mad/gigaset_m740v/my_target/build-tools/buildroot/build_mips/staging_dir/mips-linux/bin/gcc
2.3) Depends on the configure file, it might be necessary to
switch the --host command by the
--target command. It refers to the architecture
where the binary will be running.
2.4) After that, I've run make,
as usual
2.5) Some errors are shown while doing
make, because the libraries made have no index or something like that. A
message is shown to run the ranlib command, but be
careful because such a command is the one generate by the toolchain rather than
the one existing in the host system. The command is in the same directory than
gcc, in my case:
/home/mad/gigaset_m740v/my_target/build-tools/buildroot/build_mips/staging_dir/mips-linux/bin/ranlib
2.5.1) The
errors were fixed by adding the LD and
RANLIB variables in the command line:
./configure --host=mips-linux
--prefix=/home/mad/gigaset_m740v/my_target/tools/test/ \
CC=/home/mad/gigaset_m740v/my_target/build-tools/buildroot/build_mips/staging_dir/mips-linux/bin/gcc
\
LD=/home/mad/gigaset_m740v/my_target/build-tools/buildroot/build_mips/staging_dir/mips-linux/bin/ld
\
RANLIB=/home/mad/gigaset_m740v/my_target/build-tools/buildroot/build_mips/staging_dir/mips-linux/bin/ranlib
Maybe other variables related to the compilation process could be needed:
AS, AR, CC, CPP, LD, NM, OBJCOPY, OBJDUMP, RANLIB, READELF,
SIZE, STRINGS, STRIP
Most of them are binaries installed under my direcotory:
/home/mad/gigaset_m740v/my_target/build-tools/buildroot/build_mips/staging_dir/mips-linux/bin/
during the toolchain installation process.
2.6) When the compilation is finished without any errors,
then I've run make install, as usual and all
the required files are installed under the directory I've configured with the
configure command:
/home/mad/gigaset_m740v/my_target/tools/test
2.7) You can do file
home/mad/gigaset_m740v/my_target/tools/test/bin/tar to check that the
generated binary is executable only in a MIPS-I architecture
[5] NOTES ABOUT LINUX-2.4-XFS
The linux kernel included in the sources provided by Siemens is the
linux-2.4.21-xfs, so I assume that it is the one used to build the M740AV
firmware. This assumption is confirmed by the /proc/version
information provided by the M740AV.
From
http://linuxjunkies.org/html/Linux+XFS-HOWTO.html#AEN20, this linux kernel
supports the XFS filesystem that is extremely scalable, using btrees extensively
to support large sparse files, and extremely large directories. The journalling
capability means no more waiting for fsck's or worrying about meta-data
corruption.
To configure the xfs support into the kernel (not as module) there are several
options:
- Page Buffer support in Filesystems
- SGI XFS filesystem support in Filesystems
- Prompt for development and/or incomplete code/drivers in
Code maturity level options
- Optionally: Enable XFS Debug mode in SGI XFS filesystem
support
- Optionally: Enable XFS Vnode Tracing in SGI XFS filesystem
support
[6] NOTES ABOUT COMPILING THE
LINUX-2.4-XFS KERNEL
With my own cross-compiler (egcs-1.1.2/uclibc-0.9.19) I've
tried to compile the linux version provided by Siemens and I've had to fix the
following issues:
1) the -mcpu command is not supported by the
mips-uclibc-ld binary. Theoretically it supports the
-mCPU (deprecated), -march
and -mtarget
commands which have the same meaning. I've modified the scripts that uses the
-mcpu command. All the files are refered to
linux-2.4-xfs/linux/
directory:
arch/arm/Makefile
arch/pps/Makefile
arch/mips/Makefile, .#Makefile.1.10,
.#Makefile.1.12, Makefile.my
arch/mips/kernel/.#Makefile.1.8
arch/sparcs64/Makefile
arch/mips64/Makefile
Firstly I replaced in such files the command -mcpu
by -march. But it wasn't either valid. Indeed I
tried with all the theoretically supported commands (-mCPU,
-march and -mtarget) but without success. For
this reason I deleted the -mcpu command on all the
files.
2) it is necessary to create the file ./linux-2.4-xfs/linux/include/asm-mips/setup.h
It is no necessary that it has content, just it exists. (0 byes is OK).
Alternatively, you can comment the line 31 in the file
./linux/drivers/mtd/cmdlinepart.c which is
#include <asm/setup.h>.
3) Depeding on the gcc/uclibc version, it might be necessary to modify several "out:
" lines within the file
./linux/arch/mips/mm/c-r4k.c. It seems that the lack of ";"
might cause compilation errors.
4) I modified the ./linux-2.4-xfs/linux/arch/mips/ld.script.in.
I've replaced the first line 'OUTPUT_FORMAT("elf32-bigmips")'
by 'OUTPUT_FORMAT("elf32-big")' (simple quotes are
not necessary). This is because the elf32-bigmips
format is not supported by the mips-uclibc-ld
linker. (I assume that elf32-big and
elf32-bigmips format are equivalent)
5) All the steps involved in the kernel compilation has been done successfully (make
menuconfig, make vmlinux, make modules, make modules_install). The
last one fails because the module-dependencies checking is not supported by the
cross-compiler. To make manually this step I've use the 'depmod.pl'
perl binary provided by the busybox package.
6) The depmod.pl script informs about the lack of
depency of several links related to the usb support.
Specifically the following symbols are unresolved:
* unresolved symbol
tty_ldisc_deref in file
/lib/modules/2.4.21-xfs/kernel/drivers/usb/serial/usbserial.o
* unresolved symbol
tty_ldisc_ref in file
/lib/modules/2.4.21-xfs/kernel/drivers/usb/serial/usbserial.o
* unresolved symbol
tty_wakeup in file
/lib/modules/2.4.21-xfs/kernel/drivers/usb/serial/io_ti.o
* unresolved symbol
tty_ldisc_flush in file
/lib/modules/2.4.21-xfs/kernel/drivers/usb/serial/digi_acceleport.o
* unresolved symbol
tty_wakeup in file
/lib/modules/2.4.21-xfs/kernel/drivers/usb/serial/digi_acceleport.o
* unresolved symbol
tty_wakeup in file
/lib/modules/2.4.21-xfs/kernel/drivers/usb/serial/io_edgeport.o
* unresolved symbol
tty_wakeup in file
/lib/modules/2.4.21-xfs/kernel/drivers/usb/serial/keyspan_pda.o
There are two ways to fix this issue:
a) Don't choose USB Serial support during the kernel
configuration # CONFIG_USB_SERIAL is not set
b) Make a symbolic link at ./linux/drivers/usb
pointing to ./linux/drivers/usb.2.4.21 I don't know
why exist two usb directories under
./linux/drivers. The one named
/usb.2.4.21 seems clear to me that corresponds to the linux kernel
2.4.21. However the other one named just /usb I
don't know which kernel version corresponds to but it seems to fail with the
reference pointed above. Some information extracted from the Internet says that
such symbols are modutils dependant, so maybe the
best way to work is used the /usb.2.4.21 directory.
7) The image kernel within the WSW file seems to be in (gzipped)
vmlinux.bin format. For that reason I've compiled my
own image kernel in such a format. However there is no rules for
vmlinux.bin in the Makefile
file on ./linux so I've done the work manually:
1) I've modified the ./linux/arch/mips/ld.script.in
by changing the first line to OUTPUT_FORMAT("binary")
2) I've compiled the kernel as usual (make
ARCH=... CROSS_COMPILE=... dep, make ARCH=... CROSS_COMPILE=... vmlinux).
At the end of the last step, there is an error message:
"...mips-uclibc-nm vmlinux format file do not
recognized" (or somethin like that) and the
System.map file isn't created.
To fix this issue I've done the following:
..../mips-uclibc-nm a.out | grep -v
'\(compiled\)\|\(\.o$\)\|\( [aUw] \)\|\(\.\.ng$\)\|\(LASH[RL]DI\)' \
| sort > System.map
The previosus is the command executed when compiling the kernel with ELF format
but I've changed the vmlinux file by the
a.out file which is generated when the
OUTPUT_FORMAT is put to "binary"
and it is recognized by the mips-uclibc-nm binary.
[7] MISCELLANEOUS
It seems that there is a SDK for small embedded linux systems with all the
software toolchains-components included in the M740V source. It is called SPEED
Kit:
http://www.mcobject.com/speedkit.shtml
It includes:
Linux operating system for MIPS32-architecture
- GNU toolchain including
- gcc 3.2.1, glibc 2.3.1, gcc for uclibc 3.2.3, uclibc
0.9.19
- Linux kernel 2.4.21 (GPL license)
- GNU debugger MIPS cross gdb 5.3, gdbserver
- Debug monitor (serial, Ethernet and EJTAG)
- BSP inclusive JFFS2, CF IDE
- Busybox 1.00 with over 100 standard Unix utilities
This SDK has the same components used to build the M740AV firmware, which makes
me think that it was used as development environment by the Siemens people.
[8] ACKNOWLEDGEMENTS
I would like to acknowledge the European Commission support in the co-funding of
the PlaNetS project, where this work is being developed.