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.