在Android内核中加载内核模块

问题描述:

我在这里列出我的问题.

I am listing my problem here.

我有一个Google Nexus,也称为激情"手机.手机中安装了Fastboot和adb工具.并且引导加载程序已解锁.

I have a Google Nexus one a.k.a. "passion" phone with me. Fastboot and adb tools are installed in the phone. And the boot loader is unlocked.

我的任务:我必须在Linux内核中添加一个Linux内核模块.

My task: I have to add a linux kernel module to the Android kernel.

我做了什么:

我遵循了 http://source.android.com/source/initializing.html中的步骤并下载了适用于android-2.3.6_r1(激情)的内核并已构建.我也可以在手机上刷新它,并且新的android内核也可以正常工作.现在,我想要的是修改内核并添加我自己的内核模块,然后将其刷新到手机上,以便手机上的内核是我修改过的内核.

I followed the steps in http://source.android.com/source/initializing.html and downloaded the kernel for android-2.3.6_r1 (passion) and have built it. I am also able to flash it on the phone and the new android kernel also works fine. Now what I want is to modify the kernel and add my own kernel module and then flash it on the phone, so that the kernel on the phone is my modified kernel.

现在我遇到了两种方法.

Now I have come across two approaches to do this.

1)

Cross用Android内核编译我的内核模块,并使用adb命令将其推送到设备上.我在内核中使用的Makefile如下.

Cross Compile my kernel module with the android kernel and push it on the device with adb command. The Makefile I use in the kernel is as follows.

VERSION = 2
PATCHLEVEL = 3
SUBLEVEL = 6
EXTRAVERSION = -00054-g5f01537
obj-m += hello-1.o
KDIR=/home/apurva/android_dir
PWD := $(shell pwd)
all:
        make -C $(KDIR) ARCH=arm CROSS_COMPILE=/home/apurva/android_dir/prebuilt/linux-    x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- SUBDIRS=$(PWD) modules

clean:
        make -C $(KDIR) ARCH=arm CROSS_COMPILE=/home/apurva/android_dir/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- SUBDIRS=$(PWD) clean

现在,这无法生成新的hello-1.ko.我不知道为什么,我猜VERSION,PATCHLEVEL,SUBLEVEL和EXTRAVERSION值有问题.这些必要吗?我也尝试了android-2.3.6_r1的这些值,但仍然无法正常工作.我不确定这个EXTRAVERSION值是什么?

Now this is not able to generate new hello-1.ko. I do not know why, I guess there is some problem with the VERSION, PATCHLEVEL, SUBLEVEL and EXTRAVERSION values. Are these necessary? I tried these value from android-2.3.6_r1 also but still it does not work. I am not sure what is this EXTRAVERSION value?

我什至尝试使用Ubuntu编译器生成的hello-1.ko.我使用以下adb命令将此hello-1.ko推入了仿真器.

I even tried with the hello-1.ko generated from the compiler in my ubuntu. I pushed this hello-1.ko into the emulator with the following adb command.

/root/bin/src/out/host/linux-x86/bin/adb shell mount
/root/bin/src/out/host/linux-x86/bin/adb push hello-1.ko /data
/root/bin/src/out/host/linux-x86/bin/adb insmod /data/hello-1.ko

但是hello-1.ko无法insmod,并且出现以下错误. insmod:init_module()hello-1.ko函数未实现

But that hello-1.ko is not able to insmod and I get the following error. insmod : Error in init_module() hello-1.ko function not implemented

hello-1.c非常简单:

Whereas the hello-1.c is quite simple:

#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for KERN_INFO */

int init_module(void)
{
        printk(KERN_INFO "Hello world 1.\n");
        return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}

2)

第二种方法可以将内核模块的源文件放在android的内核目录中.可能在系统目录中或其他位置,并要求make生成这些源文件以及其他源文件.但是我不确定在哪里要求制作过程.我试图在main.mk中这样做,并在源文件的源目录中创建了一个Android.mk文件,但是它不起作用.也许这是一个更好的解决方案,但我对此没有任何帮助.

The second approach of doing this can be placing my source files of the kernel module in the kernel directory of android. May be in the system directory or somewhere else and ask the make to build these source files also along with the other source. But I am not sure where to ask the make process to do so. I tried to do so in main.mk and created a Android.mk file in the source directory of my source files but it did not work. May be this is a better solution but I could not find any help on this.

完成此操作后,我的内核模块应能够控制android手机的wnic(无线网络接口设备).它应该能够将wnic置于睡眠模式,然后在从我的内核模块收到命令后将其唤醒.如果您有关于如何执行此操作的指示,那将对您有所帮助.我发现在Android上,它是通过wpa_supplicant私有驱动程序控制的.命令,例如:

After doing this, my kernel modules should be able to control the wnic (Wireless Network Interface device) of the android phone. It should be able to put the wnic in sleep mode and then wake it up after receiving command from my kernel module. If you have some pointers on how to do this, that will be a help. I have found that on Android it is controlled through wpa_supplicant private driver. Commands, like:

wpa_cli driver powermode 0 - auto 
wpa_cli driver powermode 1 - active

可以完成我的任务,但是我不确定,因为我还没有尝试过.我还没有达到那个阶段.

can do my task, but I am not sure since I have not tried. I have not reached that stage.

请仔细研究并提供一些帮助/指导.

Please look into this and provide some help/guidance.

谢谢

阿普瓦(Apurva)

Apurva

与内核相比,内核模块(KO's)的使用要容易得多-只要内核已启用它们即可.最简单的方法是执行"adb shell lsmod".其次是查看内核.config是否启用了CONFIG_MODULES = y和CONFIG_MODULE_UNLOAD = y.网络上有很多有关linux KO开发的信息.

Kernel modules (KO's) are much easier to work with than a static kernel - as long as the kernel has enabled them. The easiest way to tell is do an "adb shell lsmod". Second is to see if the kernel .config has enabled CONFIG_MODULES=y and CONFIG_MODULE_UNLOAD=y. Lots of info on the web about linux KO development.

嗯,您已经很接近了,但是看起来makefile很麻烦.首先尝试在主机上构建hello KO进行单元测试,然后在目标上构建.这是我在运行姜饼的OMAP36xx上使用的示例制作文件:

Hummm, you're close but it looks like the makefile is screwy. First try to build the hello KO on your host for unit test, then build on your target. Here's a sample makefile I use on an OMAP36xx running gingerbread:

# Makefile for trivial android kernel module

obj-m += mod_hello.o

CROSS_COMPILE=/opt/distros/ARM/bin/arm-none-linux-gnueabi-
TARG_KDIR ?= /opt/android/dal/nook_kernel

HOST_KDIR=/lib/modules/$(shell uname -r)/build

# target creates:
#  .<obj>.o: CC command line for the .o, including dependencies
#  .<obj>.mod.o.cmd: CC command line for the mod.o, including dependencies
#  .<obj>.ko.cmd: LD command line which links the .o and .mod.o to create the .ko
target:
    @echo "Make module for target arm"
    make -C $(TARG_KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules

host:
    @echo "Make module for host"
    make -C $(HOST_KDIR) M=$(PWD) modules

clean:
    @echo "cleaning target"
    make -C $(TARG_KDIR) M=$(PWD) clean
    @echo "cleaning host"
    make -C $(HOST_KDIR) M=$(PWD) clean