Hacking Roku

Roku HD1000 is a settopbox like device manufactured by rokulabs. It runs a Linux OS called Roku OS and is maintained by the manufacturer. All code needed to develop for this device is available on the developers site in the form of an SDK. There is even a contest being held to produce Roku compatible software.

The VLC Media player is going to be ported to the Roku HD1000, which enables the device to function as a full fledge video client. The VLC feature page can be found here. On this page the first version of the port will be available and also progress will be visible here, so don't be a stranger ;-)

 

HOWTO Hacking Roku HD1000

In this HOWTO all steps needed for setting up a cross-development environment for the HD1000 are written down. It is a step by step tutorial. Start reading here.

Disclaimer: The author of this howto is not responsible for damage inflicted to your HD1000 software or hardware.

Author: Jean-Paul Saman, 21 May 2004.

Copyright @ 2004, Jean-Paul Saman

Revision: 1.5

Step 1: Cross-compiler

Download a cross-compiler from:

All devices need a compiler for creating applications. Here is a toolchain for building Roku compatible software. You also need the development environment from Roku to link against the right headers and libraries.

Cross compiler toolchain (built by Jon Lech Johansen) which uses glibc 2.2.4: rokutools-20040423-1.src.rpm. Use the following command as root to rebuild the compiler on your development machine: rpmbuild --rebuild rokutools-20040423-1.src.rpm. After the compilation is finished you end up with two RPM's rokutools-20020423-1.i386.rpm and rokutools-mipsel-20020423-1.i386.rpm.

If you build them as root then the binary RPM's rokutools-20040423-1.i386.rpm and rokutools-mipsel-20020423-1.i386.rpm will be created in the directory /usr/src/redhat/RPMS/i386 and the source RPM rokutools-20040423-1.src.rpm in the directory /usr/src/redhat/SRPMS.

Install these RPM's with root priviliges on your development machine with:

$ rpm -ivh --nodeps rokutools-20020423-1.i386.rpm rokutools-mipsel-20020423-1.i386.rpm

Step 2: Download development SDK

Download from roku the development SDK (http://www.rokulabs.com) and write the roku cross development environment to a Compact Flash card of at least 64 MB in size. I prefer a 128 MB of Apacer or SanDisk.

The following did not work:

  • Compact Flash cards from PQI don't work the HD1000 freezes when detecting this card.
  • Don't use a USB key, because it also hangs the HD1000.
  • Step 3: Determine IP address

    Connect a network cable to the HD1000 and lookup the ip address on the setup screen once booted.

    Step 4: Mount SDK on the HD1000

    Insert the compact flash card into the HD1000 and use the menu to run MountSDK. Now the development environment is booted under /usr/share/rokudev.

    Step 5: Custom cross-development environment

    Now we are going to take a snapshot of the environment. This snapshot will be used in our cross-compile environment. Follow the instructions below:

    1. Telnet to your Roku over ethernet, eg:

    $ telnet 192.168.0.102
    roku@(none) user: guest

    2. Become the root user:

    $ su root
    $ cd /

    3. Now tar the environment and write it to Compact Flash. The following command does that in one go.

    $ busybox tar -c /lib /usr/lib /usr/include /usr/libexec /usr/local/include /usr/local/lib /usr/local/libexec > /mnt/flash1/roku.tar

    4. Once finished unmount the development environment (or type sync to flush all disk buffers). We do not want to miss some bytes in our tar archive.

    $ umount /usr/share/rokudev
    $ /sbin/losetup -d /dev/loop/0
    $ umount /mnt/flash1

    5. Log out of the telnet session because it is not needed now:

    $ exit
    $ exit

    Step 6: Shutdown HD1000

    Turn of the power on the HD1000 and remove the compact flash card. Now all the directories needed for cross-compiling are in our development environment. The next step is to construct the cross-development environment with this snapshot.

    Step 7: Cross-development environment

    To construct our cross-development environment the Roku HD1000 SDK and the tar-file you created in previous steps are needed.The following steps are done on your development machine which you want to use for developing HD1000 compatible software. Follow the next instructions:

    1. Create a directory for instance in your normal homedirectory where the tarfile will be extracted:

    $ mkdir -p ${HOME}/src/rokudev
    $ cd ${HOME}/src/rokudev

    2. Extract the tarfile:

    $ tar -xvf /mnt/flash/roku.tar

    3. Add a missing mount directory:

    $ mkdir -p ${HOME}/src/rokudev/usr/share/rokudev

    4. Mount the development SDK using ${HOME}/src/rokudev as base directory, or use this bash script:

    $ losetup /dev/loop0 ${HOME}/download/roku/SDK/rokudev.cramfs
    $ mount -t auto /dev/loop0 ${HOME}/src/rokudev/usr/share/rokudev

    To cross-compile use the following prefix ${HOME}/src/rokudev/usr on the configure line (needed by GNU autotools). It is necessary to add additional include and library paths to use. The host part tells the configure script to use the cross-compiler mode. Beware some versions of autoconf (configure) use the --target= instead of --host.


    CFLAGS="-I${HOME}/src/rokudev/usr/local/include \
    -I${HOME}/src/rokudev/usr/share/rokudev/usr/include" \
    LDFLAGS="-L${HOME}/src/rokudev/lib \
    -L${HOME}/src/rokudev/usr/local/lib " \
    ./configure --prefix=${HOME}/src/rokudev/usr --host=mipsel

    An example application the Cascade public API can be linked in the following way:

    $ source ${HOME}/mipsel-cross.env
    $ mipsel-linux-gcc -I${HOME}/src/rokudev/usr/local/include -I${HOME}/src/rokudev/usr/share/rokudev/usr/include \
    test.cpp -o test.roku -L${HOME}/src/rokudev/lib \
    -L${HOME}/src/rokudev/usr/local/lib -Wl,-rpath-link -Wl,-L${HOME}/src/rokudev/usr/local/lib -lCascade -lmad -ldvbpsi \

    To further optimize the size of the resulting binary you could strip it. Do not do this when you want to use the debugger on the HD1000, because stripping means removing all hints and symbolnames. It also remove the information a debugger relies upon. Also stripping shared libraries is not advisable, because the library loader will not have any hints left to load it into memory and hook it into your application that needs them. An example to use strip:

    $ mipsel-linux-strip -s test.roku

    Here are some shell scripts that aid in setting up the development environment.

    • roku-mount-sdk.sh - Mount the SDK environment in your cross-development tree.
    • roku-umount-sdk.sh - Unmount the SDK environment from your cross-development tree.
    • mipsel-cross.env - Source this inside your shell or use it as `cat mipsel-cross.env` ./configure --prefix=${HOME}/src/rokudev --host=mipsel-linux .... for the GNU autotools.

    Step 8: Testing

    Testing your cross-compiled binary on a Roku means copying or installing the binary in a place where Roku OS can launch it. There are several possiblitities you can use for instance a SMB or NFS share and your Compact Flash card. The following instructions deal with the last posibility only. Mounting the SMB share is a standard feature of the HD1000 and is already described in the HD1000 documentation.

    1. For testing purposes having a large Compact Flash card (greater then or equal to 128 MB) is adviceable. The HD1000 has very little memory left to run additional applications. There for I describe here howto create a swap file of 64 MB. The other 64 MB is used to install the application you want to test and writting logfiles to from a test run.

    Insert the compact flash card into the HD1000. The Roku OS will mount it read-only under /mnt/flash1 when it is the only device plugged in. Now it has to be mounted read-write. Here is how you do that as the root user:


    $ umount /mnt/flash1
    $ mount -t vfat -o rw /dev/ide/host0/bus0/target0/lun0/part1 /mnt/flash1

    2. Before running your application we must make sure there is enough memory left to run it. Other applications already occupy quite a large amount of the available RAM. Having a swapfile will make it possible to use a little more memory or too load a larger application. Here is how a swap file can be created onto the compact flash card inserted above:

    Create the swapfile from scratch:

    $ dd if=/dev/zere of=/mnt/flash1/swap
    $ /sbin/mkswap /mnt/flash1/swap

    Make the swap file active

    $ /sbin/swapoff /mnt/flash1/swap

    3. Test your application now and collect all the data you need to debug it. In this example all logging can be written to the compact flash disk which you mounted read-write as described above.

    $ /mnt/flash1/myapp.roku -vvv > /mnt/flash1/testrun1.log

    4. The final and last step in a testing run when using this compact flash card approach is to get your data of the HD1000 and insert it into your development machine for analysis. This involves turning of the swapfile and unmounting the compact flash card like this:

    $ cd ${HOME}
    $ /sbin/swapoff /mnt/flash1/swap
    $ umount /mnt/flash1

    Now the compact flash card can be removed safely without fear of either crashing the HD1000 Roku OS or losing gathered logfiles/data.