在 Android Emulator 里面用 insmod 安装 LKM 时,会报告错误,例如:

# insmod hello.ko
insmod: init_module 'hello.ko' failed (Function not implemented)
这是因为 Android SDK 里面自带的 Emulator 所用的 kernel 关闭了加载 LKM 的功能。要在 Emulator 里面开发和调试 LKM,必须自己重新编译 kernel. 编译方法可以参考 http://www.linuxidc.com/Linux/2011-05/35740p2.htm.

NOTE: 如果是在 Mac OS X 里面编译,make 的时候可能会遇到以下错误:

HOSTCC scripts/mod/mk_elfconfig

scripts/mod/mk_elfconfig.c:4:17: error: elf.h: No such file or directory

这是因为 Mac 的 include 文件少了一个 elf.h

从网上(例如:http://www.rockbox.org/tracker/9006?getfile=16683)下载一个放到 scripts/mod 目录,并且修改 mod 目录里面引用了 elf.h 的两个文件就可以了。

编译好的新 kernel 假定是 zImage, 建议启动 emulator 的时候加上 -show-kernel 开关,这样可以把 LKM 用 printk() 输出的信息输出到 console 上,便于调试。例:emulator -kernel zImage -show-kernel -avd <AVD名字>

写一个简单的 HelloWorld来测试一下:

  1. #include<linux/init.h>
  2. #include<linux/module.h>
  3. MODULE_LICENSE("DualBSD/GPL");
  4. staticinthello_init(void)
  5. {
  6. printk(KERN_INFO"Hello,world\n");
  7. return0;
  8. }
  9. staticvoidhello_exit(void)
  10. {
  11. printk(KERN_INFO"Goodbye,cruelworld\n");
  12. }
  13. module_init(hello_init);
  14. module_exit(hello_exit);

交叉编译的Makefile:

  1. KERNELDIR:=/Users/quaful/Documents/Projects/360/kernel/
  2. PWD:=$(shellpwd)
  3. ARCH=arm
  4. CROSS_COMPILE=/Developer/android-ndk-r4b/build/prebuilt/darwin-x86/arm-eabi-4.4.0/bin/arm-eabi-
  5. CC=$(CROSS_COMPILE)gcc
  6. LD=$(CROSS_COMPILE)ld
  7. obj-m:=hello.o
  8. modules:
  9. $(MAKE)-C$(KERNELDIR)ARCH=$(ARCH)CROSS_COMPILE=$(CROSS_COMPILE)M=$(PWD)modules
  10. clean:
  11. rm*.o*.ko*.mod.c*.markers*.order*.symvers

把编译生成的hello.ko传到手机上,然后执行:

insmodhello.ko

在kernel的console 输出中就可以看到 printk的结果了。

Howto BUILD the LINUX KERNEL for the Android EMULATOR (Eclair version)
DOWNLOAD THE KERNEL SOURCE CODE

First we download the kernel source code from http://android.git.kernel.org

Within that page there are kernels for other platforms too. We choose to download kernel/common project from there.

$git clone git://android.git.kernel.org/kernel/common

We check which branch we have downloaded:
$git branch
it shows * android-2.6.27, not the one we are searching for:

To list all remote available branches:
$git branch -r


origin/HEAD -> origin/android-2.6.27 origin/android-2.6.25 origin/android-2.6.27 origin/android-2.6.29 origin/android-2.6.32 origin/android-goldfish-2.6.27 origin/android-goldfish-2.6.29

What does goldfish mean? (from android-kernel mail list)
Goldfish is the kernel hacked branch that supports the qemu based arm emulator for android, so it is the one we need.

Download GOLDFISH kernel version
$git checkout --track -b android-goldfish-2.6.29 origin/android-goldfish-2.6.29
$git branch

android-2.6.27 * android-goldfish-2.6.29


RUNNING THE EMULATOR

Within this link we will find how to get the android emulator, and launch it.
Building Android in Debian Sid

Showing the kernel version running in the emulator
$adb shell
#cat /proc/version

Linux version 2.6.29-00261-g0097074 (digit@digit.mtv.corp.google.com) (gcc version 4.4.0 (GCC) ) #14 Tue Feb 2 15:49:02 PST 2010


OBTAINING KERNEL CONFIGURATION

We are going to obtain the kernel configuration .config file from within our running emulator.

$cd common # we enter in the kernel source directory.
$adb pull /proc/config.gz . # get compressed .config file from the emulator.

$gunzip config.gz # uncompress it.
$cp config .config # rename it into .config

Now you can edit .config file the way it suits you the most.


BUILDING AND COMPILING THE KERNEL

CROSS_COMPILE environment variable stores the path to the arm cross compiling toolchain. I use the one which comes with android source code.

$ARCH=arm CROSS_COMPILE=/path/to/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- make

Executing make will build the kernel.

Last lines will show:

Kernel: arch/arm/boot/Image is ready Kernel: arch/arm/boot/zImage is ready

So we have obtained Image and zImage kernel binary files.


RUN THE EMULATOR USING THE NEW COMPILED KERNEL IMAGE

We need -kernel option:
$emulator -kernel /path/to/common/arch/arm/boot/zImage -show-kernel -verbose

We can check now the kernel version:
$adb shell
# cat /proc/version

Linux version 2.6.29-00262-gb0d93fb (user@myPC) (gcc version 4.4.0 (GCC) ) #1 Sun May 2 14:27:31 CEST 2010

If we do not specify kernel option it usually uses the prebuilt one:
$emulator -show-kernel -verbose

emulator: argv[01] = "-kernel"emulator: argv[02] = "/path/to/mydroid/prebuilt/android-arm/kernel/kernel-qemu"


ACTIVATING MODULE LOADING SUPPORT IN THE KERNEL

Module loading support is previously disabled in the kernel, if we want to load modules in the kernel we have to enable it:

edit .config file and set:
CONFIG_MODULES=y

$ ARCH=arm CROSS_COMPILE=/path/to/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- make

I am asked about some options when executing make. I ask yes for module related options.

After compiling I see several modules have been built.


MODPOST 6 modules CC drivers/video/fb_sys_fops.mod.o LD [M] drivers/video/fb_sys_fops.ko CC drivers/video/syscopyarea.mod.o LD [M] drivers/video/syscopyarea.ko CC drivers/video/sysfillrect.mod.o LD [M] drivers/video/sysfillrect.ko CC drivers/video/sysimgblt.mod.o LD [M] drivers/video/sysimgblt.ko CC drivers/video/vfb.mod.o LD [M] drivers/video/vfb.ko

We can upload the modules in the emulator and install them:
$adb push drivers/video/fb_sys_fops.ko /data
$adb shell
#insmod /data/fb_sys_fops.ko

更多相关文章

  1. Android(安卓)build-tools升级至23.0.0_rc1后无法编译的问题解决
  2. 【Android】玩转命令行工具-aapt2
  3. Android(安卓)的回调事件详解
  4. c/c++ android 平台交叉编译 {ERROR: Failed to create toolchai
  5. Ubuntu下为AndroidStudio编译并使用x264(二)AndroidStudio部分
  6. ubutun下NDK编译环境配置
  7. Android(安卓)编译错误总结及收集
  8. Android(安卓)Studio修改项目编译版本
  9. android crash 调试

随机推荐

  1. Android(安卓)ListView重要美化属性
  2. Kotlin 写 Android(安卓)单元测试(三),Mocki
  3. Android】Android(安卓)apk默认安装位置
  4. Android(安卓)的Margin和Padding属性以及
  5. 深入理解 Android消息处理系统的原理
  6. Google Maps Android(安卓)API v2初体验
  7. Android中的Handler的机制与用法详解
  8. 【Unity3D】Unity3D与Android的交互通信(A
  9. [置顶] 【Android】 基于XMPP Smack框架
  10. 《IT蓝豹》吹雪花demo,学习android传感器