您的位置:首页 > 移动开发 > Android开发

android 独立编译ko包方法

2017-07-14 15:13 330 查看
 在为android 编译ko 包并使用insmod加载过程中遇到两个问题,记录如下:

android 编译ko包实际与linux编译ko没有区别,首先编写.c .h文件等,之后编写makefile文件,

makefile中 KERNEL_DIR 为kernel编译后产生的临时文件夹的目录,有些系统工程会重定向生成的内核临时文件目录,

所以不能简单的吧KERNEL_DIR  定义为kernel源文件目录。而是应该确定生成的临时文件的目录后使用临时文件目录

例如本次使用的工程就与之前rk3288的工程不同,编译后的临时文件目录为

out/target/product/xxxxxx/obj/KERNEL_OBJ/  

所以设置 KERNEL_DIR := xxx(上一级目录)/out/target/product/xxxxxx/obj/KERNEL_OBJ/  

在编写编译选项时本次的工程并没有在顶层makefile里指定使用的系统平台等,所以编译指令里需要添加上对系统平台

的指定,以及交叉编译器的使用。

make -C  $(KERNEL_DIR) ARCH=arm CROSS_COMPILE=arm-eabi- M=$(PWD) modules

最终使用的Makefile文件如下:

KERNEL_DIR := /home/zsf/Desktop/L15/SC20_R01/out/target/product/msm8909/obj/KERNEL_OBJ/

PWD := $(shell pwd)

module-objs := test.o 

obj-m := module.o 

default:  
make -C  $(KERNEL_DIR) ARCH=arm CROSS_COMPILE=arm-eabi- M=$(PWD) modules

编译生成module.ko 后,push 到android设备的system/bin目录,

在insmod module.ko 时提示:

insmod module.ko

insmod: init_module 'module.ko' failed (Exec format error)

原因是编译的系统平台(qcom)与目前使用系统平台不符(rk)

usb 线之前是连到rk的板子上,切换到qcom的开发板后继续insmod

提示

insmod module.ko

insmod: init_module 'module.ko' failed (Required key not available)

根据提示应该是key的问题,查阅资料发现Linux 从3.n(具体版本不清楚)开启了对加载的module进行签名认证的功能

在这个功能使能之后,内核只允许安装特定的key签名的模块。

内核配置项 

CONFIG_MODULE_SIG=y

表示开启了签名机制,但是这时候模块签名或不签名都可以使用

CONFIG_MODULE_SIG_FORCE=y

如果上述配置项使能,则模块必须有正确的签名才能正常使用。

CONFIG_MODULE_SIG_ALL=y

内核在编译的时候,并不会主动去给模块签名,除非你把上述配置项打开。 
查看内核配置文件,发现上面3个配置项确实都打开了,因此肯定是ko签名的问题。

对于内核签名的理解参考文章http://blog.csdn.net/hui872370036/article/details/69950869

(感谢这位作者)

使用文中的命令hexdump -C
spidev.ko | tail

查看当前编译的签名信息为:

而内核内部正确编译的ko包签名为:

所以确定了签名不一致问题。

后续就是为ko包签名的事了

查找到

signing_key.priv signing_key.x509 文件,拷贝到module源码目录,

使用命令:

perl ../../xxxx/kernel/scripts/sign-file sha512 signing_key.priv signing_key.x509
 module.ko

对module.ko进行签名

签名后查看签名信息为:

此时签名正确,将module push 进设备insmode 悲催的是又提示

insmod module.ko

insmod: init_module 'module.ko' failed (Required key not available)

奇怪的问题,后来突然想起,最近重新编译了一次kernel 镜像,此次module 是在这次基础上编译的,是否与重新编译有关,

然后对设备fastboot flash boot boot.img 重新烧录 kernel 镜像,在进行push   而后insmod 此次模块加载成功。

总结 签名失败问题:

解决方案:

1、关闭内核的模块签名校验问题

2、使用当前内核的签名对模块进行签名 (每次编译后签名秘钥对会更新,所以在对上个版本或者更早之前的版本或者其他机器编译的内核镜像

加载模块时,需要重新烧写模块编译时的当前内核镜像,这样才不会出现签名仍然不一致问题。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: