How to use Mesa with GL/EGL GPU acceleration and DRM for Tizen 3.0 TV profile (wayland backend) on RPI2

From Tizen Wiki
Jump to: navigation, search

WARNING: this page is obsolete, please do not refer to the following guide unless you really have to.

Contents

Introduction

This guide will explain how to set up Tizen with TV profiles on a RaspberryPi 2. The end result will be having a full working operating system that will show, in a monitor or TV connected to through HDMI cable the Tizen TV UI.

I will go step by step from the SD card partitioning, boot loader, Linux Kernel compilation to the UI setting. As you will notice along the guide, the Tizen TV on Raspberry Pi 2 project is still very experimental and that's why it requires quite many steps; don't get daunted, reach the end and have fun.

Before start getting our hands dirty, an assumption is due: the SD card I will use will be associated to the /dev/sdb node and I will assume that the OS doesn't mount it automatically when plugged. So that, when performing the 'mount' or 'umount' operations, check before what is the status of the SD card.

Partitioning the SD card

Insert a micro SD card in your PC and check to which node it is associated (you can check it by running dmesg). I will assume that the SD card will be /dev/sdb, please use the correct node when following these instructions. Keep also in mind that the sizing of each partition can be done accordingly to the size of the SD card in use, the following is just an example and, in my case, I am using an 8GB SD card.

I will use fdisk as partitioner:

# fdisk /dev/sdb

Delete all partitions:

Command (m for help): o
Created a new DOS disklabel with disk identifier 0xa51ccd10.

We will setup a partition table as follows:

Label            dev             size
========================================
BOOT             /dev/sdb1       32 MB
ROOTFS           /dev/sdb2       3072 MB
SYSTEM-DATA      /dev/sdb3       512 MB
[Extend]         /dev/sdb4
 USER            /dev/sdb5       3.9 GB
 MODULE          /dev/sdb6       20 MB

The BOOT partition will contain the bootloader, the Linux Kernel and the parameters needed by the kernel to boot:

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-62521343, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-62521343, default 62521343): +32M

Created a new partition 1 of type 'Linux' and of size 32 MiB.

It has to be FAT32, so that the bootloader can access the files stored:

Command (m for help): t
Selected partition 1
Partition type (type L to list all types): b
Changed type of partition 'Linux' to 'W95 FAT32'.

The ROOTFS will contain all the file system:

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2):
First sector (67584-62521343, default 67584):
Last sector, +sectors or +size{K,M,G,T,P} (67584-62521343, default 62521343): +3072M

Created a new partition 2 of type 'Linux' and of size 3 GiB.

The SYSTEMDATA will contain all the system specific data like the user's home directory and TV profiling:

Command (m for help): n
Partition type
   p   primary (2 primary, 0 extended, 2 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (3,4, default 3):
First sector (6359040-62521343, default 6359040):
Last sector, +sectors or +size{K,M,G,T,P} (6359040-62521343, default 62521343): +512M

Created a new partition 3 of type 'Linux' and of size 512 MiB.

The fourth partition will be, instead, extended, as we need a total of five partitions:

Command (m for help): n
Partition type
   p   primary (3 primary, 0 extended, 1 free)
   e   extended (container for logical partitions)
Select (default e): e

Selected partition 4
First sector (7407616-62521343, default 7407616):
Last sector, +sectors or +size{K,M,G,T,P} (7407616-62521343, default 62521343):

Created a new partition 4 of type 'Extended' and of size 26.3 GiB.

We can proceed now at creating logical partitions within the extended. The partition number 5 will contain the user data, that is meant to save some user specific information:

Command (m for help): n
All primary partitions are in use.
Adding logical partition 5
First sector (7409664-62521343, default 7409664):
Last sector, +sectors or +size{K,M,G,T,P} (7409664-62521343, default 62521343): +3.9G

Created a new partition 5 of type 'Linux' and of size 3.9 GiB.

The last partition will contain some rpm modules and scripts:

Command (m for help): n
All primary partitions are in use.
Adding logical partition 6
First sector (62461952-62521343, default 62461952):
Last sector, +sectors or +size{K,M,G,T,P} (62461952-62521343, default 62521343): +20M

Created a new partition 6 of type 'Linux' and of size 20 MiB.

We are finally done with the partitioning and at the end everything should look like the following:

Command (m for help): p

Device    Boot      Start         End      Blocks   Id  System
/dev/sdb1   *        8192       73727       32768    e  W95 FAT16 (LBA)
/dev/sdb2           73728     6365183     3145728   83  Linux
/dev/sdb3         6365184     7413759      524288   83  Linux
/dev/sdb4         7413760    15523839     4055040    5  Extended
/dev/sdb5         7413761    15466495     4026367+  83  Linux
/dev/sdb6        15466497    15507455       20479+  83  Linux

Do not worry now about the sizing in case you have a bigger SD card, as later we will resize the partitions to fill all the micro SD capacity.

If everything is correct, then we can apply the changes:

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Now it's time to create the file system on each of the partitions, remember that the first partition has to be FAT32, while the others will all be ext4:

# mkfs.vfat /dev/sdb1 -n BOOT
# mkfs.ext4 /dev/sdb2 -L ROOTFS
# mkfs.ext4 /dev/sdb3 -L SYSTEMDATA
# mkfs.ext4 /dev/sdb5 -L USER
# mkfs.ext4 /dev/sdb6 -L MODULE

The partition table is set and ready to be populated.

Setup the bootloader

The firmware provided for the Raspberry Pi 2 is delivered as a binary and it contains the bootloader and the arguments needed by the bootloader in order to boot. It is available from github:

$ git clone  https://github.com/raspberrypi/firmware rpi2-firmware

The version we have tested and known to work fine, is available at the commit 89881b5488a5a60088677333dcbd97e1836c0e7e

$ cd rpi2-firmware
$ git checkout 89881b5488a5a60088677333dcbd97e1836c0e7e -b tizen-rpi2

The directory ./boot contains all the file required for booting any version of Raspberry Pi, including the second. It contains also a generic version of the Linux Kernel which, depending on the dtb file, can boot different versions of the hardware.

We need to copy the required files into the SD but first of all insert and mount the SD card:

# mount /dev/sdb1 /mnt/sdb1

then copy the files:

$ cd rpi2-firmware
# cp boot/bootcode.bin /mnt/sdb1/
# cp boot/cmdline.txt /mnt/sdb1/
# cp config.txt /mnt/sdb1/
# cp fixup.dat /mnt/sdb1/
# cp start.elf /mnt/sdb1/

The boot partition is not ready yet, as the kernel provided by the repository doesn't implement the drm drivers.

Kernel compilation

In this section we are going to compile the Linux Kernel with the gpu drivers.

Before downloading and compiling the Kernel, we require some tools needed to synchronize the Kernel with the bootloader

$ git clone https://github.com/raspberrypi/tools

Now we can download the Linux Kernel directly from the git repository

$ git clone https://github.com/krzk/tizen-tv-rpi-linux.git

Make sure to have a toolchain in place. If you don't, you can get a cross compiling environment from here or from your distribution. In any case, for a matter of readability let's export the following variables which will allow us to build an ARM kernel:

$ export ARCH=arm
$ export CROSS_COMPILE=<path to your toolchain>/arm-linux-gnueabi-

Configure the Kernel

$ cd linux-rpi
$ make tizen_rpi2_defconfig

and then compile:

$ make

To make the compilation a bit faster you could add the flag -jX after make where X is normally a number between the number of cores of the building machine and two times the cores of the building machine.

The kernel needs to be "tagged" by adding some code to the zImage binary, this way the bootloader will be able to find the right Kernel to load and and its binary properties. This operation is performed by using mkknlimg:

$ ../tools/mkimage/mkknlimg --dtok arch/arm/boot/zImage arch/arm/boot/zImage

Let's copy the kernel image to the boot partition we created earlier. Together with the kernel we need also the dtb file, which is a binary format of the hardware description for the Raspberry Pi 2

# cp arch/arm/boot/zImage /mnt/sdb1/kernel7.img
# cp arch/arm/boot/dts/bcm2709-rpi-2-b.dtb /mnt/sdb1/

Now unmount the partition:

# sync
# umount /dev/sdb1

Installing a basic FS

A basic Tizen 3.0 file system is available in an archive that contains the images of the three partitions. It is available here:

$ wget https://download.tizen.org/releases/milestone/tizen/tv-3.0.m1/latest/images/arm-wayland/tv-wayland-armv7l-odroidu3/tizen-tv_20150914.3_tv-wayland-armv7l-odroidu3.tar.gz

untar it:

$ tar zxf tizen-tv_20150914.3_tv-wayland-armv7l-odroidu3.tar.gz

The tar includes three files

  • rootfs.img contains a complete copy of the root file system
  • system-data.img contains the file related to the system and user
  • user.img contains the informations about the different users which use the device

these images are related to three of the partitions we created earlier, respectively sdb2, sdb3 and sdb5. Let's proceed with the copy:

# dd if=rootfs.img of=/dev/sdb2
# dd if=system-data.img of=/dev/sdb3
# dd if=user.img of=/dev/sdb5

Because the size of the image can be different from the size of the partition, we can fit the image the entire partition. Before a check is required on each of them

# e2fsck -p /dev/sdb2
# e2fsck -p /dev/sdb3
# e2fsck -p /dev/sdb5

Now we can resize

# resize2fs /dev/sdb2
# resize2fs /dev/sdb3
# resize2fs /dev/sdb5

At this point, if everything went well, we should be able to boot and get a serial console. Anyway nothing will come out from the monitor as we haven't set up the TV profile yet.

Enable the TV profile

For the coming steps I will suppose that you have already the Tizen build environment working on your PC, if not, please enable it following the instructions from this page.

Set up the environment

Before getting into the Qemu cross-compile environment, we need to perform some manual operations.

Insert the SD card and mount the second partition which contains the root file system:

# mount /dev/sdb2 /mnt/sdb2

In order to enable page flipping we need to remove or comment out the line ECORE_DRM_DEVICE_USER_HANDLER=1 in the enlightenment configuration file:

# vi /mnt/sdb2/etc/sysconfig/enlightenment

at the end the file should look like:

# env for display-manager-service.run
XDG_RUNTIME_DIR=/run
ECORE_DRM_TTY=/dev/tty1
ECORE_EVAS_FORCE_SYNC_RENDER=1
E_START=enlightenment
# ECORE_DRM_DEVICE_USER_HANDLER=1 
ELM_PROFILE=tv
ECTOR_BACKEND=default

To enable eglSwapBuffers inside EFL in the wayland_egl module we need to edit efl.sh and add at the end of the file:

$ echo "export EVAS_GL_SWAP_MODE=full" >> /mnt/sdb2/etc/profile.d/efl.sh

and also in the ecore.sh file we need to add at the end

$ echo "# add this eglGetDisplay() detection error work around..." >> /mnt/sdb2/etc/profile.d/ecore.sh"
$ echo "export EGL_PLATFORM=w" >> /mnt/sdb2/etc/profile.d/ecore.sh"

Two more packages are still needed:

  • e-tizen data
  • libllvm

We can download then somewhere in the SD card, for example in the root directory

# cd /mnt/sdb2/root
# wget https://download.tizen.org/snapshots/tizen/tv/latest/repos/arm-wayland/packages/armv7l/# libllvm-3.5.0-10.8.armv7l.rpm # TODO : obsolete ?

Unmount the SD card

# sync
# umount /dev/sdb2

Now boot the Raspberry Pi with the SD card and the serial console connected to the computer. You should be able to login through the console. When asked for the password, type 'tizen'

localhost login: root
Password: [tizen] 
Welcome to Tizen
root@localhost:~# 

We can install now the two rpm packages:

# cd /root
# rpm -Uvh libllvm-3.5.0-10.7.armv7l.rpm

Prepare for installation

To deploy the software to the SD card we will keep mounted the rootfs partition (sdb2) in a directory accessible from the Qemu envoronment. Insert the SD card mount it on mnt/

# mount /dev/sdb2 ~andi/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/mnt

watch out for the ~andi username, use your own, as this operation is performed as root user.

Now the SD card is mounted in the Tizen cross compile envoronment and we can install all the packages that we compiled above by adding the prefix flag to the make install command.

During this last phase of the guide, we will need some patches, they they are reachable through git at:

$ git clone https://github.com/krzk/tizen-tv-rpi-stuff

Enlightenment

Enlightement is the main Tizen development tool which will run an ARM virtual environment using the Qemu functionalities. We will use it for compiling some complementary software required to enable the TV profile. Let's start by downloading it:

$ git clone git://git.tizen.org/platform/upstream/enlightenment

We need to switch to the TV profiling:

$ cd enlightenment
$ git checkout 89e9c42564da70c3f73e1fe7e7472a55570843ad -b tizen_tv

A patch that is enabling some more libraries is required and available from the rpi-stuff repository:

$ patch -p1 < <path_to_repo>/tizen-tv-rpi-stuff/gbs-buildroot-enlightenment-spec.patch

Now we are ready to generate the tizen toolchain environment:

$ gbs build -A armv7l --include-all --clean

This command will generate a directory, GBS-ROOT, in your home which contains a Tizen file system where to "chroot" in. During the build process there might be some errors and warnings but you can ignore them.

libjpeg

Now we can start building the missing packages. Move to the home directory of the newly created Tizen file system and we will install the first package libjpeg8.

$ cd ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/home/
$ git clone git://git.tizen.org/framework/multimedia/libjpeg8

We need now to compile it using the toolchain, time to 'chroot':

$ gbs chroot -r ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/

Now we should have entered the tizen emulator in the '/' root directory. Move to the home where we downloaded the libjpeg8 library

(tizen-build-env)@samsunx /]# cd home/libjpeg8/


As the majority of the packages the steps are configuration, compilation and installation:

# ./configure --prefix=/mnt/usr --disable-static --enable-shared
# make
# make install

Note the --prefix=/mnt/usr, in this way we have installed libjpeg into the SD card.

drm

The next package is the drm library. At this point we can logout from the virtual machine and fetch it with git. I opened, instead, another terminal and from there:

$ cd ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/home
$ git clone http://anongit.freedesktop.org/git/mesa/drm.git

A is required from rpi-stuff:

$ cd drm
$ patch -p1 < <path_to_repo>/tizen-tv-rpi-stuff/libdrm-configure.patch

Now we need to build from the Tizen virtual machine

# cd /home/drm
# ./autogen.sh --prefix=/mnt/usr \
	--disable-silent-rules \
	--disable-dependency-tracking \
	--disable-cairo-tests \
	--enable-omap-experimental-api \
	--enable-freedreno-experimental-api \
	--enable-install-test-programs \
	--enable-intel
# make
# make install

Because the libdrm is needed for the installation of the next package, we need to install it also in the rootfs of the Tizen Qemu file system, it means that we need to set this time --prefix=/usr:

# make clean
# ./autogen.sh --prefix=/usr \
	--disable-silent-rules \
	--disable-dependency-tracking \
	--disable-cairo-tests \
	--enable-omap-experimental-api \
	--enable-freedreno-experimental-api \
	--enable-install-test-programs \
	--enable-intel
# make
# make install

mesa

The mesa package requires the python2-mako package that can be downloaded from here. Fetch it somewhere in your filesystem and you will get the file python2-mako-1.0.3-1-any.pkg.tar.xz. Untar the file with target directory the Qemu Tizen Filesystem:

$ tar xf python2-mako-1.0.3-1-any.pkg.tar.xz -C ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0

To keep it coherent I will untar the file also in the SD card:

$ tar xf python2-mako-1.0.3-1-any.pkg.tar.xz -C ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/mnt

Now we can proceed like before: in a separate terminal:

$ cd ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/home
$ git clone http://anongit.freedesktop.org/git/mesa/mesa.git
$ cd mesa/

A patch is required:

$ patch -p1 < <path_to_repo>/tizen-tv-rpi-stuff/mesalib-src.patch

On the virtual machine:

# cd /home/mesa
# ./autogen.sh --prefix=/mnt/usr \
	--enable-gles1 \
	--enable-gles2 \
	--enable-gbm \
	--disable-glx \
	--enable-nls \
	--enable-dri \
	--with-dri-drivers=swrast \
	--disable-dri3 \
	--enable-egl \
	--with-egl-platforms=drm,wayland \
	--with-gallium-drivers=swrast,vc4,vc4 \
	--enable-gallium-egl \
	--enable-gallium-gbm \
	--enable-gallium-llvm \
	--with-llvm-shared-libs \
	--disable-openvg
# make
# make install

efl

On your machine terminal same thing as before:

$ cd ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/home
$ git clone git://git.tizen.org/platform/upstream/efl

The version bc860c4f270f59efcfc3345a64ab000be44bdb72 is known to work and tested

$ cd efl
$ git checkout bc860c4f270f59efcfc3345a64ab000be44bdb72 -b m1release

Patch it:

$ patch -p1 < <path_to_repo>/tizen-tv-rpi-stuff/efl-src.patch

On the virtual terminal we will build:

# cd /home/efl
# ./autogen.sh --prefix=/mnt/usr \
	--with-glib=always \
	--disable-xim \
	--disable-scim \
	--disable-gesture \
	--with-tests=regular \
	--enable-fb \
	--disable-tslib \
	--enable-wayland \
	--enable-drm \
	--enable-gl-drm \
	--enable-egl \
	--with-opengl=es \
	--enable-tile-rotate \
	--disable-rpath \
	--with-x11=none \
	--enable-tile-rotate \
	--disable-rpath \
	--disable-cxx-bindings \
	--enable-systemd \
	--enable-lua-old \
 	--enable-ecore-buffer \
	--enable-i-really-know-what-i-am-doing-and-that-this-will-probably-break-things-and-i-will-fix-them-myself-and-send-patches-aba
# make
# make install

Conclusion

If everything went fine, then you can umount the sd card

# sync
# umount /dev/sdb2

Insert it in the RaspberryPi and boot with an HDMI monitor connected and you should be able to see the Tizen TV UI... good luck :-)

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox