Saturday, January 10, 2015

Vivante GPU on i.MX6

Installation of GPU driver on i.MX6 SabreLite. The support libraries for the i.MX6 GPU are available in the Yocto project release for i.MX6: the notes below are for using the binary release files with a Ubuntu rootfs (debootstrap) install.

References:
Frescale Linux 3.10.17_1.0.0 GA Release (registration required)
Direct link to i.MX 6Dual/6Quad Linux Reference Manual (BSP release L3.0.35_4.1.0) uploaded to Freescale forum - Chapter 9 Graphics Processing Unit
Direct link to i.MX 6 Linux Reference Manual (BSP release L3.10.17_1.0.0-ga) uploaded to Freescale forum (Chapter 13 Graphics Processing Unit.)
Summary of L3.10.17_1.0.2 i.MX 6 Yocto Project Patch Release


Installing Xorg

With the system bootstrapped to Ubuntu 13.10, a minimal Xorg 1.14.6 (runs xterm but no window manager) can be installed as follows:

apt-get install --no-install-recommends xserver-xorg-core xserver-xorg-input-all xserver-xorg-video-fbdev
apt-get install xinit

Run startx and make sure an xterm shows up. Make sure the following entry exists in /etc/apt/sources.list and install mesa-utils:

deb http://ports.ubuntu.com/ubuntu-ports saucy universe

With everything setup correctly so far, glxgears -info shows the following:

GL_RENDERER   = Software Rasterizer
GL_VERSION    = 1.4 (2.1 Mesa 9.2.0)
GL_VENDOR     = Mesa Project
GL_EXTENSIONS =
423 frames in 5.1 seconds = 83.247 FPS


Installing Binary GPU Libraries

Download BSP components to use with kernel boundary-imx_3.10.17_1.0.0_ga:

http://downloads.yoctoproject.org/mirror/sources/xserver-xorg-video-imx-viv-3.10.17-1.0.2.tar.gz
http://downloads.yoctoproject.org/mirror/sources/gpu-viv-bin-mx6q-3.10.17-1.0.2-hfp.bin


Setup gpu-viv-bin-

The system may already have files which the content of gpu-viv-bin- will overlap. This can be checked as follows:

debian@arm:~/yocto/gpu-viv-bin-mx6q-3.10.17-1.0.0-hfp/usr$   for fn in `find`; do [ -f /opt/xorg/$fn ] && ls /opt/xorg/$fn && done

On Ubuntu, the existing libraries will need to be removed from arm-linux-gnueabihf-mesa and arm-linux-gnueabihf-mesa-egl. Alternatively, they can be hidden from ld.so by commenting entries in /etc/ld.so.conf.d/arm-linux-gnueabihf_GL.conf etc. (you may see that those are links to corresponding files in  /etc/alternatives/).

On Debian, libGL.so and company are installed into /usr/lib.

My system wanted to prioritize the from-scratched libraries in /opt/xorg, so I had to resort to explicitly setting the library path order in order to pick up the blobs from /usr/lib:

LD_LIBRARY_PATH=/lib/arm-linux-gnueabihf:/usr/lib/arm-linux-gnueabihf:/usr/local/lib:/usr/lib:/opt/xorg/lib


Confirming DRI device

The running kernel must be built with CONFIG_DRM_VIVANTE=m and CONFIG_MXC_GPU_VIV=y (add 'vivante' to /etc/modules'). Verify that vivante and drm modules are loaded. 

Install '/etc/udev/rules.d/10-imx.rules' (from FSL github) and verify the rule for /dev/galcore i.e. "KERNEL=="galcore", MODE="0660", GROUP="video":

One additional rule to add:
KERNEL=="mxc_asrc",  MODE="0666"


Verify that the device nodes appear as follows ...

crw-rw---- 1 root video 226, 0 Jan 10 17:31 /dev/dri/card0
crw-rw-rw- 1 root root 199, 0 Jan 10 17:18 /dev/galcore

Also, make sure your user had been added to group 'video' e.g.

sudo usermod -a -G video ubuntu

(Remember this hint when glxgears stubbornly defers to rasterizer instead of GC2000!)


od /dev/dri/card0 # this works while X running, otherwise 'Invalid argument'


Testing with Vivante (FB) tutorials
Before trying to build the Vivante EXA driver for Xorg, first try to test GPU acceleration in the framebuffer. Exit X if it is running.

Refer to Table 13-2 of i.MX 6 Linux Reference Manual for overview of the GPU Library structure. For each library, a symbolic link must be made from either the X11 or the framebuffer version to the soname (this was documented a bit more explicitly in the L3.0.35_4.1.0 Linux manual):

        cd /usr/lib
        rm libGAL.so
        rm libEGL.so
        rm libEGL.so.1
        rm libVIVANTE.so
        sudo ln -s libGAL-fb.so libGAL.so
        sudo ln -s libEGL-fb.so libEGL.so
        sudo ln -s libEGL-fb.so libEGL.so.1
        sudo ln -s libVIVANTE-fb.so libVIVANTE.so

Be sure to change to the directory containing the tutorial e.g. 'opt/viv_samples/vdk/' otherwise it will fail silently if it unable to open any files it is expecting to exist in the current working directly.

Tutorial may also fail silently if ld.so paths are not setup properly, or udev rules not configured correctly (refer to previous section).


Testing with X

Refer to Chapter 18 of Linux Reference Manual L3.10.17_1.0.0-ga for background information. Assuming the library sonames need to be relinked to the -x11 versions:

        cd /usr/lib
        rm libGAL.so
        rm libEGL.so
        rm libEGL.so.1
        rm libVIVANTE.so
        rm libGLESv2.so
         ln -s libGAL-x11.so libGAL.so
         ln -s libEGL-x11.so libEGL.so
         ln -s libEGL-x11.so libEGL.so.1
         ln -s libVIVANTE-x11.so libVIVANTE.so
         ln -s libGLESv2-x11.so libGLESv2.so
         ln -s libGLESv2-x11.so libGLESv2.so.2


Building the Vivante Xorg EXA Driver

apt-get install xserver-xorg-dev

If $xorg is something different from default i.e. "/usr" it could present a problem, as system include files are referenced in the following manner:

 -I$(sysroot)/usr/include

If the $xorg string does not end in 'usr', then it requires modification to all occurrences of $(sysroot)/usr in EXA/src/makefile.linux

In addition, the path to libdrm includes may need modified e.g.

LOCAL_CFLAGS += -I$(sysroot)/include/libdrm

If all is well, vivante_drv.so will be built with the following compile line (addition of sysroot= if necessary):

BUILD_HARD_VFP=1 XSERVER_GREATER_THAN_13=1 BUSID_HAS_NUMBER=1 ./fastbuild.sh sysroot=/opt/xorg

Install the EXA driver:

sudo cp EXA/src/vivante_drv.so /opt/xorg/lib/xorg/modules/drivers/


The Vivante driver must be enabled in /etc/X11/xorg.conf - the file may not even exist on the system yet since it is typically not needed for the default framebuffer driver. A minimal xorg.conf is adequate to get my system working.

After firing up xorg (startx or window manager if one is installed), verify in Xorg.log that Vivante is loaded:

[  1610.413] (II) VIVANTE: driver for vivante fb: VivanteGC500, VivanteGC2100,
        VivanteGCCORE

You should not see this:

[    90.587] (II) GLX: Initialized DRISWRAST GL provider for screen 0

Everything should now be in place for glxgears.

debian@arm:~$ glxgears -info
GL_RENDERER   = Vivante GC2000
GL_VERSION    = 2.1 2.0.1
GL_VENDOR     = Vivante Corporation
GL_EXTENSIONS = WGL_ARB_extensions_string WGL_EXT_extensions_string WGL_EXT_swap_control GL_EXT_texture_env_add GL_ARB_multitexture GL_ARB_multi
...
875 frames in 5.0 seconds = 174.912 FPS


If things are not setup correctly, glxgears does not perform as expected (e.g. jerky display) or possibly not at all. If Xorg confirmed to have loaded VIVANTE, and glxgears output appears as below (uses software rasterizer), and the framebuffer tutorials worked, it's likely a permissions problem (check that your user is added to group video ... you were warned!)

debian@arm:~$ glxgears -info
libGL error: open DRM failed (Operation not permitted)
libGL error: reverting to (slow) indirect rendering
GL_RENDERER   = Software Rasterizer
GL_VERSION    = 1.4 (2.1 Mesa 9.2.0)
GL_VENDOR     = Mesa Project
GL_EXTENSIONS =
423 frames in 5.1 seconds = 83.247 FPS


Chapter 18 of Linux Reference Manual L3.10.17_1.0.0-ga makes it pretty clear that the drm-update-arm.patch must be applied to libdrm ("adding the ARM lock implementation", which might be a compelling reason to build xorg-xserver from source.

Next exercise is to build glmark2 and mesa-utils.


Monday, January 5, 2015

Debootstrap on i.MX6 Sabre Lite

My notes on installation of the root filesystem (RFS) on Freescale i.MX6 based SBCs (most on Boundary Devices BD-SL-i.MX6 aka Sabre Lite). This post was first written to document experiences with deboot-strapping Debian (Jessie), and since then I have also experimented with Ubuntu 13.10 Saucy, as it provided Xorg-server 1.14.6. Unfortunately I have not been able to get es2gears-x11 running on Ubuntu.

While making these notes I was following a debootstrap tutorial written for Olimex and did not bother repeating a lot of the details. I debootstrap the new rootfs on a spare card, using the same Sabre Lite board (running Debian Wheezy) as a host. The instructions on the Olimex blog include the details needed to bootstrap on a host of different architecture than the target.

I perform the installation with distro=jessie and use the following configuration of /etc/apt/sources.list to set my package sources to US servers:

cat << EOT > /etc/apt/sources.list
deb http://ftp.us.debian.org/debian/ $distro main contrib non-free
deb http://ftp.us.debian.org/debian/ $distro-updates main contrib non-free
deb http://security.debian.org/ $distro/updates main contrib non-free
EOT


My locale is en_US.UTF-8

While creating the RFS, I add a user in the standard way i.e. adduser debian.

Creation of /etc/fstab is absent from the instructions in the blog ... I use the following setup, which allows me to easily delete and re-install the RFS at a whim (important requirement for development), while keeping /home isolated from the RFS on it's own partition:

/dev/mmcblk0p1   /           auto   errors=remount-ro   0   1
/dev/mmcblk0p2   /home       auto   defaults            0   2

For Debian (see below for Ubuntu), the serial console login is enabled on Sabre Lite with the following line added to /etc/inittab:

T1:23:respawn:/sbin/getty -L ttymxc1 115200 vt102

One problem emerged with the first boot on the new RFS - the system failed to spawn a login process on the serial port (/dev/ttymxc1), although the login was working fine through the attached monitor/keyboard ... the following messages were observed on the serial console:

[ TIME ] Timed out waiting for device dev-ttymxc1.device.
[DEPEND] Dependency failed for Serial Getty on ttymxc1.

After enabling CONFIG_FHANDLE in my kernel (boundary-imx_3.10.17_1.0.0_ga) and rebuilding, I could login on the serial port.

With ethernet working and openssh-server already installed during the debootstrap process, I could get busy updating the system and installing some essential software packages:

apt-get install curl vim sudo gcc make bzip2 python lzop bc git libncurses5-dev
apt-get install flex libtool automake pkg-config bison 



There is one (apparently harmless) quirk observed with the new system:

[FAILED] Failed to start Login Service.
See 'systemctl status systemd-logind.service' for details.

This is possibly related to a bug in jessie. It seems that "standard system utilities" is not installed in the minimal debootstrap process - the bug report states that there is no negative effect on the boot process so long as the "System-V" init package is installed. A little more web crawling seems to indicate that there is something to do with tasksel, but I'm relatively new to Debian so leave it alone for now. (Update 1/22/2015 GN: noticed there is not a complete inittab installed so getty is not being called on tty[1-4])


Atheros WLAN working after firmware install:

usb 2-1.2: ath9k_htc: Failed to get firmware htc_9271.fw
(apt-get install firmware-atheros)


Here is some guidance on the u-boot parameters:

setenv bootargs console=${console},${baudrate} root=/dev/mmcblk0p1  rootfstype=ext4 rootwait video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off video=mxcfb4:off video=mxcfb5:off video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB16 fbmem=48M vmalloc=400 mxc_hdmi.only_cea=1 coherent_pool=48M

ext2load mmc ${mmcdev}:${mmcpart} ${fdt_addr} boot/${fdt_file}
ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} boot/${image}
bootz ${loadaddr} - ${fdt_addr}


For Ubuntu, the instructions are practically identical ... just a few differences.

sudo debootstrap --arch armhf saucy rootfs/

# etc/apt/sources.list:
deb http://ports.ubuntu.com/ubuntu-ports saucy main
#deb http://ports.ubuntu.com/ubuntu-ports/ saucy-updates main universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports saucy universe # mesa-utils


Serial port is enabled as follows:
# /etc/init/serial.conf
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
exec /sbin/getty 115200 ttymxc1


Jury is still out as to which distro is better to get the GPU stuff working on i.MX6..

Tuesday, March 4, 2014

Arcade Game Source Code Project Moved

Moved source code repo to GitHub. For some reason a while back, my remote SVN setup on GoogleCode stopped working. I didn't bother trying to fix it and looking for an excuse to try out GitHub.

Looks like the last update on GoogleCode was starting to implement the diving attack aliens. The red and yellow aliens are diving very nicely now and collisions are also handled with the fighter. Getting ready to start work on the green bosses.

Thursday, February 27, 2014

SABRE Lite i.MX6

First, getting the board running from pre-packaged Ubuntu image is easy thanks to armhf.com:

http://www.armhf.com/index.php/boards/nitrogen6x-sabre/


Building a custom kernel ... you don't have to be a trailblazer here, just follow instructions:

Refer to http://www.eewiki.net/display/linuxonarm/i.MX6x+SABRE+Lite

I built some kernels from github.com/RobertCNelson/armv7-multiplatform.git 

... but they choked on USB.

Instead I altered the procedure slightly to match the 3.9 kernel as found in the armhf.com image....

git clone https://github.com/RobertCNelson/imx-devel.git
cd imx-devel/
git checkout origin/v3.9.x-imx -b tmp
./build_kernel.sh

sudo mount /dev/sdb1 /media/tmp/
sudo cp -v imx-devel/deploy/3.9.11-imx5.zImage  /media/tmp/boot/zImage
sudo tar xfv ./imx-devel/deploy/3.9.11-imx5-dtbs.tar.gz -C /media/tmp/boot/dtbs/
sudo tar xfv ./imx-devel/deploy/3.9.11-imx5-modules.tar.gz -C /media/tmp/


After completing the above steps, I rebooted the Sabre Lite and ended up with this:

ubuntu@ubuntu-armhf:~$ uname -a
Linux ubuntu-armhf 3.9.11-imx5 #1 SMP Thu Feb 27 12:22:07 EST 2014 armv7l armv7l armv7l GNU/Linux

Tuesday, July 30, 2013

arcade-game-source-code project update

I finally have enough of the movement engine implemented, so that all the enemies are able to make it successfully to their positions in the home formation. This includes the side-to-side and the "pulsing" components of the motion. Please see video below. I haven't shared many technical details about the project to this point (after all, the source code is there for all to see!). One comment I want to make about the video is that even though the title bar window has Mame32 on it, the game logic is not in emulated Z80 - it is all C-code. However, the program is linked to a cut-down version of MAME which takes care of the "machine" stuff, i.e. graphics and sound rendering.


Thursday, February 14, 2013

Debugging apps that use OSS (Ubuntu)

There are still a few legacy applications out there that rely on OSS for the sound system, and on many distributions such as Ubuntu, these programs can be invoked through the "padsp" utility to provide the needed functionality. But what do you do if you want to debug the program in gdb?

Fortunately, the "padsp" functionality can be obtained without actually invoking padsp, by providing the application with one environment setting: "LD_PRELOAD=/usr/lib/i386-linux-gnu/pulseaudio/libpulsedsp.so".

The exact path of the library may be different on your system. This same environment value can specified in gdb with the "set env" directive. What is even more useful is that it can be specified in the command line to gdb, using the gdb argument "-ex", e.g. '-ex "set env BLAH=blurb"' etc.

This becomes very useful in an IDE such as Code:Blocks, where arbitrary command line options to gdb can be specified in the "Settings:Debugger" dialog. Simply paste the entire construct into the "Argument" text box (note the double quotes):

-ex "set env LD_PRELOAD=/usr/lib/i386-linux-gnu/pulseaudio/libpulsedsp.so"

That's all folks!

Friday, February 8, 2013

Galaga C-code Translation

Video of my Galaga C-code version running in a Code:Blocks debug session: