RetroArch on ODROID-U2 (with hardware acceleration, yes!)


I have tried to run decent console emulation on Raspberry Pi, without success.

So I recently got my hands on an ODROID-U2 (that comes with a respectable more powerful hardware) and that can potentially carry out my console emulation and preservation dreams.

In the below pictures you can see it shily coming out of the box:

A small package to rule them all

Better use a fan if you want to overclock this little beast!

This development board comes with 4 ARM Cortex A9 CPUs and the Mali 400 GPU (more about this later); when choosing a development board you should really pay attention to the planned shelf life, the expected community size and the GPU driver support. There's really nothing else that will matter more for you than the open source/closed source drivers.

In these regards the vendor, Hardkernel, gets my kudos as I see they are working hard to deliver the best to the community that's aggregating around ODROID (but keep in mind that it's not yet very big right now, so weaponize yourself for all cases!).

As far as I understood the driver is partly closed-source, for longer term dreams (full open source Mali400 driver) you could check out the Lima project, although nothing usable is available at time of writing.

I was expecting some geeky adventures to achieve my goal, and I wasn't disappointed. In the last few days I had to learn all my way through forums, IRC, blog posts and generally fragmented and incomplete information - but finally after a few strong machete cuts I have been able to see the light!


I didn't want to release the result of my efforts as Debian packages or complete SD images (update: I did!), so I will provide you with a walkthrough and the necessary steps.
The reasons are:
  • possible licensing concerns, it is not fully clear to me if I am entitled to release these (for example the vendor-provided drivers);
  • releasing concerns, once you release something you should take care to mantain it;
  • philosophy: if you are using a development board you should really get in touch with all the layers to better understand how things work.

I used this blog post as starting point and also other resources here and there; in this blog post I am focusing only on SD card booting and ODROID-U2 specifically.
Although I didn't follow it originally, you might also want to read the official post about ODROID-U2 and then come back for the other steps about Xorg configuration and RetroArch.

Update 7 May 2013: I released neagix' excellent (and unofficial) Debian Wheezy for Development&Emulation (with X11 hardware acceleration). I advise to use the image as information in this post might be obsolete.


In the following steps I aim to provide an aid at getting a fully functional RetroArch on ODROID-U2.

If you can use debian apt-get/aptitude and SSH you should be able to follow it. Also you might want to use Google in case of some strange error that is not covered by this tutorial.

This is not a from-scratch tutorial for complete newbies, so please don't expect so.

Update 25-April-2013: the more advanced cores will not exhibit a great performance, but you should be fine with emulation of 16bit (and less) consoles

Step 1 - booting the device

Insert the microSD in a Linux PC, then check with dmesg|tail what is the dev node. On my PC it was /dev/mmcblk0. Please take note of the root device, not the partition device (that would be /dev/mmcblk0p1 and so on).

Now download a prepared ODROID-U2 Ubuntu image and flash it to the microSD card.

wget http://www.mdrjr.net/odroid/mirror/ODROID-U2/Ubuntu/odroidu2_20121231-linaro-ubuntu-desktop-uSD.zip
7z x odroidu2_20121231-linaro-ubuntu-desktop-uSD.zip
sudo dd if=odroidu2_20121231-linaro-ubuntu-desktop-uSD.img of=/dev/mmcblk0 bs=24M

Update 14 July 2013: use instead the odroid-wheezy-retro image, instructions here

At this point I advice to eject/insert the microSD card, then run the following:

sudo resize2fs /dev/mmcblk0p2

This will resize the linux partition to the maximum available space on your SD card.

Before proceeding to next step you might want to mount the /dev/mmcblk0p2 partition and change some files there for easier initial setup (like wired network, for example).

And now...ready for the show! Put the SD card back in the ODROID device and boot your device.

Step 2 - First boot operations

The first time you boot you should connect through SSH to your device, default users have the following usernames/passwords:

root / root
user / user

As first operation change those passwords, and possibly you might want to use usermod to rename 'user' to something else.

After that re-generate the SSH keys:

sudo rm /etc/ssh/*_key /etc/ssh/*.pub
sudo dpkg-reconfigure openssh-server

Modify /etc/rc.local by adding these lines before the last exit 0 line (reported for reference):

cpufreq-set -g ondemand -d 200Mhz
chown .video /dev/ump
chown .video /dev/mali
chmod 0660 /dev/ump
chmod 0660 /dev/mali

Install now cpufrequtils package if you are not going to do Step 3.

Also make sure that your user is in the following groups:
user adm cdrom sudo audio dip video plugdev lpadmin pulse

Step 3 - Trimming down the installation (optional)

In this optional step (that is also untested!) I explain how to remove a lot of packages that come by default installed with Linaro Ubuntu, you can skip it if you prefer to customize it by yourself.

Download odroid-u2-slim-package-selections.txt and then restore the selections by running:

sudo apt-get install dselect
sudo dpkg --clear-selections
sudo dpkg --set-selections < odroid-u2-slim-package-selections.txt
sudo apt-get -y update
sudo apt-get dselect-upgrade

A lot of packages will be removed and you should get XFCE installed in place of Unity (although I advise using LXDE).

When you have finished, please run:

sudo dpkg-reconfigure -a

To go through all necessary configuration steps.

Please note that the display manager will also not work! So don't expect any output on HDMI yet. Real men/women use terminal ;)

Step 4 - Getting the bare metal hardware (acceleration)!

It is necessary to update the kernel to use proper Mali400 hardware-accelerated GPU drivers.

We will use the 13th February release:

wget http://dn.odroid.com/Ubuntu_U2/20130213/linux-3.0.63-odroidu2_20130213.tar.gz
tar xvfz linux-3.0.63-odroidu2_20130213.tar.gz
cd linux-3.0.63-odroidu2_20130213
rm fstab
sudo ./install.sh

At this point a reboot is necessary to make the new kernel effective, I will ask you for such reboot at a later step.

Now we will install the vendor-provided mali400 drivers:

wget http://dn.odroid.com/MALI400_R3P2/20130222/mali_packages.tar.gz
tar xvfz mali_packages.tar.gz
cd mali_packages
sudo dpkg -i mali400_2.1-13_armhf.deb mali400-dev_2.1-13_armhf.deb xf86-video-mali_1.0.1-7_armhf.deb
sudo rm -rf /usr/lib/arm-linux-gnueabihf/mesa-egl /usr/share/X11/xorg.conf.d/99-hkl_mali.conf

Please note that we are removing 2 objects here:
  • mesa-egl, because would prevent you from getting the Mali EGL acceleration
  • 99-hkl_mali.conf, that is the default Mali configuration and consitutes just a source of confusion (it always overrides your xorg.conf)

Step 5 - Build your own xf86-video-mali (optional)

This step is optional e.g. you don't need it, I am keeping it here for reference.
Install xorg-dev, xutils-dev, automake, autoconf and libtool, then download the sources from ARM website (I've used release of 11 March 2013 called Linux EXA/DRI2 and X11 Display Drivers r3p2-01rel1), then enter the proper directory and run the following script build.sh:

set -e
ODFLAGS="-DUMP_LOCK_ENABLED=1 -mfpu=neon -mfloat-abi=hard"

autoreconf -rfi
CFLAGS="$ODFLAGS" ./configure --prefix=/usr
CFLAGS="$ODFLAGS" ASFLAGS="-mfpu=neon -mfloat-abi=hard" make -j5

This will quickly deliver an usable xf86-video-mali that you can use in conjunction with the mali400 driver package from step 4.

NOTE: on some older versions of autoconf you can only do autoconf -fi

Step 6 - Starting XFCE4

If you have not before, reconfigure X11 to allow any user:

sudo dpkg reconfigure x11-common

Make sure that "Anybody" is selected and save.

Now let's setup /etc/X11/xorg.conf:

Section "Device"
        Identifier "Mali-Fbdev"
        Driver  "mali"
        Option  "fbdev"           "/dev/fb6"
        Option  "DRI2"            "true"

        Option  "DRI2_PAGE_FLIP"  "false"
        Option  "DRI2_WAIT_VSYNC" "false"

        Option  "UMP_CACHED"      "true"
        Option  "UMP_LOCK"        "false"

Section "Screen"
        Identifier   "Mali-Screen"
        Device       "Mali-Fbdev"


Section "DRI"
        Mode 0666

Please note the DRI2_PAGE_FLIP setting above, set to disabled. If you enable it your applications performance will start to thrash after a couple of minutes. For example RetroArch had a constantly falling down FPS because of this. I have also experienced instant crashes (SEGFAULT) with fullscreen applications using it.
Update 13 July 2013: The segfault was due to using the setting "DefaultDepth 16", and DRI2_PAGE_FLIP does no more show a negative behaviour, actually a positive one - so feel free to enable it. VSYNC can be enabled but it's not effective, see also this post

Update 05 May 2013: I have provided with a more recent version of xorg.conf here in this post, that adds only turning off DPMS

Now we're ready again. Reboot the system (and check that you are running kernel 3.0.63 through uname -a), then run:


XFCE4 will display in all its glory. Your Xorg.0.log will contain:

(EE) AIGLX error: dlopen of /usr/lib/arm-linux-gnueabihf/dri/Mali DRI2_dri.so failed (/usr/lib/arm-linux-gnueabihf/dri/Mali DRI2_dri.so: cannot open shared object file: No such file or directory)
(EE) AIGLX: reverting to software rendering
(II) AIGLX: Screen 0 is not DRI capable
(II) AIGLX: Loaded and initialized swrast
(II) GLX: Initialized DRISWRAST GL provider for screen 0

You can completely disregard the above as hardware acceleration will instead work, and we are now going to verify it.

Bit depth

By specifying a DefaultDepth of 24 you will get a segfault right after the GET_UMP_SECURE_ID_BUF1 line in the log.

Update 18 April 2013: libv has personally sent a patch to mdrjr so that HDMI output up to 32bit will be supported, stay tuned! :)
Update 21 April 2013: by recompiling the 3.0 kernel (provided by Hardkernel) with CONFIG_VIDEO_EXYNOS_24_FORCE=y you can use HDMI in 24 bit mode, many thanks to libv for the patch

Step 7 - Rotating horses and crates!

Now it's time to see hardware acceleration in action.

You can use 3 programs to check the status of hadware acceleration on your ODROID:
  • glxgears, a classic tool to test GLX
  • es2gears, for ES2 testing
  • glmark2-es2, that is actually a benchmark and you will score 92 if everything went right
If your hardware acceleration is enabled you will see FPS above 100 in all of them (although not in all glmark2-es2 tests).

If you verify hardware acceleration to be working, feel free to continue to step 7.

Step 8 - Time for RetroArch

Unfortunately I have not been able to use KMS with Mali 400, I think it's not supported, but I managed to use RetroArch in accelerated X11.

Let's download and compile RetroArch:

git clone https://github.com/Themaister/RetroArch.git
mv RetroArch retroarch 
cd retroarch
CFLAGS="-mfpu=neon -mfloat-abi=hard" ./configure --enable-x11 --enable-gles --enable-alsa --disable-oss --disable-jack --disable-pulse --disable-kms --disable-vg
ASFLAGS="-mfpu=neon -mfloat-abi=hard" make -j5

If you get gcc errors about virtual memory exhausted or other weird corruptions, try to set the governor to userspace for the length of compilation operations.

At this point you should have a compiled retroarch binary, we are ready for Step 8.

NOTE: I have only a small patch, you might want to use it in you have an error there (compiling with VG support):
diff --git a/gfx/vg.c b/gfx/vg.c
index c5b92e0..bbfc3a8 100644
--- a/gfx/vg.c
+++ b/gfx/vg.c
@@ -99,7 +99,7 @@ static void *vg_init(const video_info_t *video, const input_driver_t **input, vo
    RARCH_LOG("Detecting screen resolution %ux%u.\n", vg->mScreenWidth, vg->mScreenHeight);

    vg->driver->swap_interval(video->vsync ? 1 : 0);
-   vg->driver->update_window_title(true);
+   vg->driver->update_window_title();

    vg->mTexType = video->rgb32 ? VG_sXRGB_8888 : VG_sRGB_565;
    vg->mKeepAspect = video->force_aspect;
@@ -387,7 +387,7 @@ static bool vg_frame(void *data, const void *frame, unsigned width, unsigned hei
    if (msg && vg->mFontsOn)
       vg_draw_message(vg, msg);

-   vg->driver->update_window_title(false);
+   vg->driver->update_window_title();


Step 9 - We need a core

RetroArch cannot do anything if you have no cores. Let's build snes9x-next.

git clone https://github.com/libretro/snes9x-next.git
cd snes9x-next
mv snes9x-next libretro-snes9x-next
make -j5 -f Makefile.libretro

Now you will have snes9x_next_libretro.so, take note of the path to this file by copying the output of:

ls $PWD/snes9x_next_libretro.so

Now let's go back into retroarch's working directory and run RetroArch:

DISPLAY=:0 ./retroarch -L /your/complete/path/snes9x_next_libretro.so SNES9X\ Demo\ V1.16\ \(PD\).smc

If you are typing this into an XFCE terminal, then you can omit the DISPLAY=:0 part.

Now you should see the ROM being emulated with FPS count on the window title bar.
You can install the other cores manually (one by one) or by using the libretro-super scripts.

Step 10 - Packing up together

It is advised to use different CPU settings when running retroarch; for this reason I use a script similar to this snes9x.sh:

sudo cpufreq-set -g ondemand --min 1.6Ghz
DISPLAY=:0 ./retroarch -L /your/complete/path/snes9x_next_libretro.so $@
sudo cpufreq-set -g ondemand --min 200Mhz

This script will effectively change the minimum frequency when you are using RetroArch, and then restore it back when you exit (unless you use Ctrl+C, so don't!).

You can even use a higher minimum frequency if you experience slowdowns, however please pay attention that a fan might be needed when overclocking! Please refer to official ODROID information regarding this.

Step 11

SNES9X Demo ROM (Public Domain)

Enjoy it! :)


I think that ODROID-U2 has a lot of potential, I plan to do other interesting things in future with this development board.

Please let me know your feedback if there are errors or possibility of improvements by using the official ODROID forums discussion thread.