Android/SGX on the Gumstix Overo
9 Aug 2015
This document explains how I, with some assistance and quite a bit of background research by Simon Guest at TracMap, got the PowerVR SGX drivers (3_01_00_03) working with Android 4.3 on the Gumstix Overo. What’s described here isn’t a finished product, but it’s enough to get SurfaceFlinger up and running with hardware acceleration.
Throughout this document, I’m going to assume familiarity with the basics of AOSP development (the use of repo and so forth). Some of this is written from memory, and the state of the respositories described below might have changed slightly in the meantime. Be prepared to fill in some blanks and/or alter these instructions to suit your situation.
Obtaining the necessary files
Our starting point was the Gumdroid repositories, maintained by Ash Charles at Gumstix. The manifest repository contains branches called overo
and dev/overo
. We mixed and matched a little between the two. In particular:
We took almost everything from the
dev/overo
branch. This includes thedevice/gumstix
subtree and the AOSP base. Start by doing arepo init
using this manifest.We took Linux 3.2.0 and U-Boot 2014.10 from the
overo
branch.There is a repository called
hardware-ti-sgx
, which is normally unpacked inhardware/ti/sgx
. We didn’t use this at all.
Get the repositories described above, swapping out the kernel
and u-boot
components as described. You’ll also need to install the SGX Android SDK. Obtain the repository which contains the installer:
git clone git://gitorious.org/rowboat/ti_android_sgx_sdk.git
Inside this repository, you’ll find an installer named OMAP35x_Android_Graphics_SDK_setuplinux_3_01_00_03.bin
. Run that to unpack the SDK. Within the unpacked SDK, the binaries we’re interested in are located in the gfx_rel_es3.x_android subdirectory. There is also source for the kernel bridge driver, but it’s for a fairly old kernel version.
NOTE: Since gitorious.org now appears to be non-functional, I’ve uploaded a copy of the installer to Dropbox. The SHA256 hash of the file is 566fe0e82af4431e1135fc655115faff8196bbbf05f8134a5f46ee82e082aec9:
Modifications
We need to add the PVR bridge driver to the Linux kernel, and we need to add a few userspace components to the system. We also need to modify the Android frameworks to work around some quirks in the SGX userspace drivers.
Kernel bridge driver
The first thing you need to do is integrate the bridge drivers into the kernel with this patch. There are two separate drivers: one manages general communication between userspace and the SGX hardware (pvrsrvkm
), and the other manages display flip-chains (omaplfb
).
To enable these drivers, make sure your kernel configuration has these options set:
CONFIG_SGX_PVRSRV=y
CONFIG_SGX_OMAPLFB=y
This patch registers drivers only. You will also need to declare instances of the hardware to get them working. In your board-specific setup file (probably arch/arm/mach-omap2/board-overo.c
) you’ll need something like this:
static struct platform_device pvrsrvkm_device = {
.name = "pvrsrvkm",
.id = -1
};
static struct platform_device omaplfb_device = {
.name = "omaplfb",
.id = -1
};
static inline void __init overo_init_sgx(void)
{
platform_device_register(&pvrsrvkm_device);
platform_device_register(&omaplfb_device);
}
Remember to call overo_init_sgx
somewhere in your init_machine
function (perhaps overo_init
).
Userspace drivers
As stated above, the files we need from the SDK are in the gfx_rel_es3.x_android
subdirectory of the SDK package. We copy these into place in the device/gumstix/common/sgx/proprietary/3.x
subdirectory in the Android build tree.
But that’s not all! There is a bug in glDiscardFramebufferEXT
in libGLESv2_POWERVR_SGX530_121.so
which causes crashes. Since this function is only an optimization hint, we work around this problem by patching the first instruction to a return, making the call a no-op:
0000c160 <glDiscardFramebufferEXT>:
c160: e12fff1e bx lr
You can use this program to make this modification to your version:
gcc -O1 -Wall -o sgx_bp sgx_bp.c
./sgx_bp libGLESv2_POWERVR_SGX530_121.so
Ash Charles has already included an Android.mk
for the proprietary
subdirectory in the development branch, but we need to modify it a bit, as the names of the binaries to be installed are slightly different. Our modified version is here.
There are two more things that need to be tidied up in device/gumstix/overo
. First, we need to set OMAPES := 3.x
in BoardConfig.mk
. The other thing we need to do is make sure the SGX userspace init program gets run on boot. Add this stanza to init.overo.rc
:
service pvrsrvkm /system/bin/pvrsrvinit
class main
oneshot
Hardware composer
Gumdroid doesn’t provide an hwcomposer
HAL, but there is a skeleton implementation in hardware/libhardware/modules/hwcomposer
. Starting from this, we produced a basic module which provides a VSYNC signal, but supports only GLES composition. The necessary files are here:
This should produce a HAL module called hwcomposer.overo.so
, which is installed in the usual HAL location in the filesystem /system/lib/hw
.
Frameworks
Finally, some of the framework components need modification to work around SGX quirks. Patches for this purpose are listed below:
ignore-visual-id.patch: SGX’s EGL returns 0 for EGL_NATIVE_VISUAL_ID. This causes SurfaceFlinger to think that there are no suitable configurations available.
gralloc-usage-hack.patch: SGX’s gralloc module doesn’t like the GRALLOC_USAGE_HW_COMPOSER flag.
no-egl-image-external.patch: GL_TEXTURE_EXTERNAL_OES is not supported. GL_TEXTURE_2D seems to work as a subsitute for most (?) cases.
Booting
Make sure U-Boot is passing a command-line parameter configuring the kernel’s framebuffer driver to use 32-bit colour. For example:
omapfb.mode=dvi:640x480MR-32@60
Also make sure that you have sufficient video RAM to allocate at least a couple of flip-chain buffers.
The first boot takes quite a long time, as Android will compile packages ahead of time. After a few minutes, you should see the leaf-fall animation appear on screen.
If you’re having trouble, run through the following checklist:
Is the bridge driver working correctly? You should have a
/dev/pvrsrvkm
device node.Has the SGX microkernel been loaded (this is what
pvrsrvinit
does). Check the status withsgx_init_test
.Does SGX know about the display? If you run
pvr2d_test
, you should see a small test image appear on the screen. Note that it’s crucial that theomaplfb
driver is initialized after the OMAP display drivers. I’ve accomplished this withlate_initcall
inomaplfb
.Otherwise, you might have some issue with EGL/GLES. Check the output of
logcat
to see what’s going on.
Limitations
This hasn’t been thoroughly tested. It’s quite possible that some kinds of acceleration (video, perhaps) have been broken as a result of the use of GL_TEXTURE_2D in place of GL_TEXTURE_EXTERNAL_OES.