Thursday, June 15, 2017

Compiling Device Driver for Android (e.g. new wireless driver)

This is a quick tutorial on compiling a device driver / kernel module for Android. For the purpose of the tutorial, I'll be using a wireless driver (mt7601u) and android-x86 as an example. But the steps should work with the standard/arm version as well. Just make sure to use the correct compiler/gnu tool chain.

I had a USB wifi adapter like the one below which was mediatek's mt7601u based.
Googling around I found that the support for this is present from version 4.2+ (Reference: MediaTek MT7601 USB WIFI on the Raspberry Pi ). I also found multiple drivers for the same like, https://github.com/imZack/mt7601 and https://github.com/kuba-moo/mt7601u . Since the kernel that I was using was 4.0.x, the later worked. We'll be using that going forward.

There are two ways to get the kernel headers to compile the driver. The fool proof way is to compile the kernel that we are going to use with Android either just the kernel or the entire Android. Both methods has its own advantages. Another hackish way is to find the kernel headers closest to the kernel that we'd like to compile against. This should work mostly, but then...

What I did was to get the Android-x86 entirely - in my case I wanted to get an entire custom android build. Follow instructions on Android-x86 - Get Source

Once compiled clone the repo https://github.com/kuba-moo/mt7601u. You could try compiling on native linux for testing. Post that, edit the Makefile to force the path:

KDIR = /home/muthu/android-x86/out/target/product/x86/obj/kernel

run (after making sure you are using the correct gnu tool chain if you are cross compiling for arm)
make clean
make

you have the required mt7601u.ko file. Push that to Android (which is rooted), and push also the firmware bin file (e.g. you can get it from https://github.com/imZack/mt7601/blob/master/src/mcu/bin/MT7601.bin) to

/lib/firmware/mt7601u.bin

After which load the drivers (mt7601u depends on mac80211)
modprobe mac80211
insmod mt7601u.ko

Then insert the usb dongle to check if the wifi is working.
ip addr
ifconfig




Sunday, June 4, 2017

Creating a custom data image / userdata.img for Android

This is a small description / tutorial on how to create a custom data image for flashing along with Android files. This is usually done to preload settings (if you created one e.g. from Customizing / Changing Android DPI settings or would like to load other data related files / information)

Get the required tools:


Create an ext4 img file (in the example ~10GB)
dd if=/dev/zero of=data.img bs=1M count=10240
mkfs.ext4 data.img

Populate the data (sudo might be required)
mount -o loop data1.img mnt
// copy files to mnt
umount mnt 

Convert to simg
img2simg data.img userdata.img

You can now use userdata.img to flash with fastboot and other flashers/installers.

Customizing / Changing Android DPI settings

There are multiple ways in which the Android DPI Settings and other window manager settings can be changed.One common method is to use the wm helper, for example:
wm density 160

Another common method is to modify dpi settings using the prop file (/system/build.prop). This is mostly done by adding/modifying the following line
ro.sf.lcd_density=160

in the build.prop file by editing it via fastboot, root, or helper apps.

Both these have limitations, the first method may not work on all platforms and the second method doesn't work in newer android verified boot (verity).

Given that the first method is preferable, because of its 'setting' kind of behavior and doesn't touch unnecessary system files. I am writing about a method of directly modifying the settings database to achieve the same result. There are many such android settings that can be edited / modified similarly. In any case, wm and similar tools help with editing the settings.

The file that we are interested in is:
/data/data/com.android.providers.settings/databases/settings.db

Pull this with various tools like fastboot. If Android is booted, one might need it rooted to access this file. [ Articles like How to Copy Files Over to your Android In a Bootloop with No OS using ADB! and The Most Useful Things You Can Do with ADB and Fastboot on Android might help for this ]

Insert / Update the dpi in settings - for this we'll use sqlite3. 'global' is the table that we are interested there, since this is part of the global settings in android.

sqlite3 settings.db
insert or replace into global values(null, 'display_density_forced', 160);
.quit

Push the file to the same location where we picked it from and we are done.