在Android内核中加载内核模块

12
我在此列出我的问题。
我有一台谷歌Nexus One手机,也称为“passion”手机。该手机已安装Fastboot和adb工具,并且启动加载程序已解锁。
我的任务是:将Linux内核模块添加到Android内核中。
我已完成以下操作:
我按照http://source.android.com/source/initializing.html中的步骤下载了android-2.3.6_r1(passion)的内核,并对其进行了构建。我还能够将其刷入手机中,新的Android内核也能正常工作。现在,我想修改内核并添加自己的内核模块,然后将其刷入手机,以便手机上的内核是我的修改后的内核。
现在我遇到了两种方法来实现这个目标。
1)
使用Android内核交叉编译我的内核模块,并使用adb命令将其推送到设备上。我在内核中使用的Makefile如下所示。
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文件。我不知道为什么,我猜测版本、补丁级别、子级别和额外版本值可能存在问题。这些值是必需的吗?我甚至尝试了从android-2.3.6_r1中获取的这些值,但仍然无法正常工作。我不确定这个EXTRAVERSION值是什么意思?
我甚至尝试了在我的Ubuntu上使用编译器生成的hello-1.ko文件。我使用以下adb命令将此hello-1.ko推送到模拟器中。
/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: Error in init_module() hello-1.ko function not implemented
而hello-1.c相当简单:
#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命令编译这些源文件以及其他源文件。但我不确定在哪里让make进程执行此操作。我尝试在main.mk中执行此操作,并在我的源文件源目录中创建了一个Android.mk文件,但它没有起作用。也许这是更好的解决方案,但我找不到任何帮助。

完成此操作后,我的内核模块应该能够控制Android手机的wnic(无线网络接口设备)。它应该能够将wnic置于睡眠模式,然后在从我的内核模块接收到命令后唤醒它。如果您知道如何做到这一点,那将是有帮助的。我发现在Android上是通过wpa_supplicant私有驱动程序来控制它的。例如:

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

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

请查看并提供一些帮助/指导。

谢谢,

Apurva

2个回答

5
Kernel模块(KO)比静态内核更易于使用-只要内核已启用它们。最简单的方法是执行“adb shell lsmod”命令进行检查。其次,可以查看内核.config是否启用了CONFIG_MODULES = y和CONFIG_MODULE_UNLOAD = y。有很多关于Linux KO开发的信息在网上可以查找。
嗯,你离正确还差一步,似乎Makefile文件有问题。首先尝试在主机上构建hello KO进行单元测试,然后再在目标设备上构建。以下是我在运行Gingerbread系统的OMAP36xx上使用的示例Makefile:
# 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

1

首先,在 .config 文件中检查模块支持是否已启用。(CONFIG_MODULES=y 和 CONFIG_MODULE_UNLOAD=y)如果未启用,请使用 menuconfig 启用它们。

然后将您的模块放置在内核源代码的根目录,并将其添加到您在根目录找到的主 makefile 中。

core-y      := usr/ yourModule/

将此添加到您的模块文件夹的Makefile中。
obj-m := yourModule.o

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接