Compiling the iMote2 kernel

From University of Washington - Ubicomp Research Page
Jump to: navigation, search


Build Tools

    Title Link Description
    iMote2 Toolchain updated Mainstone version Use either the updated Mainstone version with an updated version of binutils. The toolchain is similar but won't build the kernel.

Needed Files

    Title Link Description
    PlatformX 1.0 Release or local mirror General PlatformX kernel build
    MSB2 Specific patches here Kernel patches and .configs
    2.6.14 linux kernel or local mirror
    iMote2 JFFS2 image fs.jffs Our default starting point JFFS2 image
    Zydas ZD1211(b) wifi driver* here and .config patch
    Advanced router kernel patch here Enables multiple internet connections
    Lib Bluetooth here Needed for some RFCOMM applications
    • Zydas driver:
      • Official version is available from
      • Non-official versions (with bug fixes) are available from

Getting Started

If you simply want to build the kernel, the easiest way is to just run the typical build script at the bottom of the page, here.

Typical Build

  • MSB2 Build
  • Windows RNDIS Gadget Driver
  • Wifi Module
  • No Standard UART console

Note, make sure the PATH is correct for your compiler and that you run this under tcsh.
Note, the fs.jffs2 image retrieved (and its download path) typically change as the system image evolves.
Note, that "rm -rf /something" is used in this file so use it at your own risk (especially since some parts like mounting and loading modules must be run as root). It is recommended that you past each line by itself (or in small groups) to avoid any problems and to ensure a successful build


setenv PATH "/usr/local/arm/3.4.3_binutils/bin/:${PATH}"
setenv ARCH arm
setenv CROSS_COMPILE arm-linux-
tar zxf linux-2.6.14.tar.gz 
tar zxf msb2_patches.tgz
tar zxf zd1211-driver-r83.tgz
tar zxf fs.tgz
tar zxf SG2Release-1_0.tgz
cd ./SG2Release-1_0/buildTree
tar zxf platx-10.tgz
cd ../../

echo "--------------------"
echo "Building and compiling Kernel"
cd linux-2.6.14
echo "Applying SG2 Patches"
patch -p1 < ../SG2Release-1_0/src/patch-2.6.14-sg2-10

echo "Applying MSB2 Patches and kernel config"
patch -p1 < ../camera-fix.patch
patch -p1 < ../msp-linux-2.6.14-pxa-mmc.patch
patch -p1 < ../msp-linux-2.6.14-uart.patch
patch -p1 < ../msp-linux-2.6.14-sd-detect.patch
patch -p1 < ../msp-linux-2.6.14-led-on-during-boot.patch
patch -p1 < ../msp-linux-2.6.14-regmon.patch
echo "Applying SD-Card Patches for DMA trasnfers"
patch -p1 < ../sd-patches.patch
echo "Copying linux configuration defaults"
cp ../msp-linux-2.6.14-config ./.config

if($PLATX_NIX_GADGET == 0) echo "Applying Windows RNDIS Patches"
if($PLATX_NIX_GADGET == 0) patch -p1 < ../msp-linux-2.6.14-winXP-rndis.patch

if($PLATX_NIX_GADGET) sed -e 's;CONFIG_USB_ETH_RNDIS=y;# CONFIG_USB_ETH_RNDIS is not set;g' .config -i
if($PLATX_NOCONSOLE) echo "No Console patch 1 of 3 (kernel)"
if($PLATX_NOCONSOLE) patch -p1 < ../msp-linux-2.6.14-noConsole_boot.patch
if($PLATX_NOCONSOLE) patch -p1 < ../msp-linux-2.6.14-noConsole_config.patch
patch -p1 < ../msp-linux-2.6.14-networking.patch

echo "Building kernel"
setenv ARCH arm
setenv CROSS_COMPILE arm-linux-
sed -e 's;export PATH;#export PATH;g' -e 's;export CROSS_COMPILE=;#export CROSS_COMPILE=;g' -e 's;test:;#test:;g' Makefile.platx -i
sed -e 's;echo zImage is ${ZIMAGE};#echo zImage is ${ZIMAGE};g' -e 's;${IMAGE}:: force;#${IMAGE}:: force;g' Makefile.platx -i
sed -e 's;@scripts/platx_config;#@scripts/platx_config;g' Makefile.platx -i
make oldconfig
make zImage
make modules
make modules_install

echo "Copying zImage"
cd ..
mkdir images
cd images
cp ../linux-2.6.14/arch/arm/boot/zImage ./
cd ..

echo "--------------------"
echo "Building Zydas driver"
cd zd1211-driver-r83
sed -e 's;MODPATH := /lib/modules/$(VERSION);MODPATH := ../linux-2.6.14/modules/lib/modules/2.6.14_r1.1;g' Makefile -i
sed -e 's;KERNEL_SOURCE=$(MODPATH)/source;KERNEL_SOURCE=$../linux-2.6.14;g' Makefile -i
sed -e "s;CC=gcc;CC=${CROSS_COMPILE}gcc;g" -e "s;CPP=g++;CPP=${CROSS_COMPILE}g++;g" -e "s;LD=ld;LD=${CROSS_COMPILE}ld;g"  Makefile -i
sed -e 's;$(MODPATH)/net;$(MODPATH)/kernel/drivers/net;g' Makefile -i
sed -e 's;depmod -a $(VERSION);depmod -F ../linux-2.6.14/ -b ../linux-2.6.14/modules -a 2.6.14_r1.1;g' Makefile -i
sed -e 's;gcc -o apdbg apdbg.c;$(CC) -o apdbg apdbg.c;g' Makefile -i
sed -e 's;cp ./apdbg /sbin/apdbg;#cp ./apdbg /sbin/apdbg;g' Makefile -i
sed -e 's;ZD1211REV_B=0;ZD1211REV_B=1;g' Makefile -i
make install
cd ..

echo "--------------------"
echo "Removing all old modules from JFFS2 Image"
rm -rf ./rootfs/lib/modules/*
echo "Copying new modules to JFFS2 Image"
cp -a  ./linux-2.6.14/modules/lib/modules/2.6.14_r1.1/ ./rootfs/lib/modules/
rm ./rootfs/lib/modules/2.6.14_r1.1/build
rm ./rootfs/lib/modules/2.6.14_r1.1/source
echo "Copying Zydas utilities to /sbin"
cp ./zd1211-driver-r83/apdbg ./rootfs/sbin
echo "Saving a copy of the .config to the filesystem"
rm ./rootfs/lib/modules/kernel.config
date > ./rootfs/lib/modules/kernel.config
cat ./linux-2.6.14/.config | grep -v # | sed '/^$/d' >> ./rootfs/lib/modules/kernel.config
if($PLATX_NOCONSOLE) echo "No Console patch 2 of 3 (inittab on fs)"
if($PLATX_NOCONSOLE) patch ./rootfs/etc/inittab ./noConsole-inittab.patch 

echo "Creating system image"
./SG2Release-1_0/buildTree/platx/util/mkfs.jffs2 --output=fs.jffs2 --root=./rootfs/ --pad=0x1DC0000 --eraseblock=0x20000
mv fs.jffs2 ./images

echo "--------------------"
echo "Building blob bootloader"
cd SG2Release-1_0/src
tar zxf blob-px2-10.tgz
cd blob-px2/src
if($PLATX_NOCONSOLE) echo "No Console patch 3 of 3 (patching blob)"
if($PLATX_NOCONSOLE) patch -p1 < ../../../../Blob_noconsole.patch 
cd blob
sed -e 's/blob_status.boot_delay = 10;/blob_status.boot_delay = 0;/g' main.c -i
patch -p1 < ../../../../../Blob_imote2_setGPIO10_outputHigh_forBT_and_SD.patch 
patch -p1 < ../../../../../Blob_imote2_setGPIO57_outputHigh_forLSB.patch
patch -p1 < ../../../../../Blob_sg2_32kHzOutputDisable.patch
cd ../../
make -f Makefile.cvs
make -f Makefile.cvs 
ln -s ../../../linux-2.6.14 linux
./configure --host=arm-linux --with-board=stargate2 \
    --with-linux-prefix=$PWD/linux \
    --enable-xlli --enable-network --enable-xmodem
cp src/blob/blob ../../../images/
cd ../../../

Build Everything

If you'd like to build all the varieties (Console/Windows Console/Linux NoConsole/Windows NoConsole/Linux), remove the setenv for the build flags, and use this script:

cd /projects/builds
rm -rf /projects/builds/buildDir
mkdir buildDir

cd /projects/builds/buildDir
mkdir noConsole_winGadget
cd noConsole_winGadget

cd /projects/builds/buildDir
mkdir noConsole_nixGadget
cd noConsole_nixGadget

cd /projects/builds/buildDir
mkdir Console_nixGadget
cd Console_nixGadget

cd /projects/builds/buildDir
mkdir Console_winGadget
cd Console_winGadget


Extracting all the Images

    Assuming you placed the platformX release, patches, and kernel in the same directory you could extract them all using the following commands: <bash>tar zxf linux-2.6.14.tar.gz tar zxf SG2Release-1_0.tgz tar zxf msb2_patches.tgz</bash>

Patch the kernel

    First we apply the SG2 release patches then we apply our MSB2 patches: <bash>cd linux-2.6.14 echo "Applying SG2 Patches" patch -p1 < ../SG2Release-1_0/src/patch-2.6.14-sg2-10 echo "Applying MSB2 Patches" patch -p1 < ../msp-linux-2.6.14-pxa-mmc.patch patch -p1 < ../msp-linux-2.6.14-uart.patch patch -p1 < ../msp-linux-2.6.14-sd-detect.patch</bash>

Configure the kernel

    At this point you can either use the normal SG2 configuration or apply the msb2 standard configuration. Be sure to add your toolchain to your path, if you've installed it in /usr/local/arm/3.4.3_binutils you could do something like this: <bash>export PATH=/usr/local/arm/3.4.3_binutils/bin/:$PATH export ARCH=arm export CROSS_COMPILE=arm-linux-</bash>

    SG2 Configuration

      The base SG2 configuration, by itself its typically not too useful. <bash>export ARCH=arm export CROSS_COMPILE=arm-linux- make stargate2_defconfig make oldconfig</bash>

    MSB2 Configuration

      The default MSB2 configuration, most builds will want to use this ontop of the SG2 base. <bash>export ARCH=arm export CROSS_COMPILE=arm-linux- cp ../msp-linux-2.6.14-config ./.config make oldconfig</bash>

    RNDIS (Windows XP) Ethernet Gadget Configuration

      If you'd like to be able to connect the iMote2 to a Windows XP host instead of a linux host you can use the RNDIS patch to add Windows XP support to the kernel. Download the patch from here to your build directory. Note, that this patch currently compiles support into the kernel and not as a module. <bash>export ARCH=arm export CROSS_COMPILE=arm-linux- cp ../msp-linux-2.6.14-config ./.config patch -p1 < ../msp-linux-2.6.14-winXP-rndis.patch make oldconfig</bash> Next you will need to do a make menuconfig (after setting up the ARCH/CROSS_COMPILE/path) and select:
      • Device Drivers
        • USB Support
          • USB GadgetSupport
            • Support for USB Gadgets (compile into the kernel)
            • USB Gadget Drivers (compile into the kernel)
            • Make sure 'Ethernet Gadget (with CDC Ethernet Support)' is selected
            • Select 'RNDIS support (EXPERIMENTAL)'
      Then exit out and save your kernel configuration.

    Configuring the kernel to use multiple Internet connections

      In order for the iMote2 to selectively use multiple Internet connections simultaneously, you must enable "policy routing" in the kernel: <bash>make menuconfig</bash> Select the following:
      • Networking
        • Networking options
          • IP: Advanced router
          • IP: Policy routing (will not appear unless "Advanced router" is set)
      You can also use the following patch here.

Compile the kernel

    You can then build the kernel as you normally would or perform any additional steps you want to before building. Note that if you are using the Mainstone tools instead of a 3.4.1 toolchain installed in /usr/local/arm/3.4.1 you will need to edit Makefile.platx and comment out the export lines at the top. <bash>...
    1. export ARCH=arm
    2. export CROSS_COMPILE=/usr/local/arm/3.4.1/bin/arm-linux-
    3. export PATH:=${PATH}:/usr/local/arm/3.4.1/bin/
    ... </bash> You can also remove the platx_config to get rid of an annoying error message in the SG2_1.0 release: <bash>${IMAGE}:: force @scripts/platx_config</bash> Now you're ready to build the kernel: <bash>mkdir ../kernel make zImage make modules make modules_install cp arch/arm/boot/zImage ../kernel/ cp -a modules/lib/modules/2.6.14_r1.1/ ../kernel/ </bash> Note you should remove the '../kernel' directory each time you do this to avoid getting a stale copy; however, I'm not about to place rm -rf commands in things people will paste arbitrarily

Building the zd1211(b) wireless driver

    While the newest versions of Linux support the zd1211(b) out-of-the-box, the kernel used on the iMote2 does not. Therefore, you must download and compile the driver separately:
    • Obtain and extract the latest version from [1]. As of the time of this edit, this was r83. You can do this in one step with: <bash>wget -O - | tar xvzf -</bash>
    • cd to the newly-created directory.
    • Edit the Makefile, and change the MODPATH (on line 13) to point at your modules/lib/modules/2.6.14_r1.1/ directory.
    • For Rev B cards you need to change line 22 to ZD1211REV_B=1
    • Compile and install:
    <bash>make make install</bash>

Putting it all together

    In order to combine the various steps together to create a ready to use kernel images/modules you need to complete the previous steps, copy the kernel image to someplace convenient, and copy the kernel images to the filesystem. See the script at the bottom of this page for instructions on installing the kernel modules and building the bootloader.

Flashing the kernel

    You will need to specify the platform (SG2/Intel Mote2) and JTAG cable that you are using (Intel(R) JTAG Cable/JTAG CPU) to XFlash. The following assumes you are programming an Intel Mote2 with a Macraigor Raven JTAG:
    xflash -p intelmote2 -tt "JTAG CPU" blob     -offset 0x00000000
    xflash -p intelmote2 -tt "JTAG CPU" zImage   -offset 0x00040000
    xflash -p intelmote2 -tt "JTAG CPU" fs.jffs2 -offset 0x00240000

    And the following assumes you are programming an Intel Mote2 with an Intel JTAG

    xflash -p intelmote2 -tt "Intel(R) JTAG Cable" blob     -offset 0x00000000
    xflash -p intelmote2 -tt "Intel(R) JTAG Cable" zImage   -offset 0x00040000
    xflash -p intelmote2 -tt "Intel(R) JTAG Cable" fs.jffs2 -offset 0x00240000