ODROID-U2I 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!
Do-it-yourselfI 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.
PrerequisitesIn 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).
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 operationsThe 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)
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
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:
tar xvfz linux-3.0.63-odroidu2_20130213.tar.gz
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:
tar xvfz mali_packages.tar.gz
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:
ODFLAGS="-DUMP_LOCK_ENABLED=1 -mfpu=neon -mfloat-abi=hard"
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 XFCE4If 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:
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"
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 depthBy 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 you verify hardware acceleration to be working, feel free to continue to step 7.
Step 8 - Time for RetroArchUnfortunately 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
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
@@ -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->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)
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
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:
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.
|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.