你好世界 Android 内核模块 & insmod 时出现未知重定位: 27

13

我正在尝试创建一个简单的内核模块。 我尝试向dmesg打印消息,但是一直收到以下错误:

insmod: init_module 'hello.ko' 失败(在安卓中出现“执行格式错误”)

之后: dmesg: unknown relocation: 27

#include <linux/module.h>
#include <linux/kdb.h>
int init_module(void)
{
    printk(KERN_ALERT "Hello world!\n");
    return 1;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}
MODULE_AUTHOR("Robert P. J. Day");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION("2:1.0") ;
MODULE_DESCRIPTION("You have to start somewhere.");

Makefile 文件

    obj-m +=hello.o


KERNELDIR ?= ~/android/kernel/common
#KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
CROSS_COMPILE=~/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-

ARCH=arm
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules

clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
rm *.symvers

有人知道为什么吗?以及如何让它工作?

我发现通过执行 readelf 命令,编译后的重定位部分指向了错误的方向。

Offset     Info    Type            Sym.Value  Sym. Name
00000008  0000171b R_ARM_PLT32       00000000   printk

实际上应该是这样的:

Offset     Info    Type            Sym.Value  Sym. Name
00000008  0000171c R_ARM_CALL       00000000   printk

有人能猜测/知道可能是什么问题吗? 感谢@Chris Stratton到目前为止的帮助。


我发现在进行readelf之后,当它被编译时,重定位部分指向错误的方向。

Offset     Info    Type            Sym.Value  Sym. Name
00000008  0000171b R_ARM_PLT32       00000000   printk

实际上,应该是这样的:

Offset     Info    Type            Sym.Value  Sym. Name
00000008  0000171c R_ARM_CALL       00000000   printk

有人能猜测/知道这可能是什么吗?感谢@Chris Stratton迄今为止的帮助。


1
可能是构建系统的问题。你确定可以使用ndk工具链来制作内核吗?我的记忆是过去不能,但也许现在已经改变了。最好objdump/readelf你的模块和任何一个可用的工作模块进行比较,并查看重定位类型。 - Chris Stratton
我认为我们找到了一个线索。当执行readelf时,我发现一个正在运行的模块的Flag是“0x5000000,Version5 EABI”,而我的模块的Flag是“0x4000000,Version4 EABI”。这会影响什么吗?我找不到任何更改它的地方。我正在寻找解决方法。如果有人知道,请告诉我。 - raising hope
它似乎向后兼容,所以我有一段时间走错了方向。 - raising hope
现在我发现在我的hello world模块中重定位节'.rel.text'在偏移0x6b8处包含4个条目: 偏移 信息 类型 符号值 符号名称 00000008 0000211b R_ARM_PLT32 00000000 printk而在wifimodule中 00001c4c 000d421c R_ARM_CALL 00000000 printk - raising hope
是的,这是错误的重定位。如果我通过十六进制编辑器将R_ARM_PLT32(1B)更改为R_ARM_CALL(1C),它会停在另一个重定位错误处。有人能猜出我可能做错了什么以获得错误的重定位吗? - raising hope
2个回答

10

事实证明我必须使用

make CFLAGS_MODULE=-fno-pic

0

谢谢,-fno-pic让我的dlkm也能工作了。现在开始进行“真正”的工作...

顺便说一下,您可以在shell中导出ARCH、SUBARCH、CROSS_COMPILE和KERNELDIR,这样Makefile就变得非常简单了。这也使得人们更容易地为本机或目标平台构建dlkm,只需正确设置KERNELDIR即可(本机不需要ARCH、SUBARCH或CROSS_COMPILE变量)。

obj-m += hello.o

all: make -C $(KERNELDIR) M=$(PWD) modules


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