1. 问题
在android系统中加载单独编译的.ko文件时,出现:
insmod: failed to load ledtest.ko: Required key not available
然而,加载已经编译在msm8909w:/system/lib/modules文档中的.ko文件时,加载无问题:
lsmod可以查到加载成功的hello驱动
msm8909w:/system/lib/modules # ls
ansi_cprng.ko gpio_output.ko mtd_speedtest.ko
bg-codec.ko hello.ko mtd_stresstest.ko
...
msm8909w:/system/lib/modules # insmod hello.ko
msm8909w:/system/lib/modules # lsmod
Module Size Used by
hello 12526 0
2. 原因
错误提示Required key not available,说明是签名问题。
查看对比ledtest.ko和hello.ko的签名。ledtest.ko没有签名。
1)查看无法加载的ledtest.ko的签名
在linux系统中,进入ledtest.ko的目录,用下面命令查看ledtest.ko的十六进制编码:
hexdump -C ledtest.ko | tail
得到结果,说明没有签名:
2)查看可以成功加载的hello.ko文档的签名
在linux系统中,系统编译后,存放hello.ko的目录,我的目录是~/msm8909-source-tree/out/target/product/msm8909w/system/lib/modules/,里面可以看到很多.ko文件
用下面命令查看hello.ko的十六进制编码:
hexdump -C hello.ko | tail
hello.ko有签名:
3)为什么单独编译的.ko没有签名?
linux系统,在kernel中的Makefile中有如下:
ifdef CONFIG_MODULE_SIG_ALL
MODSECKEY = ./signing_key.priv
MODPUBKEY = ./signing_key.x509
export MODPUBKEY
mod_sign_cmd = perl $(srctree)/scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY)
else
mod_sign_cmd = true
endif
export mod_sign_cmd**
... ...
... ...
linux系统中,查看out文件中.config所在的目录~/msm8909-source-tree/out/target/product/msm8909w/obj/kernel/msm-3.18/
有签名相关的文档:
编译kernel的时候,在modules中加入了签名。
单独编译module的时候,没有加入签名相关的命令。
3. 解决方案
解决思路:1.加签名。2.使所有的ko都不需要签名。
1). 解决方法1:加签名。
进入驱动模块目录,参考kernel中Makefile中加签名的格式,添加签名
MODSECKEY = ./signing_key.priv
MODPUBKEY = ./signing_key.x509
...
mod_sign_cmd = perl $(srctree)/scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY)
...
其中, 在我的工程文档中,
$(CONFIG_MODULE_SIG_HASH):在.config中定义,为sha512,在下面命令中直接写。
$(MODSECKEY):要signing_key.priv存放完整目录
$(MODPUBKEY):要signing_key.x509存放完整目录
命令如下:
~/home/ubuntu/msm8909-source-tree/kernel/msm-3.18/drivers/ledtest$
perl /home/ubuntu/msm8909-source-tree/kernel/msm-3.18/scripts/sign-file sha512 /home/ubuntu/msm8909-source-tree/out/target/product/msm8909w/obj/kernel/msm-3.18/signing_key.priv /home/ubuntu/msm8909-source-tree/out/target/product/msm8909w/obj/kernel/msm-3.18/signing_key.x509 ledtest.ko
再查看ledtest.ko的签名,已加上:
将.ko传送到android系统进行验证,成功加载:
msm8909w:/system/lib/modules # insmod ledtest.ko
msm8909w:/system/lib/modules # lsmod
Module Size Used by
ledtest 12691 0
2). 解决方法2:修改kernel config,使所有的ko都不签名。感觉应该不安全,就没试。
我的系统使用的kernel config文档是:kernel/msm-3.18/arch/arm/configs/msm8909w_defconfig
其中可以看到签名相关的配置:
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_ALL=y
关闭签名,改为:
# CONFIG_MODULE_SIG is not set
CONFIG_MODULE_SIG_FORCE=y
CONFIG_MODULE_SIG_ALL=y
重新编译内核,更新boot.img.
3). 解决方法2:把驱动模块加入到系统编译中,和内核一起编译。
在kernel目录下的drivers文件下的Makefile中加入要编译的驱动程序文件,如下hello驱动模块:
cd msm8909-source-tree进入源码目录,编译源码,在log中打印出如下,hello_drv/下的驱动代码得到hello.ko
参考:
- https://www.cnblogs.com/liulaolaiu/p/11744476.html
- https://blog.csdn.net/u014449366/article/details/79757489?utm_medium=distribute.pc_relevant_t0.none-task-blog-searchFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-searchFromBaidu-1.control
- https://blog.csdn.net/eliot_shao/article/details/60872738
- http://www.kroah.com/log/blog/2013/09/02/booting-a-self-signed-linux-kernel/