Jump to content

Hybris

From postmarketOS Wiki
Revision as of 07:48, 22 May 2020 by Danct12 (talk | contribs) (warning so i wont get messages on telegram)
Note Halium 9 users MUST https://gitlab.com/postmarketOS/pmaports/-/merge_requests/1144 TO BE MERGED, OR BUILD IT ON YOUR OWN.

Libhybris allows devices lacking FLOSS drivers to make full use of their hardware by using the proprietary drivers from Android. Mainlining and using free software drivers is of course the better approach, but it is not possible for all devices. We will not list devices that need hybris as featured devices (see postmarketos.org#83).

What is libhybris?

libhybris is a compatibility layer, allowing libraries compiled with bionic libc (used in Android) to be loaded by applications built with different libc (originally glibc, musl in postmarketOS case).

How it works?

libhybris includes modified Android linker (partially reimplementing it, for several Android versions) and provides android_dlsym function which can be used by host libc applications to load bionic libraries. Bionic libc gets loaded into process space alongside host libc, but with many functions hooked or replaced with host libc ones to avoid various memory structs incompatibilities between two libcs.

However, for this to work, there are few Android-side libraries to be patched. This is necessary to avoid thread-local storage (TLS) slots conflicts, as Android has reserved private slots for system libraries such as libEGL which do not require allocation through pthread API and accessed directly through CPU register containting thread pointer, which causes host libc data to be ovewritten.

Halium and mer-hybris already include patches to workaround that, but if you use different Android tree, the following needs to be applied: bionic patch mentioned in https://github.com/libhybris/libhybris/pull/395

Running Android services in LXC container or chroot

This is not strictly required to use libhybris itself, but is generally needed, because Android drivers expect Android init to be running, which provides property_service, does HW-specific initialization via init.$soc.rc script and starts vendor-specific services.

Halium solves that by providing minimal modified Android base which can run inside LXC container and system-side scripts to do that (provided by lxc-android package). If your device supports LineageOS 14.1, it might be easiest to port Halium and use resulting system.img with lxc-android.

Otherwise it is also possible to run Android init in chroot with graphical services such as zygote disabled. mer-hybris tree (built for SailfishOS ports) is an example of that and contains modifications needed for libhybris to work.

Using libhybris with your device

libhybris current usage

It is used for the Gemini PDA (non-CAF) and Samsung S4 Mini Duos (CAF), Samsung Galaxy S5 (CAF), Xiaomi Redmi 4X (CAF) device ports.

Android system image

First thing to do is convert the halium generated system.img to a mountable image (basically what the halium install script does) and the new system.img to the device, to /var/lib/lxc/android/system.img

The way to do attain this, is:

  • Port halium 7.1 (https://docs.halium.org) to your device. This may take considerable effort. Note that we only have hybris 7.1 packaged at the moment.
  • Get it running to a point where you have at least graphics operational
  • It works if you run the same kernel source for both, and apply all defconfig changes needed for the halium port to your postmarketos port
  • Boot your halium-running device into android recovery, and download the /data/system.img file from it. This is the systemimage you've built for halium, with the modifications that the installation script has done.
  • Flash postmarketOS to your device, where you've included the necessary changes for halium
  • Upload the system.img file to /var/lib/lxc/android/system.img

Install the hybris related packages

$ sudo apk add lxc-android \
               libhybris \
               libhybris-7.1 \
               libhybris-egl \
               libhybris-gles \
               libhybris-libwayland-egl \
               wayland-libs-client \
               wayland-libs-server

For X11 support, install the following, depending if you need software which is built for Code Aurora Forum’s Android for MSM (generally nicknamed “CAF” for short):

$ sudo apk add xf86-video-hwcomposer xf86-video-hwcomposer-7.1-caf

For all the other devices:

$ sudo apk add xf86-video-hwcomposer xf86-video-hwcomposer-7.1

Start the android container

$ sudo rc-service lxc-android start

Configure Xorg

You need to create the /etc/X11/xorg.conf.d/10-<device>.conf with the following:

Section "Device"
  Identifier "Card0"
  Driver "hwcomposer"
EndSection

Run hardware composer test (to verify it all works)

For a CAF device, use this command:

$ EGL_PLATFORM=hwcomposer test_hwcomposer_7_caf

For a non-CAF device, use this command:

$ EGL_PLATFORM=hwcomposer test_hwcomposer

Utilizing libhybris in different subsystems

Graphics

Android HAL requires device vendors to provide HWComposer API implementation. That API can be utilized via libhybris by Wayland compositors or Xorg to output graphical buffers on screen (as opposed to writing to fbdev directly).

The following projects support it:

Sound

PulseAudio Droid modules allow PulseAudio to use Android HAL via libhybris. While it is possible to use ALSA directly, this approach has benefits of reusing Android mixer configs, which gets very tricky on embedded devices such as phones: https://github.com/mer-hybris/pulseaudio-modules-droid. postmarketOS has this packaged as pulseaudio-modules-droid. See also Audio (libhybris).

Cellular

There are two different implementations of RIL plugin for ofono whichs allows it to communicate with Android's RIL daemon for cellular network connectivity (both data and calls).

Camera and media decoding

GStreamer plugin is maintained by SailfishOS - https://github.com/sailfishos/gst-droid. It requires https://github.com/sailfishos/droidmedia to be compiled against device Android tree and minimedia daemon running.

The alternative approach utilized by Ubuntu Touch is to use libcamera_compat_layer and libmedia_compat_layer. They comprised of libraries that need to be compiled against Android (compat folder of libhybris) and libhybris wrappers. Does not work with Android 7 and newer yet.

See also