2011年1月6日 星期四

[Android] Create a fake character device driver

1.download Android kernel, details in here

2.get the current kernel configuration from the emulator
$ adb pull /proc/config.gz .
$ gunzip config.gz
$ mv config .config

3.modify .config file
$ vim .config
CONFIG_MODULES=y

4.modify kernel Makefile
$ vim Makefile
# Use --build-id when available.
#LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
#           $(call ld-option, -Wl$(comma)--build-id,))

5.compile kernel
$ make mrproper
$ sudo make ARCH=arm CROSS_COMPILE={/path/to/android}/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-

6.get kernel image
Kernel: arch/arm/boot/Image is ready
Kernel: arch/arm/boot/zImage is ready

7.create fake driver, devone.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>

MODULE_LICENSE("Dual BSD/GPL");

static int devone_devs = 1; /* device count */
static int devone_major = 0; /* dynamic allocation */
static int devone_minor = 0;
static struct cdev devone_cdev;

ssize_t devone_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
  int i;
  unsigned char val = 0xff;
  int retval;

  for (i = 0 ; i < count ; i++) {
    if (copy_to_user(&buf[i], &val, 1)) {
      retval = -EFAULT;
      goto out;
    }
  }

  retval = count;
out:
  return (retval);
}

struct file_operations devone_fops = {
  .read = devone_read,
};

8.write fake driver Makefile
KERNELDIR={/path/to/android}/kernel
PWD := $(shell pwd)
obj-m := devone.o
modules:
  make -C $(KERNELDIR) M=$(PWD) modules
clean:
  rm -rf *.o *~ core.depend .*.cmd *.ko *.mod.c .tmp_versions modules.* Module*

9.compile kernel module
$ sudo make ARCH=arm CROSS_COMPILE={/path/to/android}/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-

10.start the emulator with our kernel
$ emulator -avd {name} -partition-size {number} -kernel {/path/to/kernel/zImage}

11.put busybox into emulator
$ adb push busybox /system/bin
$ adb shell chmod 755 /system/bin/busybox

12.put ko into emulator
$ adb remount
$ adb push devone.ko /system/lib

13.insert kernel module in emulator
$ adb shell
# insmod devone.ko
# lsmod
devone 1784 - - Live 0xbf000000

14.check the major number of devone
# cat /proc/devices
...
136 pts
252 devone
253 ttyS
...

15.insert the device node of devone
# /system/bin/busybox mknod /dev/devone c 252 0
# /system/bin/busybox ls /dev/
...
device-mapper       tty20               tty51
devone              tty21               tty52
eac                 tty22               tty53
...
# /system/bin/busybox ls -al /dev/devone
crw-rw-rw-    1 0        0        252,   0 Jan  4 05:33 /dev/devone

reference:
* 實作一個假的character driver 在emulator上跑
* Writing your first kernel module

沒有留言: