
PhoneME, a JavaVM for the Fonera FON Router
OpenWRT is a Linux distribution optimized especially for embedded devices and also builds the starting point for many popular RouterOS distributions, like DD-WRT, FreeWRT, or X-Wrt. Wikipedia has details on all those project, a good starting point would be here.
Since OpenWrt is optimized for embedded systems, it doesn't come as a surprise that features like a read-only Flash memory filesystem (SquashFS) and a read/write Flash memory filesystem (JFFS2), or BusyBox, which combines many common UNIX utilities into a single executable, are readily available to be configured into a custom image. OpenWrt also comes with a lightweight package management system (IPKG or more recently OPKG), meaning that features that have not already been built into the kernel, can be added later, at runtime.
A Java-Runtime Environment would be one of those features that are not built-in but would be nice to have for some of us. So let's take a look at how a JavaVM could be build, packaged, and deployed into an embedded system that has the OpenWrt firmware.
Since OpenWrt is optimized for embedded systems, it doesn't come as a surprise that features like a read-only Flash memory filesystem (SquashFS) and a read/write Flash memory filesystem (JFFS2), or BusyBox, which combines many common UNIX utilities into a single executable, are readily available to be configured into a custom image. OpenWrt also comes with a lightweight package management system (IPKG or more recently OPKG), meaning that features that have not already been built into the kernel, can be added later, at runtime.
A Java-Runtime Environment would be one of those features that are not built-in but would be nice to have for some of us. So let's take a look at how a JavaVM could be build, packaged, and deployed into an embedded system that has the OpenWrt firmware.
Just like JavaSE gets build and packaged for a particular host OS, a JavaVM for an embedded system needs to be build with a particular hardware platform in mind. A JavaVM calls directly into the Linux kernel, which means, not only do we need all the kernel related resources when building the JavaVM, we also need to choose a hardware platform.
The OpenWrt sources are easily available at https://svn.openwrt.org/openwrt/trunk/ and for the hardware platform, I have picked the Fonera FON, a relatively simple and inexpensive router, built on the AR531x/231x Atheros WiSoC (Wireless System-on-a-Chip), with an integrated 32-bit MIPS R4000-class processor running at 183.5 MHz. It features 8 MBytes of Flash ROM and 16 MBytes of RAM. Check here fore more details.
With the hardware platform selected and the OpenWrt source downloaded, we can start building. To add a little excitement, I decide to try the build process on a Mac, using OS X 10.5.
To find out what tools are needed, open a Terminal, cd into the OpenWrt trunk folder and run
After installing binutils, patch, bzip2, flex, bison, gettext, ... with the help of Fink Commander, we're ready to configure the build process by running
The result may come as a surprise, but the kernel configuration is done with the help of a character based UI.
The most important thing to get right here is to pick the correct Target System. For the Fonera FON, this would be Atheros 231x/5312 [2.6]. Moreover, to be able to build a JavaVM later, building the OpenWrt SDK needs to be enable here.
After a subsequent default build (entering
(If the build process fails, running
Running make in the linux-mips-openwrt folder will produce theses files:
The J2ME_CLASSLIB argument provided to Make, defines what class library will eventually be created:
Insert this makefile into the cdc folder and also create a files folder.
Eventually, the content layout needs to look like this:
Running
creates the deployable package, containing the JavaVM and a set of test classes, here:
Like declared in the makefile that was responsible for creating the ipk package, the only non-standard OpenWrt package required by PhoneME Advanced is libpthread. Running OpenWrt's
After ssh- into the FON, running
Now executing the test is as simple as
The OpenWrt sources are easily available at https://svn.openwrt.org/openwrt/trunk/ and for the hardware platform, I have picked the Fonera FON, a relatively simple and inexpensive router, built on the AR531x/231x Atheros WiSoC (Wireless System-on-a-Chip), with an integrated 32-bit MIPS R4000-class processor running at 183.5 MHz. It features 8 MBytes of Flash ROM and 16 MBytes of RAM. Check here fore more details.
With the hardware platform selected and the OpenWrt source downloaded, we can start building. To add a little excitement, I decide to try the build process on a Mac, using OS X 10.5.
Fonera FON related posts at wolfpaulus.com
- La Fonera Hacking
Does the FON have all the attributes required to be added to the digital playground? - La Fonera (FON2100) Hardware Details
A detailed look at the La Fonera (FON 2100) hardware. - La Fonera 2.0 FON 2100a/b/c
RedBoot details and booting into OpenWrt 8.09.1 Kamikaze - La Fonera 2.0 (FON2202) Hardware Details
A detailed look at the La Fonera 2.0 hardware. - La Fonera 2.0 Preview
Putting the original (or newer) firmware back on a Fonera FON 2.0, and some 2.0 screen shots. - La Fonera 2.0 (FON2202) Hacking, Cleaning House
Preparing the FON 2202 for reflashing with OpenWrt or DD-WRT - OpenWrt, Post Kernel System Initialization
A closer look at what happens when OpenWrt boots on the Fonera FON Router. - PhoneME, a JavaVM for the Fonera FON Router
A closer look at how a JavaVM could be built, packaged, and deployed into an embedded system, running the OpenWrt firmware.
Fink or MacPorts
The OpenWrt build process requires that several GNU tools are installed on machine that will eventually perform the build process and while some of these tools seem to be available on OS X, they aren't parameter compatible with the GNU version, i.e. either Fink or MacPorts is needed to get the GNU tools working.To find out what tools are needed, open a Terminal, cd into the OpenWrt trunk folder and run
make help.After installing binutils, patch, bzip2, flex, bison, gettext, ... with the help of Fink Commander, we're ready to configure the build process by running
make menuconfigThe result may come as a surprise, but the kernel configuration is done with the help of a character based UI.
The most important thing to get right here is to pick the correct Target System. For the Fonera FON, this would be Atheros 231x/5312 [2.6]. Moreover, to be able to build a JavaVM later, building the OpenWrt SDK needs to be enable here.
After a subsequent default build (entering
make without any arguments) has been successfully completed, the sdk can be found here: Kamikaze/trunk/build_dir/mips/OpenWrt-SDK-atheros-for-Darwin-i386(If the build process fails, running
make V=99 is revealing what went wrong. In my case it was a missing library. After installing it - again with the help of Fink Commander - the error message went away.)
Java
A good starting point for Java in embedded world can be found here and one actually does have a choice, when is comes to Java Virtual Machines for OpenWrt Embedded Linux.- JamVM
JamVM is a new Java Virtual Machine which conforms to the JVM specification version 2 (blue book). In comparison to most other VM's, it is extremely small, but requires the building of the GNU Classpath. Clearly the full version of Classpath isn't going to fit onto a small router, contains some native code and need to be cross-compiled. - SableVM and SableVM Mini
SableVM is a Java Bytecode Interpreter implementing Java virtual machine (JVM) specification, second edition. Its goals are to be reasonably small, fast, and efficient, as well as providing a well-designed and robust platform. - PhoneME
The PhoneME project was created after opensourcing Sun implementation of Java ME. It comes in two versions: PhoneME feature software (CLDC), for mobile phones and PhoneME advanced software (CDC), for higherend devices. Reference implementations are available for x86, ARM and MIPS.
PhoneME
Next step is to checkout the phoneme sources form: https://phoneme.dev.java.net/svn/phoneme/components (you may have to create an user account at the java.net site before being able to access the source repository). We need cdc's trunk and tools' trunk on the same level and then edit thecdc/trunk/build/linux-mips-openwrt/GNUmakefile, setting the CVM_TARGET_TOOLS_PREFIX to point to the toolchain location in the OpenWrt-SDK, like so:
CVM_TARGET_TOOLS_PREFIX ?= /Users/wolf/Work/Embedded/Kamikaze/trunk/build_dir/mips/OpenWrt-SDK-atheros-for-Darwin-i386/staging_dir/toolchain-mips_gcc4.1.2/bin/mips-linux-uclibc-Running make in the linux-mips-openwrt folder will produce theses files:
- linux-mips-openwrt/btclasses.zip
- linux-mips-openwrt/testclasses.zip
- linux-mips-openwrt/democlasses.jar
- linux-mips-openwrt/bin/cvm
- linux-mips-openwrt/lib/cdc.jar (or linux-mips-openwrt/lib/foundation.jar)
The J2ME_CLASSLIB argument provided to Make, defines what class library will eventually be created:
- cdc - (default) will create a limited class library (cdc.jar 884 KBytes) that is meant for testing purposes only.
- foundation - creates the full Foundation Profile class library (foundation.jar 1.475 KBytes).
Creating the ipkg Package
These files now have to be distributed into a manually created folder that needs to look exactly like this: Start by creating a cdc folder in the OpenWrt-SDK package location like here:/Users/wolf/Work/Embedded/Kamikaze/trunk/build_dir/mips/OpenWrt-SDK-atheros-for-Darwin-i386/package/cdcInsert this makefile into the cdc folder and also create a files folder.
Eventually, the content layout needs to look like this:
Running
make in the SDK folder here: /Users/wolf/Work/Embedded/Kamikaze/trunk/build_dir/mips/OpenWrt-SDK-atheros-for-Darwin-i386creates the deployable package, containing the JavaVM and a set of test classes, here:
/Users/wolf/Work/Embedded/Kamikaze/trunk/build_dir/mips/OpenWrt-SDK-atheros-for-Darwin-i386/bin/packages/mips/pmea-wp_1_1-2_mips.ipkLike declared in the makefile that was responsible for creating the ipk package, the only non-standard OpenWrt package required by PhoneME Advanced is libpthread. Running OpenWrt's
make menuconfig again, now shows Java in the Languages menu and if Java gets selected, libpthread (to be found in Base System) is automatically added.
Deployment and Test
With the package built, all what's left to do is deploying it and running the test suite. Deploying the ipkg file is as easy is putting it into the target's tmp folder (running sftp on the FON and Fugu on the development host, makes this easy and fast).After ssh- into the FON, running
ipkg install /tmp/pmea-wp_1_1-2_mips.ipk or opkg install /tmp/pmea-wp_1_1-2_mips.ipk will install the JavaVM as well as the test classes.Now executing the test is as simple as
/usr/java/bin/cvm -cp /usr/java/testclasses.zip Test