by Bill Courington and Gary Collins
Published August 2012
How to get Linux and Java SE Embedded running on the Raspberry Pi in less than an hour
It is hardly larger than a credit card. It costs about the same as a book on Java programming.
It's the Raspberry Pi computer, and it can support a full Java SE runtime for headless embedded applications. This article gets you started with Java on the Raspberry Pi programming with these topics:
NOTE: There are many potential variations of the instructions given here, especially which operations you execute on a host (desktop or laptop) computer, and which you execute on the Raspberry Pi. Use your knowledge and preferences (and perhaps some of the topics in the Optional Linux Tuning and Tweaking section) to create a workflow that works for you.
The Raspberry Pi is a small, low-power board built around a 700mHz ARMv6 CPU with hardware floating point and graphics processor integrated in a single chip. The graphics processor and the CPU share 256MB of RAM. There are connections for USB, Ethernet, high-definition graphics, audio, an SD card, and general-purpose I/O. Figure 1 shows a Raspberry Pi model B with an SD card inserted for scale. The SD card plays a special role: The Raspberry Pi boots from it. This article largely consists of instructions for creating and modifying files on a bootable SD card.
Figure 1. Raspberry Pi Model B
You can interact with the Raspberry Pi with a USB keyboard and mouse and an HDMI monitor or television (up to 1080p). The board’s Ethernet connection gives another option: interacting from a networked host via
ssh. The Optional Linux Tuning and Tweaking section of this article describes how to enable
To set up the Raspberry Pi model B to run Java SE Embedded, you need the following:
$ sudo apt-get install gparted
When power is applied, the Raspberry Pi firmware boots from the SD card slot. Java SE Embedded runs on Linux, therefore your first task is to get Linux on an SD card.
NOTE: These instructions are for Debian Squeeze. Other Linux implementations for the Raspberry Pi might work, but they must have been built for the ARM chip's software floating point. Images linked from the Raspberry Pi website might have been built for hardware floating point; they will not work with Java SE for Embedded.
You can find a link to a zipped Debian Squeeze image for the Raspberry Pi here: http://elinux.org/RPi_Distributions#Debian_ARM. The file size is about 450MB. The following instructions assume that you have downloaded to a new directory
~/RaspberryPi/. To verify the downloaded file, follow the SHA-1 Checksum instructions on the page that is displayed when the download starts.
Unzip the image as follows:
$ cd ~/RaspberryPi $ unzip *.zip
Unzipping creates a subdirectory called something like
On your host computer, discover the SD card device handle as follows (use a different way if you prefer):
dmesg | tailwhich shows messages associated with device mounts. Only the final messages are of interest.
dmesg | tailagain. The additional lines (compared to the first window) relate to the newly mounted SD card. They will vary in detail, but should look something like this:
[ 110.084625] sdb: detected capacity change from 0 to 3963617280
[ 118.055249] sd 2:0:0:0: [sdb] 7741440 512-byte logical blocks: (3.96 GB/3.69 GiB)
[ 118.059409] sd 2:0:0:0: [sdb] Assuming drive cache: write through
[ 118.064547] sd 2:0:0:0: [sdb] Assuming drive cache: write through
[ 118.066015] sdb: sdb1
sdb, meaning that the device handle is
sdb1refers to the example card’s single partition. Your card might have multiple partitions.
In the following instructions, we assume that the SD card device handle is
/dev/sdb and that it has a single partition
sdb1. Adjust the instructions if necessary for your environment.
$ sudo umount /dev/sdb1
of(output file) argument value correctly. You are about to invoke a low-level disk copy that overwrites all data. Specifying the wrong device will destroy data.
$ cd ~/RaspberryPi/debian6-19-04-2012
$ sudo dd if=yourDebian.img of=/dev/sdb bs=1M
1859+1 records in
1859+1 records out
1950000000 bytes (2.0 GB) copied, 212.344 s, 9.2MB/s
dd-ing to an SD card is a slow operation. It can take 5-10 minutes for a 4GB class 4 card.
ddgives no indication of progress, so be patient while it slowly does its work.
The SD card now contains three partitions and unallocated space. Now we'll add the unallocated space to the Linux file system to make more room for Java SE Embedded and applications. To assign unallocated space to the file system, we modify the partitions on the SD card, deleting and recreating one of the partitions, and resizing another.
$ sudo gparted
Figure 2. Initial SD Card Partitions
The three partitions are:
/dev/sdb1: Boot partition
/dev/sdb2: Linux root file system. Most of its 1.5GB allocation is already used.
/dev/sdb3: Linux swap area.
About half the card’s space is unallocated. The biggest chunk of free space follows the
/dev/sdb3 partition. To add this space to
/dev/sdb2 (the file system), we temporarily delete
/dev/sdb2, then re-create
/dev/sdb3(linux-swap), right click and choose Delete. The partition is shown as deleted, but GParted has queued the operation and will run it later.
Figure 3. SD Card Partitions after Queuing Delete
/dev/sdb2, which is the Linux file system, right click, and choose Resize/Move. In the dialog box that appears, drag the right arrow until “Free space following” is about 512 (or however much you want to leave for swap). You might not be able to drag to exactly 512, but the exact size is not important.
Figure 4. 512MB for Swap
Figure 5. New Swap Partition
Figure 6. New Partition Map
Note: For these steps, you must have these components connected to the Raspberry Pi: a monitor, a keyboard, and a known-to-work Ethernet cable.
$ sudo /etc/rc.local
sshlogins with this command:
$ sudo update-rc.d -f ssh defaults 20
$ sudo sync; sudo shutdown -r now
Now we can read and write the Raspberry Pi SD card over the network from the host computer.
In this section we use the host to download Java SE Embedded and copy it over the network to the Raspberry Pi’s Linux file system. Then, still working remotely, we unpack the download and launch Java.
Figure 7. First Download Link
Figure 8. Second Download Link
.gzfile to your
$ ssh pi@RaspberryIP mkdir /home/pi/java
$ scp ~/Downloads/*.gz pi@RaspberryIP:/home/pi/java
$ ssh pi@RaspberryIP
$ cd /home/pi/java
$ tar -zxvf *.gz
$ ls ejre*
$ cd ejre*
$ ./bin/java -version
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment for Embedded (build 1.7.0_04-ea-b20, headless)
Java Hotspot(TM) Embedded Client VM (build 23.0-b21, mixed mode)
$ rm /home/pi/java/*.gz
The commands in this section can make your Raspberry Pi system run more reliably, more responsively, or more conveniently. Choose those you like and run them on the Raspberry Pi. To simplify diagnosing problems, reboot after each change you make.
In this section:
If your network re-uses dynamic IP addresses, you can skip changing to a static IP because the Raspberry Pi’s IP address will effectively be constant. If the Raspberry Pi’s dynamic IP address is likely to differ each time it is booted, a static IP address is more convenient for
ssh-ing. In the following instructions, we assume that you want to assign the hostname
raspberrypi to the Raspberry Pi.
Begin by opening
/etc/hosts as superuser in a text editor (for example,
sudo vi /etc/hosts). Add a line for the Raspberry Pi consisting of a static IP address that is valid in your network, an optional domain name, and aliases. Here is a hypothetical example, in which we designate the Raspberry Pi as
127.0.0.1 localhost 192.168.0.100 raspberrypi.yourDomain raspberrypi loghost
Save the file and exit the editor.
As superuser, open
/etc/hostname in a text editor. Add a line analogous to this:
Save the file and exit the editor.
The following instructions can prevent a problem in which an overloaded network causes the operating system to change the Raspberry Pi's static IP address. As a result,
ssh or other operations that use the static IP address stop working.
Discover the Ethernet port’s hardware address as follows.
First, determine the name of the Ethernet controller (
x's stand for address digits):
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1488 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether b8:27:eb:b5:e8:90 brd ff:ff:ff:ff:ff:ff inet xx.xxx.xxx.xx/xx brd xx.xxx.xxx.xxx scope global eth0In this example, it’s
eth0. The hardware address is the hex digits following
link/ether, in this example,
Now that you have the Ethernet controller’s hardware address, as superuser, open
/etc/network/interfaces in a text editor and add lines analogous (substitute your network details) to those following the
# New entries comment shown below.
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or # /usr/share/doc/ifupdown/examples for more information. auto lo iface lo inet loopback # # New entries to support static IP follow: auto eth0 iface eth0 inet static hwaddress ether b8:27:eb:b5:e8:90 address 192.168.0.100 network 192.168.0.0 netmask 255.255.255.0 broadcast 192.168.0.255 gateway 192.168.0.1
By default, swapping is disabled in Debian Linux. If an operation exceeds the Raspberry Pi’s 256KB RAM size, the system crashes. Less serious, by default, the file system spends time maintaining a last-accessed time for each file, which is of little use in embedded applications. Maintaining last-accessed times can also reduce the life of an SD card. Both default behaviors are specified in the
As superuser, open
/etc/fstab in an editor such as
vi. The file looks like this:
proc /proc proc defaults 0 0 /dev/mmcblk0p1 /boot vfat defaults 0 0 #/dev/mmcblk0p3 none swap sw 0 0
To enable swapping, uncomment the third line.
NOTE: Swapping is slow on an SD card. For an embedded application, you probably want to manage memory so as to avoid it.
To eliminate the last-accessed overhead, insert a
p2 mount point between
nodiratime options do the job. When the file looks like this, save it and exit the editor:
proc /proc proc defaults 0 0 /dev/mmcblk0p1 /boot vfat defaults 0 0 /dev/mmcblk0p2 / auto rw,noatime,nodiratime,errors=remount-ro 0 1 /dev/mmcblk0p3 none swap sw 0 0
p3 (the swap partition we created on the host as
/dev/sdb3) to swap space:
$ sudo mkswap /dev/mmcblk0p3
By default, the Raspberry Pi is configured for the Europe/London time zone and the en_GB_UTF-8 locale. To localize your computer, follow these instructions.
To change the time zone, enter this command:
$ sudo dpkg-reconfigure tzdataA pseudo graphic interface appears.
Figure 9. Time Zone User Interface
Move the selection cursor through regions and cities with the up-down arrow keys. Use the left-right arrow keys to select <Ok> or <Cancel>. Press Return to enter a selection.
Set the locale as follows:
$ sudo dpkg-reconfigure -p low locales
The user interface is similar to that for setting the time zone.
Many operations, including software package updates, rely on a correct date and time. To set the date and time automatically, learn the identity of a network time server, then run this command:
$ sudo ntpdate yourNTPServerTo set the time on each boot, as superuser, edit
/etc/rc.local, adding this line before the script exits:
Ping a well-known Internet host, such as
www.lego.com. If the host does not respond, find out if your network is behind a proxy and If necessary, set the environment variable
http_proxy according to your network conventions, for example (hypothetical):
$ sudo export http_proxy =’http:192.168.0.1:3128’
To set the proxy each time you login, add the export command to
~/.bash_profile, or equivalent if you use a different shell.
If keyboard keys are being misinterpreted, or you want to change the keyboard layout, use this command:
$ sudo dpkg-reconfigure keyboard-configuration
The user interface is similar to that described in the Set Time Zone and Locale section of this article.
Before updating the packages distributed with Debian, as superuser, open
/etc/apt/sources.list in a text editor. This file contains the repository locations of new/updated packages. As distributed, the locations have ftp.uk in their URLs. If you are not located in the United Kingdom, you can improve performance by changing the entries to a location physically closer to you. For example, you can globally change ftp.uk to ftp.us if you are in the United States. This site has information about Debian repository locations: http://ftp.debian.org/debian/README.mirrors.html.
To update your installed packages, after verifying that the Raspberry Pi has an Internet connection, enter these commands:
$ sudo apt-get update $ sudo apt-get upgrade
If you get a message that there are duplicates in the package list, open
/etc/apt/sources.list again in an editor and comment out one of the duplicate entries. The entry containing more information is usually the best one to keep.
If you want the window system to start automatically when you login locally to the Raspberry Pi, change the default runlevel as follows. As superuser, open
/etc/inittab in a text editor. Find this entry:
# The default runlevel. id:2:initdefault:Change it to 5:
# The default runlevel. id:5:initdefault:NOTE: Graphics consumes a large chunk of the Raspberry Pi’s RAM, on the order of 90MB.
If you experience difficulties with the default midori browser, try iceweasel:
$ sudo apt-get update $ sudo apt-get install iceweasel
Raspberry Pi sound output does not work by default. To enable it, as superuser, open
/etc/modules in a text editor. Add this line to the end of the file:
Save and close the file. Sound is enabled when you reboot the Raspberry Pi.