Friday, January 28, 2011

Compiling Qt plugins for Kobo Wifi

This article is part of an extended series on Kobo development and investigation


Apparently I have to make this more obvious:

  • Take a backup of your Kobo's SD card before doing anything. If something doesn't work, you can't fix your Kobo without this backup. I will not send you a backup.
  • Any device hacking is risky. If you can't afford to break your device, leave now.

The Kobo Wifi's main user interface application, nickel, is a Qt Embedded app. It drives the ePaper display via a Linux framebuffer interface and some ioctl calls to trigger display refreshes. This is abstracted away from the app behind a QWS (Qt Window System) driver called broadsheet_ioctl that's statically linked into nickel.

Because the QWS driver is only in nickel, we can't really write stand-alone Qt applications to run on the Kobo without reimplementing it. However, the nickel app has a simple plugin interface you can use to load your own code as a shared library.

To do this, you need a full Kobo development environment, including a cross-compiled Qt Embedded build that matches the one used on the Kobo. Once you have that, you can build apps according to the template provided by examples/poker, then drop the shared library produced into /usr/local/Kobo on the device to get it to load.

You now have some totally useless code running on your Kobo. Congratulations. There's no way to invoke it. For now, I'm testing by replacing the poker plugin with my own code, but it's still painful to access it so it's not desirable for real-world use. It may prove necessary to introspect the Qt widget tree or even runtime patch classes to get useful functionality loaded by plugins without having access to the nickel sources.

If your plugin doesn't load, it may be helpful to telnet into your Kobo and create a script like this, called (eg) /usr/local/relaunch-nickel.sh

#!/bin/sh
# Kill off the old nickel
pkill nickel
# Clear plugin cache
rm -f /mnt/onboard/.kobo/Trolltech.conf
# Restart nickel
export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/lib:
export NICKEL_HOME=/mnt/onboard/.kobo
export LD_LIBRARY_PATH=/usr/local/Kobo
export QWS_KEYBOARD=netronix
export INTERFACE=eth0
export LANG=en_US.UTF-8
QT_DEBUG_PLUGINS=1 /usr/local/Kobo/nickel -qws -display broadsheet_ioctl >/mnt/onboard/.kobo/nickel.log 2>&1 &

When executed, this script will restart nickel, causing it to write a debug log to the .kobo directory on the user flash and print detailed information about plugin loading. This might help you figure out what's going on. nickel prints a fair few warnings during normal startup, so don't be thrown by that.

When developing for Qt on Kobo, the Qt for Embedded Linux Environment Variables document may be helpful, though it doesn't mention QT_DEBUG_PLUGINS.

It can also be helpful to determine how Qt was built on your target device. On the Kobo Wifi:

$ strings libQtCore.so | grep 'Build key'
Build key:           arm linux g++-4 full-config

No comments:

Post a Comment