android内核模块动态加载的问题
本帖最后由 kallytin 于 2017-01-16 16:15 编辑1、下载 android kernel source,并使用选择使用 android-goldfish-3.4
2、下载android-toolchain,并设置好相关参数:
export PATH="/dir/toolchain/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH"
export ARCH=arm
export SUBARCH=arm
export CROSS_COMPILE=arm-eabi-
3、make ARCH=arm goldfish_armv7_defconfig
4、make menuconfig(使动态加载内核模块,选上:force module loading、module unloading、force module unloading)
5、make
成功后会生成“新的内核映像文件”: ./arch/arm/boot/zImage
6、编译测试文件 hellotest.c,使生成 “android 内核模块文件”hellotest.ko(源文件:hellotest.c 和 Makefile 文件会在后面补上)
7、生成模拟器(avd_test)
> android create avd -n avd_test -t 3 --abi default/armeabi-v7a
8、运行模拟器(使用第5步生成的内核"zImage"和第7步生成的"avd_test")
>emulator-kernel ./arch/arm/boot/zImage -system /dir_1/system.img -ramdisk /dir_1/ramdisk.img -avd avd_test
9、新开一个terminal,将测试文件 hellotest.ko 上传到模拟器中
> adb push hellotest.ko /data
10、运行测试测试模块
> adb root
> adb shell
> insmod hellotest.ko
结论及问题:
1、在模拟器中,hellotest.ko是可以成功执行的(dmesg可以看到结果)
2、在真实的手机中,报错,具体如下:
1)手机的配置1:android:6.0 MRA58K,内核版本:3.18.22+ ,错误提示如下:
insmod: init_module 'hellotest.ko' failed (Function not implemented)
2)手机的配置2:android:4.4.4,内核版本:3.4 ,错误提示如下:
insmod: init_module 'hellotest.ko' failed (Exec format error)
3、我在网上找了一下,有的说法是,用于测试的手机的内核并不支持动态加载内核模块(即缺少上面“第4步:make menuconfig”),是这样吗?
如果是,那该如何操作才能让“测试的手机”支持动态加载内核模块(一定要重新编译内核并刷机吗)?
如果不是,那是什么原因造成上面的错误?
补充:
//hellotest.c
#include <linux/init.h>
#include <linux/module.h>
static int hello_init(void)
{
printk(KERN_ALERT "Hello,world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
# Makefile:
obj-m := hellotest.o
KDIR := /dir_1/android-kernel/goldfish
all:
make ARCH=arm EXTRA_CFLAGS="-D_CONFIG_ARM_ -fno-pic" -C $(KDIR) M=`pwd` modules
clean:
make -C $(KDIR) M=`pwd` cleanhe
.................................................................. module需要跟内核匹配对应的。不是随便都可以加载的。 本帖最后由 kallytin 于 2017-01-16 16:40 编辑
mournjust 发表于 2017-01-16 16:31
module需要跟内核匹配对应的。不是随便都可以加载的。
能说的详细点吗?
我目前测试设备的内核版本如下:
模拟器的是 : goldfish3.4(我的理解是 内核版本3.4)
测试手机1的是:内核3.18.22++(手机界面里的 :设置-> 关于手机 -> 内核版本)
测试手机2的是:内核3.4(手机界面里的 :设置-> 关于手机 -> 内核版本)
如果我使用测试手机1,那我该使用goldfish哪个版本?
如果我使用测试手机2,那我该使用goldfish哪个版本?
本帖最后由 mournjust 于 2017-01-17 18:02 编辑
kallytin 发表于 2017-01-16 16:35
能说的详细点吗?
我目前测试设备的内核版本如下:
没有仔细的去看内核的代码,按照我的经验和理解,哪个都不行。
你可以查看一下系统调用syscall init_module.
除了检查signature之外,还要检查symbol。
随着内核版本的推进,内核的一些函数调用也随之变化。 打个比方,假设本来在3.10中你的init函数中调用了A, 但是到了3.18版本中这个函数变为B怎么办。那么这个在3.10版本上编译出来的module是不可能在
3.18版本上insmod成功的。
module需要跟内核严格匹配,或者说两者需要一起编译出来的。
本帖最后由 kallytin 于 2017-01-17 23:23 编辑
mournjust 发表于 2017-01-17 15:57
没有仔细的去看内核的代码,按照我的经验和理解,哪个都不行。
你可以查看一下系统调用syscall init_m ...
有2点没看明白:
前提:因为“测试手机1”使用的是“内核版本3.18”,因此先不作讨论
1、针对“测试手机2(内核版本为3.4)”,我是使用内核版本3.4(goldfish)在ubuntu16.04上面对"android内核模块"进行编译,结果是编译成功的。我在ubuntu16.04上使用模拟器(内核版本为3.4)运行该内核模块,结果是成功的。当我使用“真是android手机(内核版本也是 3.4)”来测试运行该内核模块,却提示失败。那我就不明白了,我使用的都是“内核版本3.4”进行编译和运行,应该不存在“内核版本不一致”的情况,但还是提示错误,为何?
2、关于“android内核模块”签名的问题,我使用 hexdump -C hellotest.ko 对内核模块hellotest.ko进行查看,发现是“没有”签名的。但后来再baidu一下,发现是“内核版本3.7”以后才支持模块签名,也就是在“内核版本3.4”的时候,是不需要对“android内核模块”进行签名的,是吗?
此外,你最后提到的“module需要跟内核严格匹配,或者说两者需要一起编译出来的”,该如何做到?我的理解是:
1、下载goldfish,选择内核版本3.4,设置可动态加载模块,然后编译出 zImage
2、下载tool-chain交叉编译工具
3、利用第1点中编译成功后的“内核版本3.4”代码(头文件等),使用tool-chain编译出“android内核模块”hellotest.ko
4、下载android源码,编译出system.img、userdata.img和ramdisk.img
5、将上面编译出的 system.img, userdata.img, ramdisk.img, zImage 作为参数“传入”模拟器,并对 hellotest.ko进行测试
6、如果第5步中的测试成功,则将system.img, userdata.img, ramdisk.img, zImage 作为“rom”刷入“新的测试手机”
7、将hellotest.ko上传到“新的测试手机”,这样 insmod hellotest.ko就能正常运行
你的意思是这样吗?
怎么不说话了?......... 有人知道吗
页:
[1]