Making an Android device boot to Qt

Published Friday July 4th, 2014 | by

Android Injection

Qt Enterprise Embedded provides pre-built system images for a range of popular devices, like the Nexus 7 tablets and the BeagleBone Black. With these, you can make your device “boot to Qt” and be up and running with embedded development literally within minutes. But what if you want to try a device that is not among these reference devices of Qt Enterprise Embedded? Until recently, as an evaluator, you were basically out of luck. And even with an Enterprise license, you would have to rebuild the image from scratch for your device, a process that can take some time. Now, with the recent update of Qt Enterprise Embedded, there is another option available. If your device runs a recent version of Android, it is now possible to install the Boot to Qt stack directly into the existing Android system image; in effect taking it over. We call this method Android injection. In this blog post we will show how this process works in practice. We will use a device called the ODROID-U3 as our example.

odroid-box

The Injection Steps

The installation process consists of the following:

  1. Unpacking the Boot to Qt system and data archives into the /system and /data folders of the Android system
  2. Creating a device configuration file, appcontroller.conf
  3. Changing the Android boot script (init.rc) to make the device boot to Qt instead. We provide a script to perform the necessary changes.

As you can see, this is not very complicated. However, it cannot easily be automated, since  every device has different ways of packing the file systems and boot files. So a little manual effort is required.

The ODROID-U3 Device

This device is created by Hardkernel and has a quad-core Cortex-A9 processor, Mali-400 graphics processor and HDMI display output, and Android builds are available. For the injection process, any Android 4.2 or 4.4 image should do. For this blog post, I downloaded the Android 4.4 SD card image from here, and installed is as explained here. After booting twice, the device runs Android fine:

odroid-android

1. Unpacking the Boot to Qt system and data archives

The bulk of the Boot to Qt injection stack comes in the form of two tarballs, intended to be unpacked into Androids /system and /data folders respectively. On most Android distributions, those folders have separate partitions on the storage device. We need to determine which partitions that is. One way is to log in to the device and study the /fstab file, which will show where the partitions will be mounted. Like this:

~/odroid$ adb shell cat /fstab.odroidu.sdboot
# Android fstab file.
#                                                              
# The filesystem that contains the filesystem checker binary (typically /system) cannot
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK

/dev/block/mmcblk0p2    /system             ext4      rw                                                    wait
/dev/block/mmcblk0p3    /data               ext4      noatime,nosuid,nodev,nomblk_io_submit,noauto_da_alloc,errors=panic    wait
/dev/block/mmcblk0p4    /cache              ext4      noatime,nosuid,nodev,nomblk_io_submit    wait
/devices/platform/s3c-sdhci.2/mmc_host/mmc0 auto    auto    defaults voldmanaged=sdcard0:1,noemulatedsd
/devices/platform/dw_mmc/mmc_host/mmc0      auto    auto    defaults voldmanaged=sdcard1:auto
/devices/platform/s5p-ehci                  auto    auto    defaults voldmanaged=usbdisk:auto

As we see, in this case /system and /data are on partitions 2 and 3 respectively. After powering down the device, and plugging the SD card into the host PC where the Qt Enterprise Embedded SDK is installed, we are ready to do the unpacking. Here, the SD card appears as /dev/sdb, and the SDK is installed in ~/QtEE31:

~/odroid$ mkdir p2
~/odroid$ sudo mount /dev/sdb2 p2
~/odroid$ sudo tar x -C p2 -f ~/QtEE31/Boot2Qt-3.x/generic-4.4-eAndroid/images/system.tar.xz 
~/odroid$ mkdir p3
~/odroid$ sudo mount /dev/sdb3 p3
~/odroid$ sudo tar x -C p3 -f ~/QtEE31/Boot2Qt-3.x/generic-4.4-eAndroid/images/data.tar.xz

# Checking that things look good so far:

~/odroid$ ls -l p2/bin/qtlauncher
-rwxr-xr-x 1 root root 173420 Jul  1 21:41 p2/bin/qtlauncher
~/odroid$ ls -ld p3/user/qt
drwxr-xr-x 21 root root 4096 Jul  1 21:41 p3/user/qt/

2. Creating a device configuration file

The Boot to Qt stack needs a few environment variables and other device-specific settings. These are stored in plaintext format in the file /system/bin/appcontroller.conf. (Granted, that is not the most natural place for a settings file, but for now, that is where it is). One can see examples for different reference devices in the directories in Boot2Qt-3.x/generic-4.2-eAndroid/images. For the ODROID-U3, we store the following in p2/bin/appcontroller.conf:

#env=QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0
env=QT_QPA_EGLFS_NO_SURFACEFLINGER=0
env=QT_LOGGING_TO_CONSOLE=1
env=QML2_IMPORT_PATH=/data/user/qt/qmlplugins
env=QT_IM_MODULE=qtvirtualkeyboard
base=android
platform=odroidu

Since we do not have a touch screen connected, the line setting the touch screen device has been commented out.

3. Changing the Android boot script

This step can sometimes be a little tricky. The boot script (init.rc) is always in Android’s root file system. But many Android distributions package the kernel and the root file system into a special binary boot image format, and place that in a separate partition. That partition is then not mountable and modifiable like a normal file system. Instead, special scripts must be used to unpack it and repack it after modification. One can easily search up information about the process on the net.

In other cases, the boot script is available as a plain file. That is the case for our sample device, we find the ODROID’s init.rc
file in the root directory of partition 2. The modification process itself is made very simple by a script provided in the Qt Enterprise Embedded SDK:

~/odroid$ sudo cp p2/init.rc p2/init.rc.orig
~/odroid$ sudo sed -f ~/QtEE31/Boot2Qt-3.x/generic-4.4-eAndroid/images/generic/modify_init_rc.sed -i p2/init.rc

# Checking that the modification succeeded:

~/odroid$ tail -1 p2/init.rc
    start boot2qt

Ready to rock!

All that remains is to unmount the SD card:

~/odroid$ sudo umount p2
~/odroid$ sudo umount p3

Now, with trembling fingers take the SD card with your brand new Boot to Qt image and plug it into the device. Then apply the power supply and wait for the screen of success:

odroid-b2qt
(If your device should not start up like this, try to look for error messages in the output from adb logcat and adb shell appcontroller qtlauncher.)

At this point, it is easy to set up your linux host and Qt Creator for one-click deployment of your apps to your device. Just follow the simple instructions for “Setting up USB Access” and “Configuring a Device Kit in Qt Creator” in one of the Android device preparation pages. Then, you are all set to start Building and Running Embedded Applications!

Did you like this? Share it:

Posted in Android, Embedded, Uncategorized

15 comments to Making an Android device boot to Qt

Chris Sparks says:

I couldn’t find the generic folder and when I deleted the Boot2Qt folders so that I could try again they vanished completely from being selected. I am stuck now and don’t know how to determine the repository for the Boot2Qt repository.

Eirik Aavitsland says:

Hi Chris,
I understand your question as being about the installation of the Qt Enterprise Embedded SDK. To try out the latest features, you need to first download the latest installer. In the Download area of your Qt Account, select “Qt Enterprise Embedded” in the combo box.
Then, when running the installer, in the screen where you select what to install, open the folder marked Boot to Qt stack version 3.1.0. Inside it, open the eAndroid folder. There you will find the folders for the generic Android 4.2 and 4.4 devices.

Chris Sparks says:

Thanks Eirik. I tried to reun the original installer which had it, dated file of 30 Jun 2014 07:33:08 AM, and say the Boot to Qt selections but given what you said I may have to download a later version possibly as the one I am rerunning didn’t have generic

Chris Sparks says:

I went looking for a newer version of the embedded installer and the “s3″ file is what i have. Which didn’t have generic folder initially. I wait till the software installs again to see if it still isn’t there.

Chris Sparks says:

looks like I had generic. don’t know how I deleted it before today. I think I am on my way to getting closer.

Chris Sparks says:

With my device I have to modify the boot.img because init.rc is on that partition. Still have to figure out how to inject the data.tar.xz file into my tablet. I cannot remove the internal SDCARD. I don’t know if odin, which is the way I have to flash my device, can handle a data.img as the official firmware version that I am working off of didn’t have a data partition initially (I’ll double check). Also I need to reroot my device as that gets reset when I do a download which may or may not affect the qt build.

Chris Sparks says:

Well I had to overwrite the data and system files to my system first. Then I flashed the new boot.img file and now it is bricked. Logcat doesn’t work so I don’t know what is going on with the device.

Chris Sparks says:

This has been a two day effort so far and it isn’t as easy as your example shows. I have internal SD memory so I have to a lot more steps and hope that the flashing will work. I thought I was going to have success today as I got the system image in there but I keep bouncing back to recovery. I wish I could just install all of your stuff into my partition directly without debloating. My tablet was working fine after I debloated it and I save an “img” file so I can manipulate it in Linux to add your stuff.

Eirik Aavitsland says:

Hi Chris,
Sorry to hear about your troubles. However, I understand that you are trying this on a consumer device. I should perhaps have stressed more that the example above shows the process only for programmable development devices, with removable storage.

That being said, injection can often be made to work on consumer devices too, if they can be “unlocked” to allow system modification. That is why we can have Nexus 7 as an example device. But then the process needs other and additional steps. This subject is too big for a comment (perhaps it can be a future blogpost if there’s interest?) but let me just point in the general direction one would try:

a) Unlocking, like “fastboot oem unlock” for the Nexus.
b) File deployment to internal storage using adb, like the nexus deploy script does.
c) boot.img modification using a script like split_bootimage.pl to unpack, and then a tool like mkbootfs to repack.

But as always, ymmv, no guarantees :)

Chris Sparks says:

I am unfamiliar with unlocking a device. i thought by rooting it that it allowed me to modify it. So I need to try and unlock then.

I have issues with adb so maybe this has to do with the unlocking/locking issue. Let me see if I can “unlock” this device. I have been able to flash boot.img before and I know about those scripts but I think this too is affected by locking.

Let me do some research.

Chris Sparks says:

I cannot find a source for “unlocking” my tablet so I have to call my carrier to see if they can do it for me.

I have a suspicion as to what is going on. I have to verify it.

When one loads the stock firmware there are other apps that get run aboot.mbn, rpm.mbn, sbl2.mbn, sbl3.bmn and tz.mbn. So in essence I think there is a checksum being saved somewhere. So when you install a new boot or a new system image directly (not part of a complete set of files) it bricks. checksum mismatch. When one installs the original system.img.ext4 then all is honky dorey. checksums match. So the test to try is to get my newish system.img.ext4 file into a complete big tar ball and download the bunch to my device with Odin.

Chris Sparks says:

I just tried to download the full ROM to my device using the Qt enhanced system.img.ext4 file along with the other goodies that comes with the firmware release. It kept bouncing back to recovery. Don’t why that is happening but I guess it is better than being bricked! :-) Had to go back to an earlier ROM (recovery changed from stock recovery) which worked.

Chris Sparks says:

Sprint deferred me to Samsung and Samsung has chosen to ignore me. So getting it unlocked is not a likelihood. I think I would have to repartition the device with my own booter and OS.

Chris Sparks says:

This is very frustrating. I cannot get a custom binary loaded on my device. Samsung’s low level cop software is not allow the system to even boot. I guess my only other choice is to buy a more compatible device or trying to go linux embedded on this device and scratch Android altogether. I would think I could get ubuntu running on this, just dont know how to flash it into ROM. Your fastboot tool can’t even see my device.

Especially the Nexus 7 image is very interesting as this tablet is cheaper than most 7″ industry touch screen monitors. Could be very interesting in combination with my real-time remote interfaces: https://github.com/strahlex/QtQuickVcp
https://www.youtube.com/watch?v=Nha1_Jll7JQ

Commenting closed.