aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md275
1 files changed, 275 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..314596f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,275 @@
+KDBinder
+========
+
+This library is a proof of concept replacement for `libbinder`, implementing a
+subset of its API on top of KDBUS. `libbinder` is an interface between
+applications and the binder driver in the kernel. `libkdbinder` follows the same
+principle, but allowing us to replace the binder driver by KDBUS.
+
+Note that this work is experimental.
+
+Binder API
+----------
+
+The current state of the Binder API that this library implements is documented
+in `binder.md`.
+
+We are *aiming* to implement as much of the API so that surfaceflinger can run
+along with bootanimation. However, this is a work in progress.
+
+Low-level KDBUS layer
+---------------------
+
+`libkdbinder` implements its own internal interface for KDBUS, the details of
+this API are documented in `kdbus.md`. The API tries to match how KDBUS works
+so it is recommended to have a look at the high level documentation of KDBUS.
+
+Build instructions
+------------------
+
+Throughout these instructions, we'll assume the `${ANDROID_TREE}` environment
+variable points to where Android is checked out.
+
+KDBinder was tested on the JUNO r2 development platform with a release of
+Android M from Linaro.
+
+### Integrating KDBUS and KDBinder in the Android tree
+
+First of all, download the Android tree from linaro:
+
+ $ cd ${ANDROID_TREE}
+ $ repo init -u https://android-review.linaro.org/platform/manifest -b android-6.0.1_r16 -g "default,device,arm"
+ $ cd .repo
+ $ git clone git://android.git.linaro.org/platform/manifest.git -b linaro-marshmallow local_manifests
+
+We need to include KDBUS and KDBinder to the tree. We can do this by adding a
+local manifest file that points to both projects. The manifest will instruct
+`repo` to fetch the out-of-tree KDBUS kernel module and KDBinder.
+
+TODO: Add the `linaro-android` remote to this manifest snippet.
+
+ $ cat > local_manifests/kdbinder.xml <<-EOF
+ <?xml version="1.0" encoding="UTF-8"?>
+ <manifest>
+ <remote name="systemd" fetch="https://github.com/systemd/" />
+ <project path="external/kdbus" name="kdbus" remote="systemd" revision="master" />
+ <project path="frameworks/kdbinder" name="platform/external/kdbinder" remote="linaro-android" revision="master" />
+ </manifest>
+ EOF
+
+Download the Android tree.
+
+ $ cd ${ANDROID_TREE}
+ $ repo sync -j${N_JOBS}
+
+KDBUS requires a recent enough kernel, and the stable kernel we have checked out
+is based on 3.18 which is too old. We will use the latest kernel instead, as of
+the 11th of February.
+
+ $ cd kernel/linaro/armlt
+ $ git checkout latest-armlt-20160211
+
+Finally, the default configuration does not allow kernel modules. Enable it in
+"linaro/configs/android.conf" by setting "CONFIG_MODULES" to "y".
+
+### Build and install the Android filesystem
+
+We are now ready to build the new kernel and Android filesystem. Watch out for
+the sudo prompt at the end (needed to temporarily mount the system image), it
+may time out after some time.
+
+ $ source build/envsetup.sh
+ $ lunch juno-userdebug
+ $ make -j${N_JOBS} selinuxtarballs
+
+You may encounter errors (unsupported relocations) when linking ART
+executables. This seem to be a problem specific to Clang, recompile with GCC
+instead:
+
+ $ rm -rf out/host/linux-x86/obj{,32}/SHARED_LIBRARIES/*art*
+ $ make -j${N_JOBS} selinuxtarballs WITHOUT_HOST_CLANG=true
+
+We need to burn the filesystem onto a USB flash drive. Download the latest
+`linaro-image-tools` from this [git repository][1] and run the following
+commands (replace `sdX` with the drive's device node):
+
+ $ cd ${ANDROID_TREE}/out/target/product/juno
+ $ sudo linaro-image-tools/linaro-android-media-create \
+ --mmc /dev/sdX --dev vexpress \
+ --systemimage system.img --userdataimage userdata.img \
+ --boot boot.tar.bz2
+
+You may now connect the USB drive to the JUNO board.
+
+[1]: https://git.linaro.org/ci/linaro-image-tools.git
+
+### Setting up the JUNO board and booting to Android
+
+We are going to install a UEFI firmware on the juno board. You may download it
+[here][2], it is called "juno-uefi.zip".
+
+[2]: https://community.arm.com/docs/DOC-10804#jive_content_id_41_Prebuilt_configurations
+
+Power on the JUNO board with a serial cable connected and press enter to stop
+auto boot. Then execute the following commands:
+
+ Cmd> flash
+ Flash> eraseall
+ Flash> exit
+ Cmd> usb_on
+
+You should now see the JUNO board come up as a USB storage device. Mount it,
+remove *all* of its content and replace it with the content of "juno-uefi.zip".
+Make sure you keep the directory structure. For instance:
+
+ # mount /dev/sdc1 /mnt
+ # rm -r /mnt/*
+ # unzip /path/to/juno-uefi.zip -d /mnt/
+
+Then, we have to copy our kernel, device tree and ramdisk:
+
+ # cp ${ANDROID_TREE}/out/target/product/juno/boot/kernel /mnt/SOFTWARE/Image
+ # cp ${ANDROID_TREE}/out/target/product/juno/boot/juno-r2.dtb /mnt/SOFTWARE/juno-r2.dtb
+ # cp ${ANDROID_TREE}/out/target/product/juno/ramdisk.img /mnt/SOFTWARE/ramdisk.img
+
+Finally, we need to instruct UEFI to boot our kernel. You should find the
+following file in "/mnt/SOFTWARE":
+
+ # cat /mnt/SOFTWARE/startup.nsh
+ echo -off
+ echo Juno startup.nsh from NOR flash
+ echo Example command to start the kernel:
+ echo norkern dtb=board.dtb initrd=ramdisk.img console=ttyAMA0,115200n8 root=/dev/sda2 rw rootwait earlyprintk=pl011,0x7ff80000 debug user_debug=31 androidboot.hardware=juno loglevel=9 sky2.mac_address=0xAA,0xBB,0xCC,0xDD,0xEE,0xFF
+
+Append this file with the following line:
+
+ norkern dtb=board.dtb initrd=ramdisk.img console=ttyAMA0,115200n8 root=/dev/sda2 rw rootwait earlyprintk=pl011,0x7ff80000 debug user_debug=31 androidboot.hardware=juno loglevel=9 sky2.mac_address=0xAA,0xBB,0xCC,0xDD,0xEE,0xFF selinux=0
+
+We are now ready to boot to Android. Make sure you've issued a "sync" before
+umounting the JUNO's USB storage device. Plug in the USB flash drive with the
+Android file system and enter reboot the board:
+
+ Cmd> reboot
+
+If it all went well, you should have booted to a shell on the Android
+filesystem. Make sure you have connected an ethernet cable to the GigaBit
+ethernet port, just below the JTAG port. Network may take a few minutes to
+become ready.
+
+Testing KDBUS and KDBinder
+--------------------------
+
+We will need to send files over to the board with adb. However, the `/system`
+partition is mounted as read-only by default so we remount it as read-write.
+
+ $ adb connect X.X.X.X
+ $ adb remount
+
+### Building and installing KDBUS
+
+The KDBUS out-of-tree module needs to be built against the kernel. We are using
+the bare metal toolchain from [linaro][3] (but any AArch64 toolchain should be
+just as fine, modify `CROSS_COMPILE` accordingly).
+
+[3]: https://releases.linaro.org/components/toolchain/binaries/latest-5.1/aarch64-elf/gcc-linaro-5.1-2015.08-x86_64_aarch64-elf.tar.xz
+
+ $ cd ${ANDROID_TREE}/external/kdbus
+ $ export ARCH=arm64
+ $ export CROSS_COMPILE=aarch64-none-elf-
+ $ make KERNELDIR=${ANDROID_TREE}/out/target/product/juno/obj/kernel module
+
+Then you may upload and load KDBUS into the running kernel:
+
+ $ adb push ipc/kdbus/kdbus.ko /system/kdbus.ko
+ $ adb shell
+ # insmod /system/kdbus.ko
+ # mount -t kdbusfs kdbusfs /sys/fs/kdbus
+
+### Building, uploading and testing KDBinder
+
+KDBinder was checked out in "frameworks/kdbinder" by repo. All we have to do
+now is build it and upload it to the target.
+
+Build `libkdbinder` and its test-suite:
+
+ $ cd ${ANDROID_TREE}/frameworks/kdbinder/libs/kdbinder
+ $ mm
+
+Build the `kdbus_servicemanager` utility:
+
+ $ cd ${ANDROID_TREE}/frameworks/kdbinder/cmds
+ $ mm
+
+And upload everything to the target:
+
+ $ adb sync
+
+For KDBinder to work, we need this service to run in the background. Leave adb
+shell running or background it, there doesn't seem to be a clean way to
+daemonize an arbitrary process from adb:
+
+ $ adb shell
+ # kdbus_servicemanager &
+
+Now you should be able to successfully run the tests on the target!
+
+ $ adb shell
+ # /data/nativetest64/kdbinderTest/kdbinderTest
+ # /data/nativetest64/kdbinderKDBUSTest/kdbinderKDBUSTest
+
+### binderAddInts benchmark running with KDBUS
+
+The KDBinder tests we have run only make sure that the library itself is
+working. However, the interesting part is that `libkdbinder` aims to be a
+drop-in replacement for `libbinder`. This means we can choose to build
+packages depending on `libbinder` with `libkdbinder` instead.
+
+At the moment, support for this is very limited. But here is a working example
+for the `binderAddInts` benchmark.
+
+Run the benchmark on the target. You may need to make it explicitly executable.
+
+ $ adb shell
+ # chmod +x /data/nativebenchmarks/binderAddInts
+ # /data/nativebenchmarks/binderAddInts
+
+Let's create a version using `libkdbinder` called `kdbus_binderAddInts`!
+
+Navigate to `binderAddInts`:
+
+ $ cd ${ANDROID_TREE}/system/extras/tests/binder/benchmarks
+
+Edit the `Android.mk` file and append the following:
+
+ include $(CLEAR_VARS)
+ LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+ LOCAL_MODULE_TAGS := eng tests
+ LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativebenchmark
+
+ LOCAL_STATIC_LIBRARIES += \
+ libtestUtil
+
+ LOCAL_SHARED_LIBRARIES += \
+ libutils \
+ liblog \
+ libkdbinder
+
+ LOCAL_C_INCLUDES += \
+ system/extras/tests/include \
+ frameworks/base/include \
+ frameworks/kdbinder/include/kdbinder
+
+ LOCAL_MODULE := kdbus_binderAddInts
+ LOCAL_SRC_FILES := binderAddInts.cpp
+
+ include $(BUILD_EXECUTABLE)
+
+This is building an executable from the same source as the binder version, but
+this time it builds against `libkdbinder`.
+
+Build, upload and run:
+
+ $ mm
+ $ adb sync
+ $ adb shell /data/nativebenchmark/kdbus_binderAddInts